diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index 7572e7c..7f55572 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -17,5 +17,36 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v4 - - uses: asdf-vm/actions/install@v3 + + - name: Cache ASDF + uses: actions/cache@v4 + id: asdf-cache + with: + path: ~/.asdf/ + key: ${{ runner.os }}-asdf-${{ hashFiles('.tool-versions') }} + restore-keys: ${{ runner.os }}-asdf- + + - name: Setup ASDF + uses: asdf-vm/actions/setup@v3 + if: ${{ steps.asdf-cache.outputs.cache-hit == 'true' }} + + - name: Install ASDF + uses: asdf-vm/actions/install@v3 + if: ${{ steps.asdf-cache.outputs.cache-hit != 'true' }} + + - name: Reshim installed ASDF tools + shell: bash + run: asdf reshim + + - name: Cache pip dependencies + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt', '.pre-commit-config.yaml') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install pip dependencies + run: pip install -r requirements.txt + - uses: pre-commit/action@v3.0.1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6d1800c..bdf3914 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: - id: trailing-whitespace - id: check-merge-conflict - id: detect-aws-credentials - args: ['--allow-missing-credentials'] + args: ["--allow-missing-credentials"] - id: detect-private-key - id: end-of-file-fixer @@ -25,14 +25,24 @@ repos: - id: terraform_validate - id: terraform_checkov args: - - '--args=--skip-check CKV_TF_1' #CKV_TF_1: "Ensure Terraform module sources use a commit hash" + - "--args=--skip-check CKV_TF_1" #CKV_TF_1: "Ensure Terraform module sources use a commit hash" - id: terraform_docs args: - - '--args=--config=.terraform-docs.yml' + - "--args=--config=.terraform-docs.yml" - repo: https://github.com/Yelp/detect-secrets rev: v1.4.0 hooks: - id: detect-secrets - args: ['--baseline', '.secrets.baseline'] + args: ["--baseline", ".secrets.baseline"] exclude: terraform.tfstate + + - repo: local + hooks: + - id: sync-variables + name: Sync module variables + entry: ./scripts/sync-variables.py + language: system + types: [python] + always_run: true + pass_filenames: false diff --git a/.tool-versions b/.tool-versions index 7ba6b3c..91bb7e1 100644 --- a/.tool-versions +++ b/.tool-versions @@ -4,3 +4,4 @@ tflint 0.50.3 checkov 3.2.37 awscli 2.15.29 pre-commit 3.6.2 +python 3.13.1 diff --git a/README.md b/README.md index b0a4154..8afd075 100644 --- a/README.md +++ b/README.md @@ -49,47 +49,47 @@ See [basic example](examples/basic) for further information. | Name | Source | Version | |------|--------|---------| -| [addon](#module\_addon) | git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon | v0.0.11 | -| [addon-irsa](#module\_addon-irsa) | git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon-irsa | v0.0.8 | -| [addon-oidc](#module\_addon-oidc) | git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon-oidc | v0.0.9 | +| [addon](#module\_addon) | git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon | v0.0.12 | +| [addon-irsa](#module\_addon-irsa) | git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon-irsa | v0.0.12 | +| [addon-oidc](#module\_addon-oidc) | git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon-oidc | v0.0.12 | ## Resources | Name | Type | |------|------| | [utils_deep_merge_yaml.values](https://registry.terraform.io/providers/cloudposse/utils/latest/docs/data-sources/deep_merge_yaml) | data source | > [!IMPORTANT] -> Variables defined in [variables-addon.tf](variables-addon.tf) defaults to `null` to have them overridable by the addon configuration defined though the [`local.addon.*`](main.tf) local variable with some default values defined in [addon.tf](addon.tf). +> Variables defined in [variables-addon[-irsa|oidc].tf](variables-addon.tf) defaults to `null` to have them overridable by the addon configuration defined though the [`local.addon[_irsa|oidc].*`](main.tf) local variable with the default values defined in [addon[-irsa|oidc].tf](addon.tf). ## Inputs | Name | Description | Type | |------|-------------|------| -| [argo\_apiversion](#input\_argo\_apiversion) | ArgoCD Application apiVersion. Defaults to `"argoproj.io/v1alpha1"`. | `string` | -| [argo\_destination\_server](#input\_argo\_destination\_server) | Destination server for ArgoCD Application. Defaults to `"https://kubernetes.default.svc"`. | `string` | -| [argo\_enabled](#input\_argo\_enabled) | If set to true, the module will be deployed as ArgoCD application, otherwise it will be deployed as a Helm release. Defaults to `false`. | `bool` | -| [argo\_helm\_enabled](#input\_argo\_helm\_enabled) | If set to true, the ArgoCD Application manifest will be deployed using Kubernetes provider as a Helm release. Otherwise it'll be deployed as a Kubernetes manifest. See README for more info. Defaults to `false`. | `bool` | +| [argo\_apiversion](#input\_argo\_apiversion) | ArgoCD Application apiVersion. Defaults to `argoproj.io/v1alpha1`. | `string` | +| [argo\_destination\_server](#input\_argo\_destination\_server) | Destination server for ArgoCD Application. Defaults to `https://kubernetes.default.svc`. | `string` | +| [argo\_enabled](#input\_argo\_enabled) | If set to `true`, the module will be deployed as ArgoCD Application, otherwise it will be deployed as a Helm release. Defaults to `false`. | `bool` | +| [argo\_helm\_enabled](#input\_argo\_helm\_enabled) | If set to `true`, the ArgoCD Application manifest will be deployed using Kubernetes provider as a Helm release. Otherwise it'll be deployed as a Kubernetes manifest. See README for more info. Defaults to `false`. | `bool` | | [argo\_helm\_values](#input\_argo\_helm\_values) | Value overrides to use when deploying ArgoCD Application object with Helm. Defaults to `""`. | `string` | | [argo\_helm\_wait\_backoff\_limit](#input\_argo\_helm\_wait\_backoff\_limit) | Backoff limit for ArgoCD Application Helm release wait job. Defaults to `6`. | `number` | | [argo\_helm\_wait\_node\_selector](#input\_argo\_helm\_wait\_node\_selector) | Node selector for ArgoCD Application Helm release wait job. Defaults to `{}`. | `map(string)` | -| [argo\_helm\_wait\_timeout](#input\_argo\_helm\_wait\_timeout) | Timeout for ArgoCD Application Helm release wait job. Defaults to `"10m"`. | `string` | +| [argo\_helm\_wait\_timeout](#input\_argo\_helm\_wait\_timeout) | Timeout for ArgoCD Application Helm release wait job. Defaults to `10m`. | `string` | | [argo\_helm\_wait\_tolerations](#input\_argo\_helm\_wait\_tolerations) | Tolerations for ArgoCD Application Helm release wait job. Defaults to `[]`. | `list(any)` | -| [argo\_info](#input\_argo\_info) | ArgoCD info manifest parameter. Defaults to `[{name="terraform",value=true}]`. |
list(object({| +| [argo\_info](#input\_argo\_info) | ArgoCD Application manifest info parameter. Defaults to `[{"name": "terraform", "value": "true"}]`. | `list(any)` | | [argo\_kubernetes\_manifest\_computed\_fields](#input\_argo\_kubernetes\_manifest\_computed\_fields) | List of paths of fields to be handled as "computed". The user-configured value for the field will be overridden by any different value returned by the API after apply. Defaults to `["metadata.labels", "metadata.annotations", "metadata.finalizers"]`. | `list(string)` | | [argo\_kubernetes\_manifest\_field\_manager\_force\_conflicts](#input\_argo\_kubernetes\_manifest\_field\_manager\_force\_conflicts) | Forcibly override any field manager conflicts when applying the kubernetes manifest resource. Defaults to `false`. | `bool` | -| [argo\_kubernetes\_manifest\_field\_manager\_name](#input\_argo\_kubernetes\_manifest\_field\_manager\_name) | The name of the field manager to use when applying the Kubernetes manifest resource. Defaults to `"Terraform"`. | `string` | +| [argo\_kubernetes\_manifest\_field\_manager\_name](#input\_argo\_kubernetes\_manifest\_field\_manager\_name) | The name of the field manager to use when applying the Kubernetes manifest resource. Defaults to `Terraform`. | `string` | | [argo\_kubernetes\_manifest\_wait\_fields](#input\_argo\_kubernetes\_manifest\_wait\_fields) | A map of fields and a corresponding regular expression with a pattern to wait for. The provider will wait until the field matches the regular expression. Use * for any value. Defaults to `{}`. | `map(string)` | -| [argo\_metadata](#input\_argo\_metadata) | ArgoCD Application metadata configuration. Override or create additional metadata parameters. Defaults to `{finalizers=["resources-finalizer.argocd.argoproj.io"]}`. | `any` | -| [argo\_namespace](#input\_argo\_namespace) | Namespace to deploy ArgoCD application CRD to. Defaults to `"argo"`. | `string` | +| [argo\_metadata](#input\_argo\_metadata) | ArgoCD Application metadata configuration. Override or create additional metadata parameters. Defaults to `{"finalizers": ["resources-finalizer.argocd.argoproj.io"]}`. | `any` | +| [argo\_namespace](#input\_argo\_namespace) | Namespace to deploy ArgoCD Application CRD to. Defaults to `argo`. | `string` | | [argo\_project](#input\_argo\_project) | ArgoCD Application project. Defaults to `default`. | `string` | | [argo\_spec](#input\_argo\_spec) | ArgoCD Application spec configuration. Override or create additional spec parameters. Defaults to `{}`. | `any` | -| [argo\_sync\_policy](#input\_argo\_sync\_policy) | ArgoCD syncPolicy manifest parameter. Defaults to `{}`. | `any` | +| [argo\_sync\_policy](#input\_argo\_sync\_policy) | ArgoCD Application manifest syncPolicy parameter. Defaults to `{}`. | `any` | | [cluster\_identity\_oidc\_issuer](#input\_cluster\_identity\_oidc\_issuer) | The OIDC Identity issuer for the cluster (required). | `string` | | [cluster\_identity\_oidc\_issuer\_arn](#input\_cluster\_identity\_oidc\_issuer\_arn) | The OIDC Identity issuer ARN for the cluster that can be used to associate IAM roles with a Service Account (required). | `string` | | [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources. | `bool` | | [helm\_atomic](#input\_helm\_atomic) | If set, installation process purges chart on fail. The wait flag will be set automatically if atomic is used. Defaults to `false`. | `bool` | -| [helm\_chart\_name](#input\_helm\_chart\_name) | Helm chart name to be installed. Defaults to `local.addon.name` (required). | `string` | -| [helm\_chart\_version](#input\_helm\_chart\_version) | Version of the Helm chart. Defaults to `local.addon.helm_chart_version` (required). | `string` | +| [helm\_chart\_name](#input\_helm\_chart\_name) | Helm chart name to be installed (required). | `string` | +| [helm\_chart\_version](#input\_helm\_chart\_version) | Version of the Helm chart (required). | `string` | | [helm\_cleanup\_on\_fail](#input\_helm\_cleanup\_on\_fail) | Allow deletion of new resources created in this Helm upgrade when upgrade fails. Defaults to `false`. | `bool` | -| [helm\_create\_namespace](#input\_helm\_create\_namespace) | Create the namespace if it does not yet exist. Defaults to `true`. | `bool` | +| [helm\_create\_namespace](#input\_helm\_create\_namespace) | Create the Namespace if it does not yet exist. Defaults to `true`. | `bool` | | [helm\_dependency\_update](#input\_helm\_dependency\_update) | Runs Helm dependency update before installing the chart. Defaults to `false`. | `bool` | | [helm\_description](#input\_helm\_description) | Set Helm release description attribute (visible in the history). Defaults to `""`. | `string` | | [helm\_devel](#input\_helm\_devel) | Use Helm chart development versions, too. Equivalent to version '>0.0.0-0'. If version is set, this is ignored. Defaults to `false`. | `bool` | @@ -97,63 +97,65 @@ See [basic example](examples/basic) for further information. | [helm\_disable\_webhooks](#input\_helm\_disable\_webhooks) | Prevent Helm chart hooks from running. Defaults to `false`. | `bool` | | [helm\_enabled](#input\_helm\_enabled) | Set to false to prevent installation of the module via Helm release. Defaults to `true`. | `bool` | | [helm\_force\_update](#input\_helm\_force\_update) | Force Helm resource update through delete/recreate if needed. Defaults to `false`. | `bool` | -| [helm\_keyring](#input\_helm\_keyring) | Location of public keys used for verification. Used only if `helm_package_verify` is `true`. Defaults to `"~/.gnupg/pubring.gpg"`. | `string` | +| [helm\_keyring](#input\_helm\_keyring) | Location of public keys used for verification. Used only if `helm_package_verify` is `true`. Defaults to `~/.gnupg/pubring.gpg`. | `string` | | [helm\_lint](#input\_helm\_lint) | Run the Helm chart linter during the plan. Defaults to `false`. | `bool` | | [helm\_package\_verify](#input\_helm\_package\_verify) | Verify the package before installing it. Helm uses a provenance file to verify the integrity of the chart; this must be hosted alongside the chart. Defaults to `false`. | `bool` | | [helm\_postrender](#input\_helm\_postrender) | Value block with a path to a binary file to run after Helm renders the manifest which can alter the manifest contents. Defaults to `{}`. | `map(any)` | | [helm\_recreate\_pods](#input\_helm\_recreate\_pods) | Perform pods restart during Helm upgrade/rollback. Defaults to `false`. | `bool` | | [helm\_release\_max\_history](#input\_helm\_release\_max\_history) | Maximum number of release versions stored per release. Defaults to `0`. | `number` | -| [helm\_release\_name](#input\_helm\_release\_name) | Helm release name. Defaults to `local.addon.name` (required). | `string` | +| [helm\_release\_name](#input\_helm\_release\_name) | Helm release name (required). | `string` | | [helm\_render\_subchart\_notes](#input\_helm\_render\_subchart\_notes) | If set, render Helm subchart notes along with the parent. Defaults to `true`. | `bool` | | [helm\_replace](#input\_helm\_replace) | Re-use the given name of Helm release, only if that name is a deleted release which remains in the history. This is unsafe in production. Defaults to `false`. | `bool` | | [helm\_repo\_ca\_file](#input\_helm\_repo\_ca\_file) | Helm repositories CA cert file. Defaults to `""`. | `string` | | [helm\_repo\_cert\_file](#input\_helm\_repo\_cert\_file) | Helm repositories cert file. Defaults to `""`. | `string` | | [helm\_repo\_key\_file](#input\_helm\_repo\_key\_file) | Helm repositories cert key file. Defaults to `""`. | `string` | | [helm\_repo\_password](#input\_helm\_repo\_password) | Password for HTTP basic authentication against the Helm repository. Defaults to `""`. | `string` | -| [helm\_repo\_url](#input\_helm\_repo\_url) | Helm repository. Defaults to `local.addon.helm_repo_url` (required). | `string` | +| [helm\_repo\_url](#input\_helm\_repo\_url) | Helm repository (required). | `string` | | [helm\_repo\_username](#input\_helm\_repo\_username) | Username for HTTP basic authentication against the Helm repository. Defaults to `""`. | `string` | | [helm\_reset\_values](#input\_helm\_reset\_values) | When upgrading, reset the values to the ones built into the Helm chart. Defaults to `false`. | `bool` | -| [helm\_reuse\_values](#input\_helm\_reuse\_values) | When upgrading, reuse the last Helm release's values and merge in any overrides. If 'helm\_reset\_values' is specified, this is ignored. Defaults to `false`. | `bool` | +| [helm\_reuse\_values](#input\_helm\_reuse\_values) | When upgrading, reuse the last Helm release's values and merge in any overrides. If `helm_reset_values` is specified, this is ignored. Defaults to `false`. | `bool` | | [helm\_set\_sensitive](#input\_helm\_set\_sensitive) | Value block with custom sensitive values to be merged with the values yaml that won't be exposed in the plan's diff. Defaults to `{}`. | `map(any)` | | [helm\_skip\_crds](#input\_helm\_skip\_crds) | If set, no CRDs will be installed before Helm release. Defaults to `false`. | `bool` | | [helm\_timeout](#input\_helm\_timeout) | Time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks). Defaults to `300`. | `number` | | [helm\_wait](#input\_helm\_wait) | Will wait until all Helm release resources are in a ready state before marking the release as successful. It will wait for as long as timeout. Defaults to `false`. | `bool` | | [helm\_wait\_for\_jobs](#input\_helm\_wait\_for\_jobs) | If wait is enabled, will wait until all Helm Jobs have been completed before marking the release as successful. It will wait for as long as timeout. Defaults to `false`. | `bool` | | [irsa\_additional\_policies](#input\_irsa\_additional\_policies) | Map of the additional policies to be attached to IRSA role. Where key is arbitrary id and value is policy ARN. Defaults to `{}`. | `map(string)` | -| [irsa\_assume\_role\_arns](#input\_irsa\_assume\_role\_arns) | List of ARNs assumable by the IRSA role. Applied only if `irsa_assume_role_enabled` is `true`. | `list(string)` | +| [irsa\_assume\_role\_arns](#input\_irsa\_assume\_role\_arns) | List of ARNs assumable by the IRSA role. Applied only if `irsa_assume_role_enabled` is `true`. Defaults to `[]`. | `list(string)` | | [irsa\_assume\_role\_enabled](#input\_irsa\_assume\_role\_enabled) | Whether IRSA is allowed to assume role defined by `irsa_assume_role_arn`. Mutually exclusive with `irsa_policy_enabled`. Defaults to `false`. | `bool` | -| [irsa\_permissions\_boundary](#input\_irsa\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the IRSA role. Defaults to `""`. | `string` | -| [irsa\_policy](#input\_irsa\_policy) | Policy to be attached to the IRSA role. Applied only if `irsa_policy_enabled` is `true`. | `string` | +| [irsa\_assume\_role\_policy\_condition\_test](#input\_irsa\_assume\_role\_policy\_condition\_test) | Specifies the condition test to use for the assume role trust policy. Defaults to `StringEquals`. | `string` | +| [irsa\_assume\_role\_policy\_condition\_values](#input\_irsa\_assume\_role\_policy\_condition\_values) | Specifies the values for the assume role trust policy condition. Each entry in this list must follow the required format `system:serviceaccount:$service_account_namespace:$service_account_name`. If this variable is left as the default, `local.irsa_assume_role_policy_condition_values_default` is used instead, which is a list containing a single value. Note that if this list is defined, the `service_account_name` and `service_account_namespace` variables are ignored. Defaults to `[]`. | `list(string)` | +| [irsa\_permissions\_boundary](#input\_irsa\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the IRSA role. Defaults to `null`. | `string` | +| [irsa\_policy](#input\_irsa\_policy) | AWS IAM policy JSON document to be attached to the IRSA role. Applied only if `irsa_policy_enabled` is `true`. Defaults to `""`. | `string` | | [irsa\_policy\_enabled](#input\_irsa\_policy\_enabled) | Whether to create IAM policy specified by `irsa_policy`. Mutually exclusive with `irsa_assume_role_enabled`. Defaults to `false`. | `bool` | | [irsa\_role\_create](#input\_irsa\_role\_create) | Whether to create IRSA role and annotate Service Account. Defaults to `true`. | `bool` | -| [irsa\_role\_name](#input\_irsa\_role\_name) | IRSA role name. The value is prefixed by `var.irsa_role_name_prefix`. Defaults to addon Helm chart name. | `string` | -| [irsa\_role\_name\_prefix](#input\_irsa\_role\_name\_prefix) | IRSA role name prefix. Defaults to addon IRSA component name with `irsa` suffix. | `string` | +| [irsa\_role\_name](#input\_irsa\_role\_name) | IRSA role name. The value is prefixed by `irsa_role_name_prefix`. Either `irsa_role_name` or `irsa_role_name_prefix` must be set. Defaults to `""`. | `string` | +| [irsa\_role\_name\_prefix](#input\_irsa\_role\_name\_prefix) | IRSA role name prefix. Either `irsa_role_name_prefix` or `irsa_role_name` must be set. Defaults to `""`. | `string` | | [irsa\_tags](#input\_irsa\_tags) | IRSA resources tags. Defaults to `{}`. | `map(string)` | -| [namespace](#input\_namespace) | The Kubernetes Namespace in which the Helm chart will be installed. Defaults to `local.addon.name`. | `string` | +| [namespace](#input\_namespace) | The Kubernetes Namespace in which the Helm chart will be installed (required). | `string` | | [oidc\_additional\_policies](#input\_oidc\_additional\_policies) | Map of the additional policies to be attached to OIDC role. Where key is arbitrary id and value is policy ARN. Defaults to `{}`. | `map(string)` | | [oidc\_assume\_role\_arns](#input\_oidc\_assume\_role\_arns) | List of ARNs assumable by the OIDC role. Applied only if `oidc_assume_role_enabled` is `true`. Defaults to `[]`. | `list(string)` | | [oidc\_assume\_role\_enabled](#input\_oidc\_assume\_role\_enabled) | Whether OIDC is allowed to assume role defined by `oidc_assume_role_arn`. Mutually exclusive with `oidc_policy_enabled`. Defaults to `false`. | `bool` | | [oidc\_assume\_role\_policy\_condition\_test](#input\_oidc\_assume\_role\_policy\_condition\_test) | Specifies the condition test to use for the assume role trust policy. Defaults to `StringLike`. | `string` | | [oidc\_assume\_role\_policy\_condition\_values](#input\_oidc\_assume\_role\_policy\_condition\_values) | Specifies the values for the assume role trust policy condition. Defaults to `[]`. | `list(string)` | | [oidc\_assume\_role\_policy\_condition\_variable](#input\_oidc\_assume\_role\_policy\_condition\_variable) | Specifies the variable to use for the assume role trust policy. Defaults to `""`. | `string` | -| [oidc\_custom\_provider\_arn](#input\_oidc\_custom\_provider\_arn) | Specifies a custom OIDC provider ARN. If specified, overrides provider created by this module. If set, it is recommended to disable default OIDC provider creation by setting var.oidc\_provider\_create to false. Defaults to `""`. | `string` | +| [oidc\_custom\_provider\_arn](#input\_oidc\_custom\_provider\_arn) | Specifies a custom OIDC provider ARN. Defaults to `""`. | `string` | | [oidc\_openid\_client\_ids](#input\_oidc\_openid\_client\_ids) | List of OpenID Connect client IDs that are allowed to assume the OIDC provider. Defaults to `[]`. | `list(string)` | | [oidc\_openid\_provider\_url](#input\_oidc\_openid\_provider\_url) | OIDC provider URL. Defaults to `""`. | `string` | | [oidc\_openid\_thumbprints](#input\_oidc\_openid\_thumbprints) | List of thumbprints of the OIDC provider's server certificate. Defaults to `[]`. | `list(string)` | -| [oidc\_permissions\_boundary](#input\_oidc\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the OIDC role. Defaults to `""`. | `string` | -| [oidc\_policy](#input\_oidc\_policy) | Policy to be attached to the OIDC role. Applied only if `oidc_policy_enabled` is `true`. | `string` | +| [oidc\_permissions\_boundary](#input\_oidc\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the OIDC role. Defaults to `null`. | `string` | +| [oidc\_policy](#input\_oidc\_policy) | AWS IAM policy JSON document to be attached to the OIDC role. Applied only if `oidc_policy_enabled` is `true`. Defaults to `""`. | `string` | | [oidc\_policy\_enabled](#input\_oidc\_policy\_enabled) | Whether to create IAM policy specified by `oidc_policy`. Mutually exclusive with `oidc_assume_role_enabled`. Defaults to `false`. | `bool` | -| [oidc\_provider\_create](#input\_oidc\_provider\_create) | Whether to create OIDC provider. Defaults to `true`. Set to false if you want to disable default OIDC provider when oidc\_custom\_provider\_arn is set. | `bool` | -| [oidc\_role\_create](#input\_oidc\_role\_create) | Whether to create OIDC role and annotate Service Account. Defaults to `true`. | `bool` | -| [oidc\_role\_name](#input\_oidc\_role\_name) | OIDC role name. The value is prefixed by `var.oidc_role_name_prefix`. Defaults to addon Helm chart name. | `string` | -| [oidc\_role\_name\_prefix](#input\_oidc\_role\_name\_prefix) | OIDC role name prefix. Defaults to addon OIDC component name with `oidc` suffix. | `string` | +| [oidc\_provider\_create](#input\_oidc\_provider\_create) | Whether to create OIDC provider. Set to `false` if you want to disable default OIDC provider when `oidc_custom_provider_arn` is set. Defaults to `true`. | `bool` | +| [oidc\_role\_create](#input\_oidc\_role\_create) | Whether to create OIDC role. Defaults to `true`. | `bool` | +| [oidc\_role\_name](#input\_oidc\_role\_name) | OIDC role name. The value is prefixed by `oidc_role_name_prefix`. Either `oidc_role_name` or `oidc_role_name_prefix` must be set. Defaults to `""`. | `string` | +| [oidc\_role\_name\_prefix](#input\_oidc\_role\_name\_prefix) | OIDC role name prefix. Either `oidc_role_name_prefix` or `oidc_role_name` must be set. Defaults to `""`. | `string` | | [oidc\_tags](#input\_oidc\_tags) | OIDC resources tags. Defaults to `{}`. | `map(string)` | | [rbac\_create](#input\_rbac\_create) | Whether to create and use RBAC resources. Defaults to `true`. | `bool` | | [service\_account\_create](#input\_service\_account\_create) | Whether to create Service Account. Defaults to `true`. | `bool` | -| [service\_account\_name](#input\_service\_account\_name) | The Kubernetes Service Account name. Defaults to addon name. | `string` | -| [service\_account\_namespace](#input\_service\_account\_namespace) | The Kubernetes Service Account namespace. Defaults to addon namespace. | `string` | +| [service\_account\_name](#input\_service\_account\_name) | The Kubernetes Service Account name. Defaults to the addon name. Defaults to `""`. | `string` | +| [service\_account\_namespace](#input\_service\_account\_namespace) | The Kubernetes Service Account namespace. Defaults to the addon namespace. Defaults to `""`. | `string` | | [settings](#input\_settings) | Additional Helm sets which will be passed to the Helm chart values. Defaults to `{}`. | `map(any)` | -| [values](#input\_values) | Additional yaml encoded values which will be passed to the Helm chart. Defaults to `""`. | `string` | +| [values](#input\_values) | Additional YAML encoded values which will be passed to the Helm chart. Defaults to `""`. | `string` | ## Outputs | Name | Description | diff --git a/addon-irsa.tf b/addon-irsa.tf index ee37e76..63c32ef 100644 --- a/addon-irsa.tf +++ b/addon-irsa.tf @@ -2,7 +2,7 @@ module "addon-irsa" { for_each = local.addon_irsa - source = "git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon-irsa?ref=v0.0.8" + source = "git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon-irsa?ref=v0.0.12" enabled = var.enabled @@ -22,9 +22,12 @@ module "addon-irsa" { irsa_policy = var.irsa_policy != null ? var.irsa_policy : try(each.value.irsa_policy, "") irsa_assume_role_enabled = var.irsa_assume_role_enabled != null ? var.irsa_assume_role_enabled : try(each.value.irsa_assume_role_enabled, false) irsa_assume_role_arns = var.irsa_assume_role_arns != null ? var.irsa_assume_role_arns : try(each.value.irsa_assume_role_arns, []) - irsa_permissions_boundary = var.irsa_permissions_boundary != null ? var.irsa_permissions_boundary : try(each.value.irsa_permissions_boundary, "") + irsa_permissions_boundary = var.irsa_permissions_boundary != null ? var.irsa_permissions_boundary : try(each.value.irsa_permissions_boundary, null) irsa_additional_policies = var.irsa_additional_policies != null ? var.irsa_additional_policies : try(each.value.irsa_additional_policies, tomap({})) + irsa_assume_role_policy_condition_test = var.irsa_assume_role_policy_condition_test != null ? var.irsa_assume_role_policy_condition_test : try(each.value.irsa_assume_role_policy_condition_test, "StringEquals") + irsa_assume_role_policy_condition_values = var.irsa_assume_role_policy_condition_values != null ? var.irsa_assume_role_policy_condition_values : try(each.value.irsa_assume_role_policy_condition_values, []) + irsa_tags = var.irsa_tags != null ? var.irsa_tags : try(each.value.irsa_tags, tomap({})) } diff --git a/addon-oidc.tf b/addon-oidc.tf index ef5a6db..f7dbd51 100644 --- a/addon-oidc.tf +++ b/addon-oidc.tf @@ -2,7 +2,7 @@ module "addon-oidc" { for_each = local.addon_oidc - source = "git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon-oidc?ref=v0.0.9" + source = "git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon-oidc?ref=v0.0.12" enabled = var.enabled @@ -15,7 +15,7 @@ module "addon-oidc" { oidc_policy = var.oidc_policy != null ? var.oidc_policy : try(each.value.oidc_policy, "") oidc_assume_role_enabled = var.oidc_assume_role_enabled != null ? var.oidc_assume_role_enabled : try(each.value.oidc_assume_role_enabled, false) oidc_assume_role_arns = var.oidc_assume_role_arns != null ? var.oidc_assume_role_arns : try(each.value.oidc_assume_role_arns, []) - oidc_permissions_boundary = var.oidc_permissions_boundary != null ? var.oidc_permissions_boundary : try(each.value.oidc_permissions_boundary, "") # tflint-ignore: aws_iam_role_invalid_permissions_boundary + oidc_permissions_boundary = var.oidc_permissions_boundary != null ? var.oidc_permissions_boundary : try(each.value.oidc_permissions_boundary, null) oidc_additional_policies = var.oidc_additional_policies != null ? var.oidc_additional_policies : try(each.value.oidc_additional_policies, tomap({})) oidc_openid_client_ids = var.oidc_openid_client_ids != null ? var.oidc_openid_client_ids : try(each.value.oidc_openid_client_ids, []) oidc_openid_provider_url = var.oidc_openid_provider_url != null ? var.oidc_openid_provider_url : try(each.value.oidc_openid_provider_url, "") diff --git a/addon.tf b/addon.tf index df0c2e2..ac91009 100644 --- a/addon.tf +++ b/addon.tf @@ -6,7 +6,7 @@ locals { } module "addon" { - source = "git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon?ref=v0.0.11" + source = "git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon?ref=v0.0.12" enabled = var.enabled diff --git a/docs/.inputs.md b/docs/.inputs.md index 87dfcdf..8e1763d 100644 --- a/docs/.inputs.md +++ b/docs/.inputs.md @@ -1,2 +1,2 @@ > [!IMPORTANT] -> Variables defined in [variables-addon.tf](variables-addon.tf) defaults to `null` to have them overridable by the addon configuration defined though the [`local.addon.*`](main.tf) local variable with some default values defined in [addon.tf](addon.tf). +> Variables defined in [variables-addon[-irsa|oidc].tf](variables-addon.tf) defaults to `null` to have them overridable by the addon configuration defined though the [`local.addon[_irsa|oidc].*`](main.tf) local variable with the default values defined in [addon[-irsa|oidc].tf](addon.tf). diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e22b84c --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +python-hcl2==5.1.1 +Jinja2==3.1.4 diff --git a/scripts/sync-variables.py b/scripts/sync-variables.py new file mode 100755 index 0000000..6786b71 --- /dev/null +++ b/scripts/sync-variables.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python + +import os +import hcl2 +import re +import argparse +import logging +from jinja2 import Environment, FileSystemLoader + +def filter_terraform_type(value): + # Currently there is a limition in handling Terraform complex types + # https://github.com/amplify-education/python-hcl2/issues/179 + # https://github.com/amplify-education/python-hcl2/issues/172 + if isinstance(value, str): + return re.sub(r'\${(.*)}', r'\1', value) + return value + +def filter_terraform_default(value): + if isinstance(value, bool): + return str(value).lower() + + if isinstance(value, str): + if value == "": + return '\\"\\"' + + if value == None: + return 'null' + + return re.sub(r'\'', r'\\"', str(value)) + +def get_template(): + env = Environment(loader=FileSystemLoader(".")) + env.filters['terraform_type'] = filter_terraform_type + env.filters['terraform_default'] = filter_terraform_default + + return env.from_string("""# IMPORTANT: This file is synced with the "terraform-aws-eks-universal-addon" module. Any changes to this file might be overwritten upon the next release of that module. +{%- for variable in variables %} +{%- for name, spec in variable.items() %} +{%- if name != 'enabled' %} +variable "{{ name }}" { + type = {{ spec.type | terraform_type }} + default = null + description = "{{ spec.description }}{% if spec.default is defined %} Defaults to `{{ spec.default | terraform_default }}`.{% endif %}" +} +{%- endif %} +{%- endfor %} +{% endfor %} +""") + +def get_logger(args): + log_level = args.log.upper() + + numeric_level = getattr(logging, log_level, None) + if not isinstance(numeric_level, int): + raise ValueError('Invalid log level `%s`' % log_level) + + logging.basicConfig(format='%(levelname)s: %(message)s', level=numeric_level) + + return logging.getLogger(__name__) + +def main(args): + log = get_logger(args) + log.info("Syncing variables from Terraform modules...") + log.warning("Terraform variable complex types are NOT supported!") + + template = get_template() + + for module in os.listdir('.terraform/modules'): # Iterate over all initialized modules + if not module.startswith('addon') or module.find(".") != -1: # Skip non-addon modules, ie. nested modules + log.info("Skipping module `%s`", module) + continue + + log.info("Processing module `%s`", module) + + source = '.terraform/modules/'+module+'/modules/'+module+'/variables.tf' + target = 'variables-'+module+'.tf' + + with open(source, 'r') as f: + log.info("Reading variables from `%s`", source) + + variables = hcl2.load(f).get('variable') + log.info("Collected variables: %d", len(variables)) + log.debug(variables) + + with open(target, "w") as f: + log.info("Writing variables to `%s`", target) + f.write(template.render(variables=variables)) + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Sync Terraform variables from the local addon modules to proxy variable files') + parser.add_argument('--log', default='INFO', help='Set the logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)') + + args = parser.parse_args() + + main(args) diff --git a/variables-addon-irsa.tf b/variables-addon-irsa.tf index 6405409..60e505a 100644 --- a/variables-addon-irsa.tf +++ b/variables-addon-irsa.tf @@ -1,7 +1,5 @@ # IMPORTANT: This file is synced with the "terraform-aws-eks-universal-addon" module. Any changes to this file might be overwritten upon the next release of that module. -# ================ IRSA variables (optional) ================ - variable "cluster_identity_oidc_issuer" { type = string default = null @@ -29,13 +27,13 @@ variable "service_account_create" { variable "service_account_name" { type = string default = null - description = "The Kubernetes Service Account name. Defaults to addon name." + description = "The Kubernetes Service Account name. Defaults to the addon name. Defaults to `\"\"`." } variable "service_account_namespace" { type = string default = null - description = "The Kubernetes Service Account namespace. Defaults to addon namespace." + description = "The Kubernetes Service Account namespace. Defaults to the addon namespace. Defaults to `\"\"`." } variable "irsa_role_create" { @@ -47,13 +45,13 @@ variable "irsa_role_create" { variable "irsa_role_name_prefix" { type = string default = null - description = "IRSA role name prefix. Defaults to addon IRSA component name with `irsa` suffix." + description = "IRSA role name prefix. Either `irsa_role_name_prefix` or `irsa_role_name` must be set. Defaults to `\"\"`." } variable "irsa_role_name" { type = string default = null - description = "IRSA role name. The value is prefixed by `var.irsa_role_name_prefix`. Defaults to addon Helm chart name." + description = "IRSA role name. The value is prefixed by `irsa_role_name_prefix`. Either `irsa_role_name` or `irsa_role_name_prefix` must be set. Defaults to `\"\"`." } variable "irsa_policy_enabled" { @@ -65,7 +63,7 @@ variable "irsa_policy_enabled" { variable "irsa_policy" { type = string default = null - description = "Policy to be attached to the IRSA role. Applied only if `irsa_policy_enabled` is `true`." + description = "AWS IAM policy JSON document to be attached to the IRSA role. Applied only if `irsa_policy_enabled` is `true`. Defaults to `\"\"`." } variable "irsa_assume_role_enabled" { @@ -77,13 +75,13 @@ variable "irsa_assume_role_enabled" { variable "irsa_assume_role_arns" { type = list(string) default = null - description = "List of ARNs assumable by the IRSA role. Applied only if `irsa_assume_role_enabled` is `true`." + description = "List of ARNs assumable by the IRSA role. Applied only if `irsa_assume_role_enabled` is `true`. Defaults to `[]`." } variable "irsa_permissions_boundary" { type = string default = null - description = "ARN of the policy that is used to set the permissions boundary for the IRSA role. Defaults to `\"\"`." + description = "ARN of the policy that is used to set the permissions boundary for the IRSA role. Defaults to `null`." } variable "irsa_additional_policies" { @@ -97,3 +95,15 @@ variable "irsa_tags" { default = null description = "IRSA resources tags. Defaults to `{}`." } + +variable "irsa_assume_role_policy_condition_test" { + type = string + default = null + description = "Specifies the condition test to use for the assume role trust policy. Defaults to `StringEquals`." +} + +variable "irsa_assume_role_policy_condition_values" { + type = list(string) + default = null + description = "Specifies the values for the assume role trust policy condition. Each entry in this list must follow the required format `system:serviceaccount:$service_account_namespace:$service_account_name`. If this variable is left as the default, `local.irsa_assume_role_policy_condition_values_default` is used instead, which is a list containing a single value. Note that if this list is defined, the `service_account_name` and `service_account_namespace` variables are ignored. Defaults to `[]`." +} diff --git a/variables-addon-oidc.tf b/variables-addon-oidc.tf index db4e0a0..173b527 100644 --- a/variables-addon-oidc.tf +++ b/variables-addon-oidc.tf @@ -1,29 +1,33 @@ # IMPORTANT: This file is synced with the "terraform-aws-eks-universal-addon" module. Any changes to this file might be overwritten upon the next release of that module. -# ================ oidc variables (optional) ================ - variable "oidc_provider_create" { type = bool default = null - description = "Whether to create OIDC provider. Defaults to `true`. Set to false if you want to disable default OIDC provider when oidc_custom_provider_arn is set." + description = "Whether to create OIDC provider. Set to `false` if you want to disable default OIDC provider when `oidc_custom_provider_arn` is set. Defaults to `true`." +} + +variable "oidc_custom_provider_arn" { + type = string + default = null + description = "Specifies a custom OIDC provider ARN. Defaults to `\"\"`." } variable "oidc_role_create" { type = bool default = null - description = "Whether to create OIDC role and annotate Service Account. Defaults to `true`." + description = "Whether to create OIDC role. Defaults to `true`." } variable "oidc_role_name_prefix" { type = string default = null - description = "OIDC role name prefix. Defaults to addon OIDC component name with `oidc` suffix." + description = "OIDC role name prefix. Either `oidc_role_name_prefix` or `oidc_role_name` must be set. Defaults to `\"\"`." } variable "oidc_role_name" { type = string default = null - description = "OIDC role name. The value is prefixed by `var.oidc_role_name_prefix`. Defaults to addon Helm chart name." + description = "OIDC role name. The value is prefixed by `oidc_role_name_prefix`. Either `oidc_role_name` or `oidc_role_name_prefix` must be set. Defaults to `\"\"`." } variable "oidc_policy_enabled" { @@ -35,7 +39,7 @@ variable "oidc_policy_enabled" { variable "oidc_policy" { type = string default = null - description = "Policy to be attached to the OIDC role. Applied only if `oidc_policy_enabled` is `true`." + description = "AWS IAM policy JSON document to be attached to the OIDC role. Applied only if `oidc_policy_enabled` is `true`. Defaults to `\"\"`." } variable "oidc_assume_role_enabled" { @@ -53,7 +57,7 @@ variable "oidc_assume_role_arns" { variable "oidc_permissions_boundary" { type = string default = null - description = "ARN of the policy that is used to set the permissions boundary for the OIDC role. Defaults to `\"\"`." + description = "ARN of the policy that is used to set the permissions boundary for the OIDC role. Defaults to `null`." } variable "oidc_additional_policies" { @@ -103,9 +107,3 @@ variable "oidc_openid_thumbprints" { default = null description = "List of thumbprints of the OIDC provider's server certificate. Defaults to `[]`." } - -variable "oidc_custom_provider_arn" { - type = string - default = null - description = "Specifies a custom OIDC provider ARN. If specified, overrides provider created by this module. If set, it is recommended to disable default OIDC provider creation by setting var.oidc_provider_create to false. Defaults to `\"\"`." -} diff --git a/variables-addon.tf b/variables-addon.tf index 96bfe49..3a7bbf7 100644 --- a/variables-addon.tf +++ b/variables-addon.tf @@ -1,7 +1,5 @@ # IMPORTANT: This file is synced with the "terraform-aws-eks-universal-addon" module. Any changes to this file might be overwritten upon the next release of that module. -# ================ common variables (required) ================ - variable "helm_enabled" { type = bool default = null @@ -11,37 +9,37 @@ variable "helm_enabled" { variable "helm_chart_name" { type = string default = null - description = "Helm chart name to be installed. Defaults to `local.addon.name` (required)." + description = "Helm chart name to be installed (required)." } variable "helm_chart_version" { type = string default = null - description = "Version of the Helm chart. Defaults to `local.addon.helm_chart_version` (required)." + description = "Version of the Helm chart (required)." } variable "helm_release_name" { type = string default = null - description = "Helm release name. Defaults to `local.addon.name` (required)." + description = "Helm release name (required)." } variable "helm_repo_url" { type = string default = null - description = "Helm repository. Defaults to `local.addon.helm_repo_url` (required)." + description = "Helm repository (required)." } variable "helm_create_namespace" { type = bool default = null - description = "Create the namespace if it does not yet exist. Defaults to `true`." + description = "Create the Namespace if it does not yet exist. Defaults to `true`." } variable "namespace" { type = string default = null - description = "The Kubernetes Namespace in which the Helm chart will be installed. Defaults to `local.addon.name`." + description = "The Kubernetes Namespace in which the Helm chart will be installed (required)." } variable "settings" { @@ -53,33 +51,31 @@ variable "settings" { variable "values" { type = string default = null - description = "Additional yaml encoded values which will be passed to the Helm chart. Defaults to `\"\"`." + description = "Additional YAML encoded values which will be passed to the Helm chart. Defaults to `\"\"`." } -# ================ argo variables (required) ================ - variable "argo_namespace" { type = string default = null - description = "Namespace to deploy ArgoCD application CRD to. Defaults to `\"argo\"`." + description = "Namespace to deploy ArgoCD Application CRD to. Defaults to `argo`." } variable "argo_enabled" { type = bool default = null - description = "If set to true, the module will be deployed as ArgoCD application, otherwise it will be deployed as a Helm release. Defaults to `false`." + description = "If set to `true`, the module will be deployed as ArgoCD Application, otherwise it will be deployed as a Helm release. Defaults to `false`." } variable "argo_helm_enabled" { type = bool default = null - description = "If set to true, the ArgoCD Application manifest will be deployed using Kubernetes provider as a Helm release. Otherwise it'll be deployed as a Kubernetes manifest. See README for more info. Defaults to `false`." + description = "If set to `true`, the ArgoCD Application manifest will be deployed using Kubernetes provider as a Helm release. Otherwise it'll be deployed as a Kubernetes manifest. See README for more info. Defaults to `false`." } variable "argo_helm_wait_timeout" { type = string default = null - description = "Timeout for ArgoCD Application Helm release wait job. Defaults to `\"10m\"`." + description = "Timeout for ArgoCD Application Helm release wait job. Defaults to `10m`." } variable "argo_helm_wait_node_selector" { @@ -103,7 +99,7 @@ variable "argo_helm_wait_backoff_limit" { variable "argo_destination_server" { type = string default = null - description = "Destination server for ArgoCD Application. Defaults to `\"https://kubernetes.default.svc\"`." + description = "Destination server for ArgoCD Application. Defaults to `https://kubernetes.default.svc`." } variable "argo_project" { @@ -113,30 +109,27 @@ variable "argo_project" { } variable "argo_info" { - type = list(object({ - name = string - value = string - })) + type = list(any) default = null - description = "ArgoCD info manifest parameter. Defaults to `[{name=\"terraform\",value=true}]`." + description = "ArgoCD Application manifest info parameter. Defaults to `[{\"name\": \"terraform\", \"value\": \"true\"}]`." } variable "argo_sync_policy" { type = any default = null - description = "ArgoCD syncPolicy manifest parameter. Defaults to `{}`." + description = "ArgoCD Application manifest syncPolicy parameter. Defaults to `{}`." } variable "argo_metadata" { type = any default = null - description = "ArgoCD Application metadata configuration. Override or create additional metadata parameters. Defaults to `{finalizers=[\"resources-finalizer.argocd.argoproj.io\"]}`." + description = "ArgoCD Application metadata configuration. Override or create additional metadata parameters. Defaults to `{\"finalizers\": [\"resources-finalizer.argocd.argoproj.io\"]}`." } variable "argo_apiversion" { type = string default = null - description = "ArgoCD Application apiVersion. Defaults to `\"argoproj.io/v1alpha1\"`." + description = "ArgoCD Application apiVersion. Defaults to `argoproj.io/v1alpha1`." } variable "argo_spec" { @@ -151,8 +144,6 @@ variable "argo_helm_values" { description = "Value overrides to use when deploying ArgoCD Application object with Helm. Defaults to `\"\"`." } -# ================ argo kubernetes manifest variables (required) ================ - variable "argo_kubernetes_manifest_computed_fields" { type = list(string) default = null @@ -162,7 +153,7 @@ variable "argo_kubernetes_manifest_computed_fields" { variable "argo_kubernetes_manifest_field_manager_name" { type = string default = null - description = "The name of the field manager to use when applying the Kubernetes manifest resource. Defaults to `\"Terraform\"`." + description = "The name of the field manager to use when applying the Kubernetes manifest resource. Defaults to `Terraform`." } variable "argo_kubernetes_manifest_field_manager_force_conflicts" { @@ -177,8 +168,6 @@ variable "argo_kubernetes_manifest_wait_fields" { description = "A map of fields and a corresponding regular expression with a pattern to wait for. The provider will wait until the field matches the regular expression. Use * for any value. Defaults to `{}`." } -# ================ Helm release variables (required) ================ - variable "helm_repo_key_file" { type = string default = null @@ -224,7 +213,7 @@ variable "helm_package_verify" { variable "helm_keyring" { type = string default = null - description = "Location of public keys used for verification. Used only if `helm_package_verify` is `true`. Defaults to `\"~/.gnupg/pubring.gpg\"`." + description = "Location of public keys used for verification. Used only if `helm_package_verify` is `true`. Defaults to `~/.gnupg/pubring.gpg`." } variable "helm_timeout" { @@ -248,7 +237,7 @@ variable "helm_reset_values" { variable "helm_reuse_values" { type = bool default = null - description = "When upgrading, reuse the last Helm release's values and merge in any overrides. If 'helm_reset_values' is specified, this is ignored. Defaults to `false`." + description = "When upgrading, reuse the last Helm release's values and merge in any overrides. If `helm_reset_values` is specified, this is ignored. Defaults to `false`." } variable "helm_force_update" {
name = string
value = string
}))