Skip to content

Commit 0d69ed5

Browse files
authored
Add full namespace support (#34)
1 parent 2fc98f3 commit 0d69ed5

File tree

12 files changed

+466
-433
lines changed

12 files changed

+466
-433
lines changed

.github/workflows/validate-codeowners.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ jobs:
1010
steps:
1111
- name: "Checkout source code at current commit"
1212
uses: actions/checkout@v2
13+
# Leave pinned at 0.7.1 until https://github.com/mszostok/codeowners-validator/issues/173 is resolved
1314
- uses: mszostok/codeowners-validator@v0.7.1
1415
if: github.event.pull_request.head.repo.full_name == github.repository
1516
name: "Full check of CODEOWNERS"

README.md

Lines changed: 73 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
2929
-->
3030

31-
This `terraform-aws-helm-release` module creates a helm chart with an option to create an EKS IAM role.
31+
This `terraform-aws-helm-release` module deploys a [Helm chart](https://helm.sh/docs/topics/charts/) with
32+
an option to create an EKS IAM Role for a Service Account ([IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)).
3233

3334
---
3435

@@ -93,10 +94,67 @@ the registry shows many of our inputs as required when in fact they are optional
9394
The table below correctly indicates which inputs are required.
9495

9596

96-
For a complete example, see [examples/complete](examples/complete).
9797

98-
For automated tests of the complete example using [bats](https://github.com/bats-core/bats-core) and [Terratest](https://github.com/gruntwork-io/terratest)
99-
(which tests and deploys the example on AWS), see [test](test).
98+
This module deploys a [Helm chart](https://helm.sh/docs/topics/charts/) with
99+
an option to create an EKS IAM Role for a Service Account ([IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)).
100+
It has many of the same features and limitations of Helm, and uses the
101+
Terraform [Helm provider](https://github.com/hashicorp/terraform-provider-helm),
102+
specifically the [helm_release](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) resource.
103+
104+
NOTE: This module is just a convenient wrapper, packaging up 3 concepts:
105+
1. Deploying a Helm Chart to an EKS cluster
106+
1. Creating a Kubernetes namespace in the EKS cluster
107+
1. Creating an IAM role for a Kubernetes Service Account (which, in turn,
108+
is presumably created by deploying the Helm Chart)
109+
110+
Many issues may arise that are due to limitations of Helm, Kubernetes, EKS,
111+
Terraform, or the Terraform providers. Please address issues and complaints
112+
to the project that can potentially fix them, which will usually not be this module.
113+
114+
### Provider requirements.
115+
116+
This module is unusual in that it requires you to configure 3 separate Terraform providers:
117+
1. AWS
118+
2. Helm
119+
3. Kubernetes
120+
121+
Cloud Posse maintains a [provider-helm.tf](https://github.com/cloudposse/terraform-aws-components/blob/master/mixins/provider-helm.tf)
122+
file "mixin" for use in Cloud Posse [components](https://github.com/cloudposse/terraform-aws-components)
123+
which you can also use as an example of how to configure the Helm and Kubernetes providers in your own component.
124+
125+
126+
### Creating a namespace
127+
128+
This module provides 2 options for creating the namespace the chart will be deployed to, for the
129+
case where you are deploying the chart into its own namespace that does not already exist.
130+
131+
1. `create_namespace_with_kubernetes` will manage the namespace using a Terraform `kubernetes_namespace`
132+
resource. This is the recommended way to create the namespace, because it allows you to
133+
annotate (`kubernetes_namespace_annotations`) and label (`kubernetes_namespace_labels`) the namespace,
134+
and it provides proper sequencing of creation and
135+
destruction of deployments, resources, and IAM roles. When the deployment is
136+
destroyed with `terraform destroy`, the namespace will be deleted, too. This will
137+
delete everything else in the namespace (but never the Custom Resource Definitions,
138+
which themselves are non-namespaced), so if this is not the desired behavior, you
139+
should create the namespace in a separate Terraform component.
140+
1. `create_namespace` is the obsolete way to create a namespace, by delegating the
141+
responsibility to Helm. This is not recommended because it provides no control over
142+
the annotations or labels of the namespace, and when the deployment is
143+
destroyed with `terraform destroy`, the namespace will be left behind.
144+
This can cause problems with future deployments.
145+
146+
Note: You may have trouble deleting a release from within Terraform if the Kubernetes cluster
147+
has been modified outside of this module, for example if the namespace or the cluster itself has been deleted.
148+
You can delete the Terraform state if the resources are gone, using `terraform state rm`
149+
or even `terraform workspace delete`, or you can try using `terraform destroy`.
150+
In some cases, it may be helpful to set `var.enabled` to `false` while destroying:
151+
152+
```shell
153+
terraform destroy -var enabled=false
154+
```
155+
156+
157+
For a complete example, see [examples/complete](examples/complete).
100158

101159
```hcl
102160
module "helm_release" {
@@ -209,12 +267,14 @@ Available targets:
209267
|------|---------|
210268
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
211269
| <a name="requirement_helm"></a> [helm](#requirement\_helm) | >= 2.2 |
270+
| <a name="requirement_kubernetes"></a> [kubernetes](#requirement\_kubernetes) | >= 2.7.1 |
212271

213272
## Providers
214273

215274
| Name | Version |
216275
|------|---------|
217276
| <a name="provider_helm"></a> [helm](#provider\_helm) | >= 2.2 |
277+
| <a name="provider_kubernetes"></a> [kubernetes](#provider\_kubernetes) | >= 2.7.1 |
218278

219279
## Modules
220280

@@ -229,6 +289,7 @@ Available targets:
229289
| Name | Type |
230290
|------|------|
231291
| [helm_release.this](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource |
292+
| [kubernetes_namespace.default](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource |
232293

233294
## Inputs
234295

@@ -243,7 +304,8 @@ Available targets:
243304
| <a name="input_chart_version"></a> [chart\_version](#input\_chart\_version) | Specify the exact chart version to install. If this is not specified, the latest version is installed. | `string` | `null` | no |
244305
| <a name="input_cleanup_on_fail"></a> [cleanup\_on\_fail](#input\_cleanup\_on\_fail) | Allow deletion of new resources created in this upgrade when upgrade fails. Defaults to `false`. | `bool` | `null` | no |
245306
| <a name="input_context"></a> [context](#input\_context) | Single object for setting entire context at once.<br>See description of individual variables for details.<br>Leave string and numeric variables as `null` to use default value.<br>Individual variable settings (non-null) override settings in context object,<br>except for attributes, tags, and additional\_tag\_map, which are merged. | `any` | <pre>{<br> "additional_tag_map": {},<br> "attributes": [],<br> "delimiter": null,<br> "descriptor_formats": {},<br> "enabled": true,<br> "environment": null,<br> "id_length_limit": null,<br> "label_key_case": null,<br> "label_order": [],<br> "label_value_case": null,<br> "labels_as_tags": [<br> "unset"<br> ],<br> "name": null,<br> "namespace": null,<br> "regex_replace_chars": null,<br> "stage": null,<br> "tags": {},<br> "tenant": null<br>}</pre> | no |
246-
| <a name="input_create_namespace"></a> [create\_namespace](#input\_create\_namespace) | Create the namespace if it does not yet exist. Defaults to `false`. | `bool` | `null` | no |
307+
| <a name="input_create_namespace"></a> [create\_namespace](#input\_create\_namespace) | (Not recommended, use `create_namespace_with_kubernetes` instead)<br>Create the namespace via Helm if it does not yet exist. Defaults to `false`.<br>Does not support annotations or labels. May have problems when destroying.<br>Ignored when `create_namespace_with_kubernetes` is set. | `bool` | `null` | no |
308+
| <a name="input_create_namespace_with_kubernetes"></a> [create\_namespace\_with\_kubernetes](#input\_create\_namespace\_with\_kubernetes) | Create the namespace via Kubernetes if it does not yet exist. Defaults to `false`.<br>Must set `true` if you want to use namespace annotations or labels. | `bool` | `null` | no |
247309
| <a name="input_delimiter"></a> [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.<br>Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
248310
| <a name="input_dependency_update"></a> [dependency\_update](#input\_dependency\_update) | Runs helm dependency update before installing the chart. Defaults to `false`. | `bool` | `null` | no |
249311
| <a name="input_description"></a> [description](#input\_description) | Release description attribute (visible in the history). | `string` | `null` | no |
@@ -262,6 +324,8 @@ Available targets:
262324
| <a name="input_id_length_limit"></a> [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).<br>Set to `0` for unlimited length.<br>Set to `null` for keep the existing setting, which defaults to `0`.<br>Does not affect `id_full`. | `number` | `null` | no |
263325
| <a name="input_keyring"></a> [keyring](#input\_keyring) | Location of public keys used for verification. Used only if `verify` is true. Defaults to `/.gnupg/pubring.gpg` in the location set by `home`. | `string` | `null` | no |
264326
| <a name="input_kubernetes_namespace"></a> [kubernetes\_namespace](#input\_kubernetes\_namespace) | The namespace to install the release into. Defaults to `default`. | `string` | `null` | no |
327+
| <a name="input_kubernetes_namespace_annotations"></a> [kubernetes\_namespace\_annotations](#input\_kubernetes\_namespace\_annotations) | Annotations to be added to the created namespace. Ignored unless `create_namespace_with_kubernetes` is `true`. | `map(string)` | `{}` | no |
328+
| <a name="input_kubernetes_namespace_labels"></a> [kubernetes\_namespace\_labels](#input\_kubernetes\_namespace\_labels) | Labels to be added to the created namespace. Ignored unless `create_namespace_with_kubernetes` is `true`. | `map(string)` | `{}` | no |
265329
| <a name="input_label_key_case"></a> [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.<br>Does not affect keys of tags passed in via the `tags` input.<br>Possible values: `lower`, `title`, `upper`.<br>Default value: `title`. | `string` | `null` | no |
266330
| <a name="input_label_order"></a> [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.<br>Defaults to ["namespace", "environment", "stage", "name", "attributes"].<br>You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no |
267331
| <a name="input_label_value_case"></a> [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,<br>set as tag values, and output by this module individually.<br>Does not affect values of tags passed in via the `tags` input.<br>Possible values: `lower`, `title`, `upper` and `none` (no transformation).<br>Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.<br>Default value: `lower`. | `string` | `null` | no |
@@ -330,15 +394,16 @@ Are you using this project or any of our other projects? Consider [leaving a tes
330394

331395
Check out these related projects.
332396

397+
- [terraform-aws-eks-iam-role](https://github.com/cloudposse/terraform-aws-eks-iam-role/) - Terraform module to provision an EKS IAM Role for Service Account.
333398
- [terraform-null-label](https://github.com/cloudposse/terraform-null-label) - Terraform module designed to generate consistent names and tags for resources. Use terraform-null-label to implement a strict naming convention.
334399

335400

336401
## References
337402

338403
For additional context, refer to some of these links.
339404

340-
- [Terraform Standard Module Structure](https://www.terraform.io/docs/modules/index.html#standard-module-structure) - HashiCorp's standard module structure is a file and directory layout we recommend for reusable modules distributed in separate repositories.
341-
- [Terraform Module Requirements](https://www.terraform.io/docs/registry/modules/publish.html#requirements) - HashiCorp's guidance on all the requirements for publishing a module. Meeting the requirements for publishing a module is extremely easy.
405+
- [Helm](https://helm.sh/) - Helm: The package manager for Kubernetes.
406+
- [IAM Roles for Service Accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) - HashiCorp's guidance on all the requirements for publishing a module. Meeting the requirements for publishing a module is extremely easy.
342407
- [Terraform Version Pinning](https://www.terraform.io/docs/configuration/terraform.html#specifying-a-required-terraform-version) - The required_version setting can be used to constrain which versions of the Terraform CLI can be used with your configuration
343408

344409

@@ -414,7 +479,7 @@ In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow.
414479

415480
## Copyrights
416481

417-
Copyright © 2021-2022 [Cloud Posse, LLC](https://cloudposse.com)
482+
Copyright © 2021-2022-2022 [Cloud Posse, LLC](https://cloudposse.com)
418483

419484

420485

README.yaml

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ license: "APACHE2"
1717
copyrights:
1818
- name: "Cloud Posse, LLC"
1919
url: "https://cloudposse.com"
20-
year: "2021"
20+
year: "2021-2022"
2121

2222
# Canonical GitHub repo
2323
github_repo: cloudposse/terraform-aws-helm-release
@@ -36,36 +36,93 @@ badges:
3636

3737
# List any related terraform modules that this module may be used with or that this module depends on.
3838
related:
39+
- name: "terraform-aws-eks-iam-role"
40+
description: "Terraform module to provision an EKS IAM Role for Service Account."
41+
url: "https://github.com/cloudposse/terraform-aws-eks-iam-role/"
3942
- name: "terraform-null-label"
4043
description: "Terraform module designed to generate consistent names and tags for resources. Use terraform-null-label to implement a strict naming convention."
4144
url: "https://github.com/cloudposse/terraform-null-label"
4245

4346
# List any resources helpful for someone to get started. For example, link to the hashicorp documentation or AWS documentation.
4447
references:
45-
- name: "Terraform Standard Module Structure"
46-
description: "HashiCorp's standard module structure is a file and directory layout we recommend for reusable modules distributed in separate repositories."
47-
url: "https://www.terraform.io/docs/modules/index.html#standard-module-structure"
48-
- name: "Terraform Module Requirements"
48+
- name: "Helm"
49+
description: "Helm: The package manager for Kubernetes."
50+
url: "https://helm.sh/"
51+
- name: "IAM Roles for Service Accounts"
4952
description: "HashiCorp's guidance on all the requirements for publishing a module. Meeting the requirements for publishing a module is extremely easy."
50-
url: "https://www.terraform.io/docs/registry/modules/publish.html#requirements"
53+
url: "https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html"
5154
- name: "Terraform Version Pinning"
5255
description: "The required_version setting can be used to constrain which versions of the Terraform CLI can be used with your configuration"
5356
url: "https://www.terraform.io/docs/configuration/terraform.html#specifying-a-required-terraform-version"
5457

5558
# Short description of this project
5659
description: |-
57-
This `terraform-aws-helm-release` module creates a helm chart with an option to create an EKS IAM role.
58-
59-
# Introduction to the project
60-
#introduction: |-
61-
# This is an introduction.
60+
This `terraform-aws-helm-release` module deploys a [Helm chart](https://helm.sh/docs/topics/charts/) with
61+
an option to create an EKS IAM Role for a Service Account ([IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)).
6262
6363
# How to use this module. Should be an easy example to copy and paste.
6464
usage: |-
65-
For a complete example, see [examples/complete](examples/complete).
6665
67-
For automated tests of the complete example using [bats](https://github.com/bats-core/bats-core) and [Terratest](https://github.com/gruntwork-io/terratest)
68-
(which tests and deploys the example on AWS), see [test](test).
66+
This module deploys a [Helm chart](https://helm.sh/docs/topics/charts/) with
67+
an option to create an EKS IAM Role for a Service Account ([IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)).
68+
It has many of the same features and limitations of Helm, and uses the
69+
Terraform [Helm provider](https://github.com/hashicorp/terraform-provider-helm),
70+
specifically the [helm_release](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) resource.
71+
72+
NOTE: This module is just a convenient wrapper, packaging up 3 concepts:
73+
1. Deploying a Helm Chart to an EKS cluster
74+
1. Creating a Kubernetes namespace in the EKS cluster
75+
1. Creating an IAM role for a Kubernetes Service Account (which, in turn,
76+
is presumably created by deploying the Helm Chart)
77+
78+
Many issues may arise that are due to limitations of Helm, Kubernetes, EKS,
79+
Terraform, or the Terraform providers. Please address issues and complaints
80+
to the project that can potentially fix them, which will usually not be this module.
81+
82+
### Provider requirements.
83+
84+
This module is unusual in that it requires you to configure 3 separate Terraform providers:
85+
1. AWS
86+
2. Helm
87+
3. Kubernetes
88+
89+
Cloud Posse maintains a [provider-helm.tf](https://github.com/cloudposse/terraform-aws-components/blob/master/mixins/provider-helm.tf)
90+
file "mixin" for use in Cloud Posse [components](https://github.com/cloudposse/terraform-aws-components)
91+
which you can also use as an example of how to configure the Helm and Kubernetes providers in your own component.
92+
93+
94+
### Creating a namespace
95+
96+
This module provides 2 options for creating the namespace the chart will be deployed to, for the
97+
case where you are deploying the chart into its own namespace that does not already exist.
98+
99+
1. `create_namespace_with_kubernetes` will manage the namespace using a Terraform `kubernetes_namespace`
100+
resource. This is the recommended way to create the namespace, because it allows you to
101+
annotate (`kubernetes_namespace_annotations`) and label (`kubernetes_namespace_labels`) the namespace,
102+
and it provides proper sequencing of creation and
103+
destruction of deployments, resources, and IAM roles. When the deployment is
104+
destroyed with `terraform destroy`, the namespace will be deleted, too. This will
105+
delete everything else in the namespace (but never the Custom Resource Definitions,
106+
which themselves are non-namespaced), so if this is not the desired behavior, you
107+
should create the namespace in a separate Terraform component.
108+
1. `create_namespace` is the obsolete way to create a namespace, by delegating the
109+
responsibility to Helm. This is not recommended because it provides no control over
110+
the annotations or labels of the namespace, and when the deployment is
111+
destroyed with `terraform destroy`, the namespace will be left behind.
112+
This can cause problems with future deployments.
113+
114+
Note: You may have trouble deleting a release from within Terraform if the Kubernetes cluster
115+
has been modified outside of this module, for example if the namespace or the cluster itself has been deleted.
116+
You can delete the Terraform state if the resources are gone, using `terraform state rm`
117+
or even `terraform workspace delete`, or you can try using `terraform destroy`.
118+
In some cases, it may be helpful to set `var.enabled` to `false` while destroying:
119+
120+
```shell
121+
terraform destroy -var enabled=false
122+
```
123+
124+
125+
For a complete example, see [examples/complete](examples/complete).
69126
70127
```hcl
71128
module "helm_release" {

0 commit comments

Comments
 (0)