From 7271877fff93a2dcc63d29313355d7c0da5a0768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Odstr=C4=8Dil=C3=ADk?= Date: Tue, 27 May 2025 22:08:39 +0200 Subject: [PATCH 1/6] feat: universal-addon template migration --- .github/workflows/pre-commit.yaml | 69 +++ .github/workflows/pre-commit.yml | 52 --- ...lease-drafter.yml => release-drafter.yaml} | 22 +- .github/workflows/template-sync.yaml | 96 ++++ .github/workflows/validate.yaml | 51 ++- .gitignore | 2 - .pre-commit-config.yaml | 54 ++- .secrets.baseline | 22 +- .templatesyncignore | 10 + .terraform-docs.yml | 27 +- .terraform.lock.hcl | 99 ++++ .tflint.hcl | 5 +- .tool-versions | 7 + README.md | 240 +++++----- addon-irsa.tf | 52 +++ addon.tf | 101 +++++ argo-helm.tf | 170 ------- argo.tf | 57 --- docs/.addon.md | 31 ++ docs/.footer.md | 37 ++ docs/.inputs.md | 2 + examples/basic/.terraform.lock.hcl | 161 +++++++ examples/basic/README.md | 41 -- examples/basic/base.tf | 34 +- examples/basic/main.tf | 13 +- examples/basic/providers.tf | 12 +- examples/basic/versions.tf | 6 +- helm.tf | 68 --- helm/argocd-application/.helmignore | 23 - helm/argocd-application/Chart.yaml | 18 - .../argocd-application/templates/_helpers.tpl | 51 --- .../templates/application.yaml | 19 - helm/argocd-application/values.yaml | 2 - iam.tf | 99 ---- main.tf | 31 ++ migrations.tf | 24 + outputs.tf | 19 - requirements.txt | 3 +- scripts/sync-variables.py | 95 ++++ values.tf | 162 ------- variables-addon-irsa.tf | 163 +++++++ variables-addon.tf | 385 ++++++++++++++++ variables.tf | 428 +----------------- versions.tf | 12 +- 44 files changed, 1661 insertions(+), 1414 deletions(-) create mode 100644 .github/workflows/pre-commit.yaml delete mode 100644 .github/workflows/pre-commit.yml rename .github/workflows/{release-drafter.yml => release-drafter.yaml} (52%) create mode 100644 .github/workflows/template-sync.yaml create mode 100644 .templatesyncignore create mode 100644 .terraform.lock.hcl create mode 100644 .tool-versions create mode 100644 addon-irsa.tf create mode 100644 addon.tf delete mode 100644 argo-helm.tf delete mode 100644 argo.tf create mode 100644 docs/.addon.md create mode 100644 docs/.footer.md create mode 100644 docs/.inputs.md create mode 100644 examples/basic/.terraform.lock.hcl delete mode 100644 examples/basic/README.md delete mode 100644 helm.tf delete mode 100644 helm/argocd-application/.helmignore delete mode 100644 helm/argocd-application/Chart.yaml delete mode 100644 helm/argocd-application/templates/_helpers.tpl delete mode 100644 helm/argocd-application/templates/application.yaml delete mode 100644 helm/argocd-application/values.yaml delete mode 100644 iam.tf create mode 100644 main.tf create mode 100644 migrations.tf delete mode 100644 outputs.tf create mode 100755 scripts/sync-variables.py delete mode 100644 values.tf create mode 100644 variables-addon-irsa.tf create mode 100644 variables-addon.tf diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml new file mode 100644 index 0000000..17688c8 --- /dev/null +++ b/.github/workflows/pre-commit.yaml @@ -0,0 +1,69 @@ +name: pre-commit + +on: + workflow_dispatch: + pull_request: + branches: + - main + - master + +permissions: + contents: read + +concurrency: + group: pre-commit-${{ github.ref }} + cancel-in-progress: false + +env: + # renovate: datasource=github-releases depName=asdf-vm/asdf + ASDF_VERSION: 31e8c93004abd76253d186b8896785895069749b # v0.15.0 # pragma: allowlist secret + +jobs: + pre-commit: + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + + - name: Setup ASDF + uses: asdf-vm/actions/setup@05e0d2ed97b598bfce82fd30daf324ae0c4570e6 # v3.0.2 + + - name: Cache ASDF + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + id: asdf-cache + with: + # https://github.com/asdf-vm/asdf/blob/master/.gitignore + path: | + ~/.asdf/installs + ~/.asdf/plugins + ~/.asdf/shims + key: ${{ runner.os }}-asdf-${{ hashFiles('.tool-versions') }} + restore-keys: ${{ runner.os }}-asdf- + + - name: Install ASDF + uses: asdf-vm/actions/install@05e0d2ed97b598bfce82fd30daf324ae0c4570e6 # v3.0.2 + if: ${{ steps.asdf-cache.outputs.cache-hit != 'true' }} + with: + asdf_branch: ${{ env.ASDF_VERSION }} + + - name: Reshim installed ASDF tools + shell: bash + run: asdf reshim + + - name: Cache pip + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + 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 + + - name: Run pre-commit + run: pre-commit run --show-diff-on-failure --color=always --all-files + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # required for zizmor diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml deleted file mode 100644 index bbbd33f..0000000 --- a/.github/workflows/pre-commit.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: pre-commit - -permissions: - contents: read - -on: - workflow_dispatch: - pull_request: - branches: - - main - - master - -env: - PYTHON_VERSION: "3.10" - TERRAFORM_DOCS_VERSION: "v0.16.0" - TFLINT_VERSION: "v0.40.1" - -jobs: - pre-commit: - runs-on: ubuntu-22.04 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - with: - python-version: ${{ env.PYTHON_VERSION }} - cache: pip - - - name: Install Python dependencies - run: pip install -r requirements.txt - - - name: Install terraform-docs - uses: jaxxstorm/action-install-gh-release@v1.9.0 - with: - repo: terraform-docs/terraform-docs - tag: ${{ env.TERRAFORM_DOCS_VERSION }} - cache: enable - - - name: TFLint cache - uses: actions/cache@v3 - with: - path: ~/.tflint.d/plugins - key: ${{ runner.os }}-tflint-${{ hashFiles('.tflint.hcl') }} - - - name: Install TFLint - uses: terraform-linters/setup-tflint@v2 - with: - tflint_version: ${{ env.TFLINT_VERSION }} - - - name: Run pre-commit - uses: pre-commit/action@v3.0.0 diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yaml similarity index 52% rename from .github/workflows/release-drafter.yml rename to .github/workflows/release-drafter.yaml index 9528a7a..67303c3 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yaml @@ -1,8 +1,4 @@ -name: Release Drafter - -permissions: - contents: write - pull-requests: read +name: Release drafter on: push: @@ -11,13 +7,21 @@ on: - master pull_request: - types: [opened, reopened, synchronize, labeled] + types: + - opened + - reopened + - synchronize + - labeled + +permissions: + contents: write + pull-requests: read jobs: - update_release_draft: - runs-on: ubuntu-22.04 + release-drafter: + runs-on: ubuntu-24.04 steps: - - uses: release-drafter/release-drafter@v5 + - uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0 with: config-name: RELEASE_DRAFTER.yml env: diff --git a/.github/workflows/template-sync.yaml b/.github/workflows/template-sync.yaml new file mode 100644 index 0000000..6425d0f --- /dev/null +++ b/.github/workflows/template-sync.yaml @@ -0,0 +1,96 @@ +name: Template sync + +on: + workflow_dispatch: + schedule: + - cron: '0 0 * * *' # every day at midnight + +permissions: {} + +concurrency: + group: pre-commit + cancel-in-progress: false + +env: + # renovate: datasource=github-releases depName=asdf-vm/asdf + ASDF_VERSION: 31e8c93004abd76253d186b8896785895069749b # v0.15.0 # pragma: allowlist secret + +jobs: + universal-addon: + if: github.repository != 'lablabs/terraform-aws-eks-universal-addon' + runs-on: ubuntu-24.04 + steps: + - name: Generate GitHub App token + id: template-sync-app-token + uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2 + with: + app-id: ${{ secrets.LARA_TEMPLATE_SYNC_APP_ID }} + private-key: ${{ secrets.LARA_TEMPLATE_SYNC_APP_PRIVATE_KEY }} + repositories: ${{ github.event.repository.name }} + owner: ${{ github.repository_owner }} + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + token: ${{ steps.template-sync-app-token.outputs.token }} # needed for private repositories + persist-credentials: false + + - name: Sync universal-addon template + uses: AndreasAugustin/actions-template-sync@bcb94410a4f1dffdfe5eaabc8234c3b8e76ebc5b # v2.5.1 + with: + source_gh_token: ${{ steps.template-sync-app-token.outputs.token }} + source_repo_path: lablabs/terraform-aws-eks-universal-addon + upstream_branch: main + + target_gh_token: ${{ steps.template-sync-app-token.outputs.token }} + + git_remote_pull_params: --allow-unrelated-histories --squash --strategy=recursive --no-tags -X theirs + + pr_labels: kind/sync + pr_branch_name_prefix: "feat/universal-addon-sync" + pr_title: "feat(sync): sync universal-addon changes" + pr_commit_msg: "feat(sync): sync universal-addon changes" + + is_pr_cleanup: true + + - name: Setup ASDF + uses: asdf-vm/actions/setup@05e0d2ed97b598bfce82fd30daf324ae0c4570e6 # v3.0.2 + + - name: Cache ASDF + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + id: asdf-cache + with: + # https://github.com/asdf-vm/asdf/blob/master/.gitignore + path: | + ~/.asdf/installs + ~/.asdf/plugins + ~/.asdf/shims + key: ${{ runner.os }}-asdf-${{ hashFiles('.tool-versions') }} + restore-keys: ${{ runner.os }}-asdf- + + - name: Install ASDF + uses: asdf-vm/actions/install@05e0d2ed97b598bfce82fd30daf324ae0c4570e6 # v3.0.2 + if: ${{ steps.asdf-cache.outputs.cache-hit != 'true' }} + with: + asdf_branch: ${{ env.ASDF_VERSION }} + + - name: Reshim installed ASDF tools + shell: bash + run: asdf reshim + + - name: Cache pip + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + with: + path: ~/.cache/pip/ + key: ${{ runner.os }}-pip-${{ hashFiles('.pre-commit-config.yaml') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Update README.md + run: pre-commit run --show-diff-on-failure --color=always terraform_docs --all-files || true + + - name: Commit and push README.md + uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4 + with: + add: README.md + message: "docs: update README.md" diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 2b9e3e7..b7463fe 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -11,42 +11,45 @@ on: - master jobs: - versionExtract: + extract-version: name: Extract min/max Terraform versions - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false - name: Extract Terraform min/max versions - id: minMax - uses: clowdhaus/terraform-min-max@main + id: terraform-min-max + uses: clowdhaus/terraform-min-max@f489335873df04c3ce04b5e73f385a726d910039 # v1.3.2 with: directory: . outputs: - minVersion: ${{ steps.minMax.outputs.minVersion }} - maxVersion: ${{ steps.minMax.outputs.maxVersion }} + minVersion: ${{ steps.terraform-min-max.outputs.minVersion }} + maxVersion: ${{ steps.terraform-min-max.outputs.maxVersion }} terraform-validate: - runs-on: ubuntu-22.04 - needs: versionExtract + runs-on: ubuntu-24.04 + needs: extract-version strategy: matrix: tf_ver: - - ${{ needs.versionExtract.outputs.minVersion }} - - ${{ needs.versionExtract.outputs.maxVersion }} - + - ${{ needs.extract-version.outputs.minVersion }} + - ${{ needs.extract-version.outputs.maxVersion }} steps: - - uses: actions/checkout@v3 - - uses: hashicorp/setup-terraform@v2 - with: - terraform_version: ${{ matrix.tf_ver }} - - - name: Terraform Init - id: init - run: terraform init - - - name: Terraform Validate - id: validate - run: terraform validate + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + + - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 + with: + terraform_version: ${{ matrix.tf_ver }} + + - name: Terraform Init + run: terraform init + + - name: Terraform Validate + run: terraform validate diff --git a/.gitignore b/.gitignore index dd32dc8..18221f8 100644 --- a/.gitignore +++ b/.gitignore @@ -32,5 +32,3 @@ override.tf.json # Ignore CLI configuration files .terraformrc terraform.rc - -.terraform.lock.hcl diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2f4c9dd..60a9cad 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,28 +1,58 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + # renovate: datasource=github-tags depName=pre-commit/pre-commit-hooks + rev: cef0300fd0fc4d2a87a85fa2093c6b283ea36f4b # v5.0.0 # pragma: allowlist secret hooks: - id: trailing-whitespace + args: ["--markdown-linebreak-ext=md"] - 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 - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.75.0 + # renovate: datasource=github-releases depName=antonbabenko/pre-commit-terraform + rev: 55d0143972eec4905fdaea2f444f1e88218f9dce # v1.96.3 # pragma: allowlist secret hooks: - - id: terraform_fmt - - id: terraform_tflint - - id: terraform_validate - - id: terraform_checkov - - id: terraform_docs - args: - - '--args=--config=.terraform-docs.yml' + - id: terraform_validate + - id: terraform_fmt + - id: terraform_providers_lock + args: + - --hook-config=--mode=only-check-is-current-lockfile-cross-platform + - --args=-platform=darwin_amd64 + - --args=-platform=darwin_arm64 + - --args=-platform=linux_amd64 + - id: terraform_tflint + args: + - --args=--config=__GIT_WORKING_DIR__/.tflint.hcl + - id: terraform_checkov + args: + - "--args=--quiet --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" - repo: https://github.com/Yelp/detect-secrets - rev: v1.3.0 + # renovate: datasource=github-releases depName=Yelp/detect-secrets + rev: 01886c8a910c64595c47f186ca1ffc0b77fa5458 # v1.5.0 # pragma: allowlist secret hooks: - id: detect-secrets - args: ['--baseline', '.secrets.baseline'] + args: ["--baseline", ".secrets.baseline"] exclude: terraform.tfstate + + - repo: https://github.com/woodruffw/zizmor-pre-commit + # renovate: datasource=github-releases depName=woodruffw/zizmor-pre-commit + rev: 07a06156e31897fbb5ba0e22a961e8e3c2a0677b # v1.16.0 # pragma: allowlist secret + hooks: + - id: zizmor + + - 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/.secrets.baseline b/.secrets.baseline index eaf7047..45f65d3 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -1,5 +1,5 @@ { - "version": "1.3.0", + "version": "1.5.0", "plugins_used": [ { "name": "ArtifactoryDetector" @@ -20,9 +20,15 @@ { "name": "CloudantDetector" }, + { + "name": "DiscordBotTokenDetector" + }, { "name": "GitHubTokenDetector" }, + { + "name": "GitLabTokenDetector" + }, { "name": "HexHighEntropyString", "limit": 3.0 @@ -33,6 +39,9 @@ { "name": "IbmCosHmacDetector" }, + { + "name": "IPPublicDetector" + }, { "name": "JwtTokenDetector" }, @@ -46,9 +55,15 @@ { "name": "NpmDetector" }, + { + "name": "OpenAIDetector" + }, { "name": "PrivateKeyDetector" }, + { + "name": "PypiTokenDetector" + }, { "name": "SendGridDetector" }, @@ -64,6 +79,9 @@ { "name": "StripeDetector" }, + { + "name": "TelegramBotTokenDetector" + }, { "name": "TwilioKeyDetector" } @@ -109,5 +127,5 @@ } ], "results": {}, - "generated_at": "2022-07-28T10:50:47Z" + "generated_at": "2025-03-28T07:59:49Z" } diff --git a/.templatesyncignore b/.templatesyncignore new file mode 100644 index 0000000..7901ba9 --- /dev/null +++ b/.templatesyncignore @@ -0,0 +1,10 @@ +modules +examples/basic/main.tf +main.tf +variables.tf +README.md +.secrets.baseline +.github/workflows/renovate.yaml +renovate.json +addon-oidc.tf +variables-addon-oidc.tf diff --git a/.terraform-docs.yml b/.terraform-docs.yml index cb998c2..d45d422 100644 --- a/.terraform-docs.yml +++ b/.terraform-docs.yml @@ -1,11 +1,28 @@ formatter: markdown table +header-from: main.tf +footer-from: docs/.footer.md + +content: |- + {{ .Header }} + {{ include "docs/.addon.md" }} + {{ .Requirements }} + {{ .Providers }} + {{ .Modules }} + {{ .Resources }} + {{ include "docs/.inputs.md" }} + {{ .Inputs }} + {{ .Outputs }} + {{ .Footer }} + output: - mode: inject + file: README.md + mode: replace template: |- - + {{ .Content }} - + + {{- printf "\n" -}} sections: hide: @@ -13,3 +30,7 @@ sections: sort: by: required + +settings: + default: false + required: false diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl new file mode 100644 index 0000000..a1b3c67 --- /dev/null +++ b/.terraform.lock.hcl @@ -0,0 +1,99 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/cloudposse/utils" { + version = "1.19.2" + constraints = ">= 0.17.0" + hashes = [ + "h1:0Ch7BTulKB1jXOm0AV7d5f1bdMKEyZc1BA+PZ6cXkAY=", + "h1:gqYR81ADrA9HeWCMnEOg/x9RIMce6dwOXOC/DxjsYto=", + "h1:yy3kB4scsoyM81yyyUMPxuJXeFvexBL5KMrCKrjrUkE=", + "h1:zeLrxuXDYEA5+hArYpigYKZJiIB57WQ3nn7VGTc0QDc=", + "zh:1002d1c3f458b569119b31eb2f732c093922b7f86aa59d999d77c3f3ca297f53", + "zh:367ca0d95bf24db1ff6632da94affe1ac0b51679e00f6ca3f1b8f927b9724c3b", + "zh:3e48ef23e276d18a88405926f39b476d40fb543859f2fcfc316f70501071c1ed", + "zh:3fe9d58ee267423e65c9c52cb486dda1eb59973f42eea9d84fe4c842108fdb73", + "zh:5e9ee6099ee56c30c3dfec935f749b3cef9ad2d4c6d8ad2cf39ee87587fc496d", + "zh:6babf986f8af41c739f1e441a4c0512262ff8bc36892f9506839b126138fce25", + "zh:6d9e659f1e18e409149ed8090ced8894317f37cdf234b34fe86b5aba354d559b", + "zh:828109b900c0fa9240bd48358423034817ab3a81d706b29d84a0e10401766ae4", + "zh:aff0d59c6ba5713a09e11a4f14dad048d787569e92ed4d6aa4b7778d39f52d31", + "zh:b7f469e47d1f94b276590809388ac216f59e1f4fb2d6b950c3f9fcbe9e4e2161", + "zh:b9003915fcbdd74c9e02ba11935daa6110516bf434bfee58f738ae3f2a595c2b", + "zh:dea118d95fe434b9089321e6db7573a882bd8b36d89fe2527e9adefa538561e1", + "zh:e18ef6d2be2cee7b8d0ac03c5eec362fd132c8f2b48da3999a280a4d778ec6ea", + "zh:f317eb941a57e6a899afa44ed6dc12a5c51228fcdf1b3043823346f3887facc9", + ] +} + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.42.0" + constraints = "~> 5.0" + hashes = [ + "h1:0lkSSlK45Qil9fO1kFy8RXVC/k6qfC4LDZIaCKnWcUc=", + "h1:Gwe5HXZYD/3M5j6LwKhp8amb1SraCR9p+G96d381RVc=", + "h1:Wjmg0WFQxZ7J7OeZ/SY+NW4JRe/jKJEut5tVb51z++4=", + "h1:Yxsj34z606m8wssYDHyleuBlQ9i+94MHwRs38thQPZU=", + "zh:0fb12bd56a3ad777b29f957c56dd2119776dbc01b6074458f597990e368c82de", + "zh:16e99c13bef6e3777f67c240c916f57c01c9c142254cfb2720e08281ff906447", + "zh:218268f5fe73bcb19e9a996f781ab66df0da9e333d1c60612e3c51ad28a5105f", + "zh:220b17f7053d11548f35136669687d30ef1f1036e15393275325fd2b9654c715", + "zh:2256cfd74988ce05eada76b42efffc6fe2bf4d60b61f57e4db4fcf65ced4c666", + "zh:52da19f531e0cb9828f73bca620e30264e63a494bd7f9ce826aabcf010d3a241", + "zh:56069ce08d720280ba39aaf2fdd40c4357ffb54262c80e4d39c4e540a38e76af", + "zh:82c81398e68324029167f813fbb7c54fa3d233e99fa05001d85cbce8bdd08bb3", + "zh:82d6eaa87f5ab318959064e6c89adc2baabaf70b13f2f7de866f62416de05352", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:ade8490cfdd8de8b9a82986588595b67e0ad1048d9e2d3a6f5164320179c2cd0", + "zh:b094ef56ae9bfffd586f46d4f7fb0097798738df758a8f3c51578ee163495c7e", + "zh:bd5e68e1e454bae0f8d73cff8448e814a35855a561c33b745e1b8b525fb06c9f", + "zh:c111c6a854bf121facca1642d528bfa80fb4214554ac6c33e4a59c86bc605b71", + "zh:e04df69a557adbcdf8efc77eb45be748f0acbe800ccede1e0895393c87722a0f", + ] +} + +provider "registry.terraform.io/hashicorp/helm" { + version = "2.12.1" + constraints = ">= 2.6.0" + hashes = [ + "h1:7wfYOAeSEchHB8idNl+2jf+OkFi9zFSOLWkEZFuTCik=", + "h1:aBfcqM4cbywa7TAxfT1YoFS+Cst9waerlm4XErFmJlk=", + "h1:sgYI7lwGqJqPopY3NGmhb1eQ0YbH8PIXaAZAmnJrAvw=", + "h1:xwHVa6ab/XVfDrZ3h35OzLJ6g0Zte4VAvSnyKw3f9AI=", + "zh:1d623fb1662703f2feb7860e3c795d849c77640eecbc5a776784d08807b15004", + "zh:253a5bc62ba2c4314875139e3fbd2feaad5ef6b0fb420302a474ab49e8e51a38", + "zh:282358f4ad4f20d0ccaab670b8645228bfad1c03ac0d0df5889f0aea8aeac01a", + "zh:4fd06af3091a382b3f0d8f0a60880f59640d2b6d9d6a31f9a873c6f1bde1ec50", + "zh:6816976b1830f5629ae279569175e88b497abbbac30ee809948a1f923c67a80d", + "zh:7d82c4150cdbf48cfeec867be94c7b9bd7682474d4df0ebb7e24e148f964844f", + "zh:83f062049eea2513118a4c6054fb06c8600bac96196f25aed2cc21898ec86e93", + "zh:a79eec0cf4c08fca79e44033ec6e470f25ff23c3e2c7f9bc707ed7771c1072c0", + "zh:b2b2d904b2821a6e579910320605bc478bbef063579a23fbfdd6fcb5871b81f8", + "zh:e91177ca06a15487fc570cb81ecef6359aa399459ea2aa7c4f7367ba86f6fcad", + "zh:e976bcb82996fc4968f8382bbcb6673efb1f586bf92074058a232028d97825b1", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "2.27.0" + constraints = ">= 2.20.0" + hashes = [ + "h1:/3kLyOR2jTaWS1MKso4xAztrocGBMxi8yVadWiqSWOg=", + "h1:GzU0FzYAT/+IgAhnSBcFH3bT+4I5N6oSga6iZgNJAus=", + "h1:TrlG/sofnDv8kAbzKOD5pIPeUiI5VQY61NuWH+cItDw=", + "h1:WuU4rl7szPJr9Nfu5OoQGF84k8yQf+gmS9zU2eZuxcc=", + "zh:3bdba30ae67c55dc7e9a317ac0da3b208ea7926fe9c2f0ae6587ee88dcc58d1f", + "zh:3f35138a831c00b188d2ffee27111dd0cf59afad2dd5653ed9e67d59646de12c", + "zh:64066d18f6ae9a316c2bc840ef3e641d7ab94e1ea3a41d12523e77345ad442ef", + "zh:653063d44b44881af3a480f7f8eaa94fa300e0229df2072d30f606bddcc9f025", + "zh:87f306e37efb61d13efa6da53a1e45e97e5996ebc0568b1caf8c3c5e54c05809", + "zh:8c428b9708f9634391e52300218771eab3fe942bb1295d8c0ad50ca4b33db3d9", + "zh:a44e87119a0337ded15479851786a13f412b413d9a463ba550d1210249206b0f", + "zh:aa2c4d110b0de6ef997c0d45f3f23f8a98f5530753095d6eff439a6d91a8ea31", + "zh:eb15ed8781ac6a0dec2f7d03cf090e23cfa05e3225806c6231ff2c574662fd63", + "zh:eb81c563f93bd3303f9620d11cd49f21f3f89ac3475c6d3e821b239feb9c217d", + "zh:f1a344a7f16131123577e4ec994d04a34ea458ec16c1ccac53fe7946bd817b18", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/.tflint.hcl b/.tflint.hcl index 372282e..81011f8 100644 --- a/.tflint.hcl +++ b/.tflint.hcl @@ -1,11 +1,12 @@ plugin "terraform" { enabled = true - version = "0.1.1" + version = "0.6.0" source = "github.com/terraform-linters/tflint-ruleset-terraform" preset = "recommended" } + plugin "aws" { enabled = true - version = "0.17.0" + version = "0.30.0" source = "github.com/terraform-linters/tflint-ruleset-aws" } diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..c9bf870 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,7 @@ +terraform 1.5.7 +terraform-docs 0.20.0 +tflint 0.50.3 +checkov 3.2.352 +awscli 2.27.4 +pre-commit 4.2.0 +python 3.13.3 diff --git a/README.md b/README.md index 8e0f4b9..0fa8210 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,20 @@ -# AWS EKS Node-Local-DNS Terraform module + +# AWS EKS Node Local DNS Terraform module -[](https://lablabs.io/) - -We help companies build, run, deploy and scale software and infrastructure by embracing the right technologies and principles. Check out our website at - ---- +A Terraform module to deploy the [Node Local DNS](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/) on Amazon EKS cluster. The upgrade process of this module is using the `create before destroy` feature, and the already running DaemonSet will be terminated after the new one is already running. [![Terraform validate](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/validate.yaml/badge.svg)](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/validate.yaml) [![pre-commit](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/pre-commit.yml) -## Description - -A Terraform module to deploy the node-local-dns on Amazon EKS cluster. The upgrade process of this module is using the `create before destroy` feature, and the already running daemonset will be terminated after the new one is already running. +--- ## Related Projects -Check out other [terraform kubernetes addons](https://github.com/orgs/lablabs/repositories?q=terraform-aws-eks&type=public&language=&sort=). +Check out other [Terraform Kubernetes addons](https://github.com/orgs/lablabs/repositories?q=terraform-aws-eks&type=public&language=&sort=). + +[](https://lablabs.io/) + +We help companies build, run, deploy and scale software and infrastructure by embracing the right technologies and principles. Check out our website at . ## Deployment methods @@ -34,142 +33,134 @@ Deploy Helm chart as ArgoCD Application via Kubernetes manifest resource (set `e ### Argo Helm Deploy Helm chart as ArgoCD Application via Helm resource (set `enabled = true`, `argo_enabled = true` and `argo_helm_enabled = true`) - - - - ## Examples -See [Basic example](examples/basic/README.md) for further information. - - +See [basic example](examples/basic) for further information. ## Requirements | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 4.19.0 | +| [terraform](#requirement\_terraform) | >= 1.5.0 | +| [aws](#requirement\_aws) | ~> 5 | | [helm](#requirement\_helm) | >= 2.6.0 | -| [kubernetes](#requirement\_kubernetes) | >= 2.16.0 | -| [random](#requirement\_random) | >= 3.4.3 | +| [kubernetes](#requirement\_kubernetes) | >= 2.20.0 | | [utils](#requirement\_utils) | >= 0.17.0 | ## Modules -No modules. - +| Name | Source | Version | +|------|--------|---------| +| [addon](#module\_addon) | git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon | v0.0.18 | +| [addon-irsa](#module\_addon-irsa) | git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon-irsa | v0.0.18 | ## Resources | Name | Type | |------|------| -| [aws_iam_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | -| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | -| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | -| [aws_iam_role_policy_attachment.this_additional](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | -| [helm_release.argo_application](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | -| [helm_release.this](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | -| [kubernetes_job.helm_argo_application_wait](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/job) | resource | -| [kubernetes_manifest.this](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | -| [kubernetes_role.helm_argo_application_wait](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/role) | resource | -| [kubernetes_role_binding.helm_argo_application_wait](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/role_binding) | resource | -| [kubernetes_service_account.helm_argo_application_wait](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service_account) | resource | -| [random_integer.metrics_port](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) | resource | -| [random_pet.release_name_suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | -| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | -| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [aws_iam_policy_document.this_assume](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [aws_iam_policy_document.this_irsa](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [utils_deep_merge_yaml.argo_helm_values](https://registry.terraform.io/providers/cloudposse/utils/latest/docs/data-sources/deep_merge_yaml) | data source | | [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[-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 | Default | Required | -|------|-------------|------|---------|:--------:| -| [cluster\_identity\_oidc\_issuer](#input\_cluster\_identity\_oidc\_issuer) | The OIDC Identity issuer for the cluster | `string` | n/a | yes | -| [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 | `string` | n/a | yes | -| [argo\_apiversion](#input\_argo\_apiversion) | ArgoCD Appliction apiVersion | `string` | `"argoproj.io/v1alpha1"` | no | -| [argo\_destination\_server](#input\_argo\_destination\_server) | Destination server for ArgoCD Application | `string` | `"https://kubernetes.default.svc"` | no | -| [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 | `bool` | `false` | no | -| [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 | `bool` | `false` | no | -| [argo\_helm\_values](#input\_argo\_helm\_values) | Value overrides to use when deploying argo application object with helm | `string` | `""` | no | -| [argo\_helm\_wait\_backoff\_limit](#input\_argo\_helm\_wait\_backoff\_limit) | Backoff limit for ArgoCD Application Helm release wait job | `number` | `6` | no | -| [argo\_helm\_wait\_node\_selector](#input\_argo\_helm\_wait\_node\_selector) | Node selector for ArgoCD Application Helm release wait job | `map(string)` | `{}` | no | -| [argo\_helm\_wait\_timeout](#input\_argo\_helm\_wait\_timeout) | Timeout for ArgoCD Application Helm release wait job | `string` | `"10m"` | no | -| [argo\_helm\_wait\_tolerations](#input\_argo\_helm\_wait\_tolerations) | Tolerations for ArgoCD Application Helm release wait job | `list(any)` | `[]` | no | -| [argo\_info](#input\_argo\_info) | ArgoCD info manifest parameter |
list(object({
name = string
value = string
}))
|
[
{
"name": "terraform",
"value": "true"
}
]
| no | -| [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. | `list(string)` |
[
"metadata.labels",
"metadata.annotations",
"metadata.finalizers"
]
| no | -| [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 | `bool` | `false` | no | -| [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` | `"Terraform"` | no | -| [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. | `map(string)` |
{
"status.health.status": "Healthy",
"status.operationState.phase": "Succeeded",
"status.sync.status": "Synced"
}
| no | -| [argo\_metadata](#input\_argo\_metadata) | ArgoCD Application metadata configuration. Override or create additional metadata parameters | `any` |
{
"finalizers": [
"resources-finalizer.argocd.argoproj.io"
]
}
| no | -| [argo\_namespace](#input\_argo\_namespace) | Namespace to deploy ArgoCD application CRD to | `string` | `"argo"` | no | -| [argo\_project](#input\_argo\_project) | ArgoCD Application project | `string` | `"default"` | no | -| [argo\_spec](#input\_argo\_spec) | ArgoCD Application spec configuration. Override or create additional spec parameters | `any` | `{}` | no | -| [argo\_sync\_policy](#input\_argo\_sync\_policy) | ArgoCD syncPolicy manifest parameter | `any` | `{}` | no | -| [enabled](#input\_enabled) | Variable indicating whether deployment is enabled | `bool` | `true` | no | -| [helm\_atomic](#input\_helm\_atomic) | If set, installation process purges chart on fail. The wait flag will be set automatically if atomic is used | `bool` | `false` | no | -| [helm\_chart\_name](#input\_helm\_chart\_name) | Helm chart name to be installed | `string` | `"node-local-dns"` | no | -| [helm\_chart\_version](#input\_helm\_chart\_version) | Version of the Helm chart | `string` | `"1.4.0"` | no | -| [helm\_cleanup\_on\_fail](#input\_helm\_cleanup\_on\_fail) | Allow deletion of new resources created in this helm upgrade when upgrade fails | `bool` | `false` | no | -| [helm\_create\_namespace](#input\_helm\_create\_namespace) | Create the namespace if it does not yet exist | `bool` | `true` | no | -| [helm\_dependency\_update](#input\_helm\_dependency\_update) | Runs helm dependency update before installing the chart | `bool` | `false` | no | -| [helm\_description](#input\_helm\_description) | Set helm release description attribute (visible in the history) | `string` | `""` | no | -| [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 | `bool` | `false` | no | -| [helm\_disable\_openapi\_validation](#input\_helm\_disable\_openapi\_validation) | If set, the installation process will not validate rendered helm templates against the Kubernetes OpenAPI Schema | `bool` | `false` | no | -| [helm\_disable\_webhooks](#input\_helm\_disable\_webhooks) | Prevent helm chart hooks from running | `bool` | `false` | no | -| [helm\_force\_update](#input\_helm\_force\_update) | Force helm resource update through delete/recreate if needed | `bool` | `false` | no | -| [helm\_keyring](#input\_helm\_keyring) | Location of public keys used for verification. Used only if helm\_package\_verify is true | `string` | `"~/.gnupg/pubring.gpg"` | no | -| [helm\_lint](#input\_helm\_lint) | Run the helm chart linter during the plan | `bool` | `false` | no | -| [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 | `bool` | `false` | no | -| [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 | `map(any)` | `{}` | no | -| [helm\_recreate\_pods](#input\_helm\_recreate\_pods) | Perform pods restart during helm upgrade/rollback | `bool` | `false` | no | -| [helm\_release\_max\_history](#input\_helm\_release\_max\_history) | Maximum number of release versions stored per release | `number` | `0` | no | -| [helm\_release\_name](#input\_helm\_release\_name) | Helm release name | `string` | `"node-local-dns"` | no | -| [helm\_render\_subchart\_notes](#input\_helm\_render\_subchart\_notes) | If set, render helm subchart notes along with the parent | `bool` | `true` | no | -| [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 | `bool` | `false` | no | -| [helm\_repo\_ca\_file](#input\_helm\_repo\_ca\_file) | Helm repositories cert file | `string` | `""` | no | -| [helm\_repo\_cert\_file](#input\_helm\_repo\_cert\_file) | Helm repositories cert file | `string` | `""` | no | -| [helm\_repo\_key\_file](#input\_helm\_repo\_key\_file) | Helm repositories cert key file | `string` | `""` | no | -| [helm\_repo\_password](#input\_helm\_repo\_password) | Password for HTTP basic authentication against the helm repository | `string` | `""` | no | -| [helm\_repo\_url](#input\_helm\_repo\_url) | Helm repository | `string` | `"https://lablabs.github.io/k8s-nodelocaldns-helm/"` | no | -| [helm\_repo\_username](#input\_helm\_repo\_username) | Username for HTTP basic authentication against the helm repository | `string` | `""` | no | -| [helm\_reset\_values](#input\_helm\_reset\_values) | When upgrading, reset the values to the ones built into the helm chart | `bool` | `false` | no | -| [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 | `bool` | `false` | no | -| [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 | `map(any)` | `{}` | no | -| [helm\_skip\_crds](#input\_helm\_skip\_crds) | If set, no CRDs will be installed before helm release | `bool` | `false` | no | -| [helm\_timeout](#input\_helm\_timeout) | Time in seconds to wait for any individual kubernetes operation (like Jobs for hooks) | `number` | `300` | no | -| [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 | `bool` | `true` | no | -| [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 | `bool` | `false` | no | -| [irsa\_additional\_policies](#input\_irsa\_additional\_policies) | Map of the additional policies to be attached to default role. Where key is arbitrary id and value is policy arn. | `map(string)` | `{}` | no | -| [irsa\_assume\_role\_arn](#input\_irsa\_assume\_role\_arn) | Assume role arn. Assume role must be enabled. | `string` | `""` | no | -| [irsa\_assume\_role\_enabled](#input\_irsa\_assume\_role\_enabled) | Whether IRSA is allowed to assume role defined by irsa\_assume\_role\_arn. | `bool` | `false` | no | -| [irsa\_policy\_enabled](#input\_irsa\_policy\_enabled) | Whether to create opinionated policy to allow operations on specified zones in `policy_allowed_zone_ids`. | `bool` | `true` | no | -| [irsa\_role\_create](#input\_irsa\_role\_create) | Whether to create IRSA role and annotate service account | `bool` | `true` | no | -| [irsa\_role\_name\_prefix](#input\_irsa\_role\_name\_prefix) | The IRSA role name prefix for node-local-dns | `string` | `"node-local-dns-irsa"` | no | -| [irsa\_tags](#input\_irsa\_tags) | IRSA resources tags | `map(string)` | `{}` | no | -| [namespace](#input\_namespace) | The K8s namespace in which the kube-system service account has been created | `string` | `"kube-system"` | no | -| [rbac\_create](#input\_rbac\_create) | Whether to create and use RBAC resources | `bool` | `true` | no | -| [service\_account\_create](#input\_service\_account\_create) | Whether to create Service Account | `bool` | `true` | no | -| [service\_account\_name](#input\_service\_account\_name) | The k8s node-local-dns service account name | `string` | `"node-local-dns"` | no | -| [settings](#input\_settings) | Additional helm sets which will be passed to the Helm chart values, see https://github.com/lablabs/k8s-nodelocaldns-helm/tree/master/charts/node-local-dns | `map(any)` | `{}` | no | -| [values](#input\_values) | Additional yaml encoded values which will be passed to the Helm chart, see https://github.com/lablabs/k8s-nodelocaldns-helm/tree/master/charts/node-local-dns | `string` | `""` | no | - +| 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\_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\_kubectl\_version](#input\_argo\_helm\_wait\_kubectl\_version) | Version of kubectl to use for ArgoCD Application wait job. Defaults to `1.33.0`. | `string` | +| [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\_tolerations](#input\_argo\_helm\_wait\_tolerations) | Tolerations for ArgoCD Application Helm release wait job. Defaults to `[]`. | `list(any)` | +| [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\_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\_name](#input\_argo\_name) | Name of the ArgoCD Application. Required if `argo_source_type` is set to `kustomize` or `directory`. If `argo_source_type` is set to `helm`, ArgoCD Application name will equal `helm_release_name`. Defaults to `""`. | `string` | +| [argo\_namespace](#input\_argo\_namespace) | Namespace to deploy ArgoCD Application to. Defaults to `argo`. | `string` | +| [argo\_operation](#input\_argo\_operation) | ArgoCD Application manifest operation parameter. Defaults to `{}`. | `any` | +| [argo\_project](#input\_argo\_project) | ArgoCD Application project. Defaults to `default`. | `string` | +| [argo\_source\_path](#input\_argo\_source\_path) | ArgoCD Application source path. Required if `argo_source_type` is set to `kustomize` or `directory`. Defaults to `""`. | `string` | +| [argo\_source\_repo\_url](#input\_argo\_source\_repo\_url) | ArgoCD Application source repo URL. Required if `argo_source_type` is set to `kustomize` or `directory`. Defaults to `""`. | `string` | +| [argo\_source\_target\_revision](#input\_argo\_source\_target\_revision) | ArgoCD Application source target revision. Required if `argo_source_type` is set to `kustomize` or `directory`. Defaults to `""`. | `string` | +| [argo\_source\_type](#input\_argo\_source\_type) | Source type for ArgoCD Application. Can be either `helm`, `kustomize`, or `directory`. Defaults to `helm`. | `string` | +| [argo\_spec](#input\_argo\_spec) | ArgoCD Application spec configuration. Configuration is extended by deep merging with the default spec parameters. Defaults to `{}`. | `any` | +| [argo\_spec\_override](#input\_argo\_spec\_override) | ArgoCD Application spec configuration. Configuration is overriden by merging natively with the default spec parameters. 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 for IRSA). Defaults to `""`. | `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 for IRSA). Defaults to `""`. | `string` | +| [cluster\_name](#input\_cluster\_name) | The name of the cluster (required for pod identity). Defaults to `""`. | `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. Required if `argo_source_type` is set to `helm`. Defaults to `""`. | `string` | +| [helm\_chart\_version](#input\_helm\_chart\_version) | Version of the Helm chart. Required if `argo_source_type` is set to `helm`. Defaults to `""`. | `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\_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` | +| [helm\_disable\_openapi\_validation](#input\_helm\_disable\_openapi\_validation) | If set, the installation process will not validate rendered Helm templates against the Kubernetes OpenAPI Schema. Defaults to `false`. | `bool` | +| [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\_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. Required if `argo_source_type` is set to `helm`. Defaults to `""`. | `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. Required if `argo_source_type` is set to `helm`. Defaults to `""`. | `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\_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`. 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\_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 `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 (required). | `string` | +| [pod\_identity\_additional\_policies](#input\_pod\_identity\_additional\_policies) | Map of the additional policies to be attached to pod identity role. Where key is arbitrary id and value is policy ARN. Defaults to `{}`. | `map(string)` | +| [pod\_identity\_permissions\_boundary](#input\_pod\_identity\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the pod identity role. Defaults to `null`. | `string` | +| [pod\_identity\_policy](#input\_pod\_identity\_policy) | AWS IAM policy JSON document to be attached to the pod identity role. Applied only if `pod_identity_policy_enabled` is `true`. Defaults to `""`. | `string` | +| [pod\_identity\_policy\_enabled](#input\_pod\_identity\_policy\_enabled) | Whether to create IAM policy specified by `pod_identity_policy`. Defaults to `false`. | `bool` | +| [pod\_identity\_role\_create](#input\_pod\_identity\_role\_create) | Whether to create pod identity role and annotate Service Account. Defaults to `false`. | `bool` | +| [pod\_identity\_role\_name](#input\_pod\_identity\_role\_name) | Pod identity role name. The value is prefixed by `pod_identity_role_name_prefix`. Either `pod_identity_role_name` or `pod_identity_role_name_prefix` must be set. Defaults to `""`. | `string` | +| [pod\_identity\_role\_name\_prefix](#input\_pod\_identity\_role\_name\_prefix) | Pod identity role name prefix. Either `pod_identity_role_name_prefix` or `pod_identity_role_name` must be set. Defaults to `""`. | `string` | +| [pod\_identity\_tags](#input\_pod\_identity\_tags) | Pod identity 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 `""`. | `string` | +| [service\_account\_namespace](#input\_service\_account\_namespace) | The Kubernetes Service Account namespace. Defaults to `""`. | `string` | +| [settings](#input\_settings) | Additional Helm sets which will be passed to the Helm chart values or Kustomize or directory configuration which will be passed to ArgoCD Application source. Defaults to `{}`. | `map(any)` | +| [values](#input\_values) | Additional YAML encoded values which will be passed to the Helm chart. Defaults to `""`. | `string` | ## Outputs | Name | Description | |------|-------------| -| [helm\_release\_application\_metadata](#output\_helm\_release\_application\_metadata) | Argo application helm release attributes | -| [helm\_release\_metadata](#output\_helm\_release\_metadata) | Helm release attributes | -| [iam\_role\_attributes](#output\_iam\_role\_attributes) | <$addon-name> IAM role atributes | -| [kubernetes\_application\_attributes](#output\_kubernetes\_application\_attributes) | Argo kubernetes manifest attributes | - - +| [addon](#output\_addon) | The addon module outputs | +| [addon\_irsa](#output\_addon\_irsa) | The addon IRSA module outputs | ## Contributing and reporting issues Feel free to create an issue in this repository if you have questions, suggestions or feature requests. @@ -207,3 +198,4 @@ See [LICENSE](LICENSE) for full details. KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + diff --git a/addon-irsa.tf b/addon-irsa.tf new file mode 100644 index 0000000..969281c --- /dev/null +++ b/addon-irsa.tf @@ -0,0 +1,52 @@ +# 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. +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.18" + + enabled = var.enabled + + rbac_create = var.rbac_create != null ? var.rbac_create : try(each.value.rbac_create, null) + service_account_create = var.service_account_create != null ? var.service_account_create : try(each.value.service_account_create, null) + service_account_name = var.service_account_name != null ? var.service_account_name : try(each.value.service_account_name, each.key) + service_account_namespace = var.service_account_namespace != null ? var.service_account_namespace : try(each.value.service_account_namespace, local.addon_namespace) + + # IRSA + cluster_identity_oidc_issuer = var.cluster_identity_oidc_issuer != null ? var.cluster_identity_oidc_issuer : try(each.value.cluster_identity_oidc_issuer, null) + cluster_identity_oidc_issuer_arn = var.cluster_identity_oidc_issuer_arn != null ? var.cluster_identity_oidc_issuer_arn : try(each.value.cluster_identity_oidc_issuer_arn, null) + + irsa_role_create = var.irsa_role_create != null ? var.irsa_role_create : try(each.value.irsa_role_create, null) + irsa_role_name_prefix = var.irsa_role_name_prefix != null ? var.irsa_role_name_prefix : try(each.value.irsa_role_name_prefix, "${each.key}-irsa") + irsa_role_name = var.irsa_role_name != null ? var.irsa_role_name : try(each.value.irsa_role_name, local.addon_name) + + irsa_policy_enabled = var.irsa_policy_enabled != null ? var.irsa_policy_enabled : try(each.value.irsa_policy_enabled, null) + irsa_policy = var.irsa_policy != null ? var.irsa_policy : try(each.value.irsa_policy, null) + irsa_assume_role_enabled = var.irsa_assume_role_enabled != null ? var.irsa_assume_role_enabled : try(each.value.irsa_assume_role_enabled, null) + irsa_assume_role_arns = var.irsa_assume_role_arns != null ? var.irsa_assume_role_arns : try(each.value.irsa_assume_role_arns, null) + 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 : lookup(each.value, "irsa_additional_policies", null) + + 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, null) + 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, null) + + irsa_tags = var.irsa_tags != null ? var.irsa_tags : try(each.value.irsa_tags, null) + + # Pod identity + cluster_name = var.cluster_name != null ? var.cluster_name : try(each.value.cluster_name, null) + + pod_identity_role_create = var.pod_identity_role_create != null ? var.pod_identity_role_create : try(each.value.pod_identity_role_create, null) + pod_identity_role_name_prefix = var.pod_identity_role_name_prefix != null ? var.pod_identity_role_name_prefix : try(each.value.pod_identity_role_name_prefix, "${each.key}-pi") + pod_identity_role_name = var.pod_identity_role_name != null ? var.pod_identity_role_name : try(each.value.pod_identity_role_name, local.addon_name) + + pod_identity_policy_enabled = var.pod_identity_policy_enabled != null ? var.pod_identity_policy_enabled : try(each.value.pod_identity_policy_enabled, null) + pod_identity_policy = var.pod_identity_policy != null ? var.pod_identity_policy : try(each.value.pod_identity_policy, null) + pod_identity_permissions_boundary = var.pod_identity_permissions_boundary != null ? var.pod_identity_permissions_boundary : try(each.value.pod_identity_permissions_boundary, null) + pod_identity_additional_policies = var.pod_identity_additional_policies != null ? var.pod_identity_additional_policies : lookup(each.value, "pod_identity_additional_policies", null) + + pod_identity_tags = var.pod_identity_tags != null ? var.pod_identity_tags : try(each.value.pod_identity_tags, null) +} + +output "addon_irsa" { + description = "The addon IRSA module outputs" + value = module.addon-irsa +} diff --git a/addon.tf b/addon.tf new file mode 100644 index 0000000..92ce9e9 --- /dev/null +++ b/addon.tf @@ -0,0 +1,101 @@ +# 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. +locals { + addon_argo_source_type = var.argo_source_type != null ? var.argo_source_type : try(local.addon.argo_source_type, "helm") + addon_argo_source_helm_enabled = local.addon_argo_source_type == "helm" + + addon_argo_name = var.argo_name != null ? var.argo_name : try(local.addon.argo_name, local.addon.name) + addon_helm_release_name = var.helm_release_name != null ? var.helm_release_name : try(local.addon.helm_release_name, local.addon.name) + + addon_name = local.addon_argo_source_helm_enabled ? local.addon_helm_release_name : local.addon_argo_name + addon_namespace = var.namespace != null ? var.namespace : try(local.addon.namespace, local.addon.name) +} + +module "addon" { + source = "git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon?ref=v0.0.18" + + enabled = var.enabled + + # variable priority var.* (provided by the module user) > local.addon.* (universal addon default override) > default (universal addon default) + namespace = local.addon_namespace + + helm_enabled = var.helm_enabled != null ? var.helm_enabled : try(local.addon.helm_enabled, null) + helm_release_name = local.addon_name + helm_chart_name = var.helm_chart_name != null ? var.helm_chart_name : try(local.addon.helm_chart_name, local.addon.name) + helm_chart_version = var.helm_chart_version != null ? var.helm_chart_version : try(local.addon.helm_chart_version, null) + helm_atomic = var.helm_atomic != null ? var.helm_atomic : try(local.addon.helm_atomic, null) + helm_cleanup_on_fail = var.helm_cleanup_on_fail != null ? var.helm_cleanup_on_fail : try(local.addon.helm_cleanup_on_fail, null) + helm_create_namespace = var.helm_create_namespace != null ? var.helm_create_namespace : try(local.addon.helm_create_namespace, null) + helm_dependency_update = var.helm_dependency_update != null ? var.helm_dependency_update : try(local.addon.helm_dependency_update, null) + helm_description = var.helm_description != null ? var.helm_description : try(local.addon.helm_description, null) + helm_devel = var.helm_devel != null ? var.helm_devel : try(local.addon.helm_devel, null) + helm_disable_openapi_validation = var.helm_disable_openapi_validation != null ? var.helm_disable_openapi_validation : try(local.addon.helm_disable_openapi_validation, null) + helm_disable_webhooks = var.helm_disable_webhooks != null ? var.helm_disable_webhooks : try(local.addon.helm_disable_webhooks, null) + helm_force_update = var.helm_force_update != null ? var.helm_force_update : try(local.addon.helm_force_update, null) + helm_keyring = var.helm_keyring != null ? var.helm_keyring : try(local.addon.helm_keyring, null) + helm_lint = var.helm_lint != null ? var.helm_lint : try(local.addon.helm_lint, null) + helm_package_verify = var.helm_package_verify != null ? var.helm_package_verify : try(local.addon.helm_package_verify, null) + helm_postrender = var.helm_postrender != null ? var.helm_postrender : try(local.addon.helm_postrender, null) + helm_recreate_pods = var.helm_recreate_pods != null ? var.helm_recreate_pods : try(local.addon.helm_recreate_pods, null) + helm_release_max_history = var.helm_release_max_history != null ? var.helm_release_max_history : try(local.addon.helm_release_max_history, null) + helm_render_subchart_notes = var.helm_render_subchart_notes != null ? var.helm_render_subchart_notes : try(local.addon.helm_render_subchart_notes, null) + helm_replace = var.helm_replace != null ? var.helm_replace : try(local.addon.helm_replace, null) + helm_repo_ca_file = var.helm_repo_ca_file != null ? var.helm_repo_ca_file : try(local.addon.helm_repo_ca_file, null) + helm_repo_cert_file = var.helm_repo_cert_file != null ? var.helm_repo_cert_file : try(local.addon.helm_repo_cert_file, null) + helm_repo_key_file = var.helm_repo_key_file != null ? var.helm_repo_key_file : try(local.addon.helm_repo_key_file, null) + helm_repo_password = var.helm_repo_password != null ? var.helm_repo_password : try(local.addon.helm_repo_password, null) + helm_repo_url = var.helm_repo_url != null ? var.helm_repo_url : try(local.addon.helm_repo_url, null) + helm_repo_username = var.helm_repo_username != null ? var.helm_repo_username : try(local.addon.helm_repo_username, null) + helm_reset_values = var.helm_reset_values != null ? var.helm_reset_values : try(local.addon.helm_reset_values, null) + helm_reuse_values = var.helm_reuse_values != null ? var.helm_reuse_values : try(local.addon.helm_reuse_values, null) + helm_set_sensitive = var.helm_set_sensitive != null ? var.helm_set_sensitive : try(local.addon.helm_set_sensitive, null) + helm_skip_crds = var.helm_skip_crds != null ? var.helm_skip_crds : try(local.addon.helm_skip_crds, null) + helm_timeout = var.helm_timeout != null ? var.helm_timeout : try(local.addon.helm_timeout, null) + helm_wait = var.helm_wait != null ? var.helm_wait : try(local.addon.helm_wait, null) + helm_wait_for_jobs = var.helm_wait_for_jobs != null ? var.helm_wait_for_jobs : try(local.addon.helm_wait_for_jobs, null) + + argo_source_type = local.addon_argo_source_type + argo_source_repo_url = var.argo_source_repo_url != null ? var.argo_source_repo_url : try(local.addon.argo_source_repo_url, null) + argo_source_target_revision = var.argo_source_target_revision != null ? var.argo_source_target_revision : try(local.addon.argo_source_target_revision, null) + argo_source_path = var.argo_source_path != null ? var.argo_source_path : try(local.addon.argo_source_path, null) + + argo_apiversion = var.argo_apiversion != null ? var.argo_apiversion : try(local.addon.argo_apiversion, null) + argo_destination_server = var.argo_destination_server != null ? var.argo_destination_server : try(local.addon.argo_destination_server, null) + argo_enabled = var.argo_enabled != null ? var.argo_enabled : try(local.addon.argo_enabled, null) + argo_helm_enabled = var.argo_helm_enabled != null ? var.argo_helm_enabled : try(local.addon.argo_helm_enabled, null) + argo_helm_values = var.argo_helm_values != null ? var.argo_helm_values : try(local.addon.argo_helm_values, null) + argo_helm_wait_backoff_limit = var.argo_helm_wait_backoff_limit != null ? var.argo_helm_wait_backoff_limit : try(local.addon.argo_helm_wait_backoff_limit, null) + argo_helm_wait_node_selector = var.argo_helm_wait_node_selector != null ? var.argo_helm_wait_node_selector : try(local.addon.argo_helm_wait_node_selector, null) + argo_helm_wait_timeout = var.argo_helm_wait_timeout != null ? var.argo_helm_wait_timeout : try(local.addon.argo_helm_wait_timeout, null) + argo_helm_wait_tolerations = var.argo_helm_wait_tolerations != null ? var.argo_helm_wait_tolerations : try(local.addon.argo_helm_wait_tolerations, null) + argo_helm_wait_kubectl_version = var.argo_helm_wait_kubectl_version != null ? var.argo_helm_wait_kubectl_version : try(local.addon.argo_helm_wait_kubectl_version, null) + argo_info = var.argo_info != null ? var.argo_info : try(local.addon.argo_info, null) + argo_kubernetes_manifest_computed_fields = var.argo_kubernetes_manifest_computed_fields != null ? var.argo_kubernetes_manifest_computed_fields : try(local.addon.argo_kubernetes_manifest_computed_fields, null) + argo_kubernetes_manifest_field_manager_force_conflicts = var.argo_kubernetes_manifest_field_manager_force_conflicts != null ? var.argo_kubernetes_manifest_field_manager_force_conflicts : try(local.addon.argo_kubernetes_manifest_field_manager_force_conflicts, null) + argo_kubernetes_manifest_field_manager_name = var.argo_kubernetes_manifest_field_manager_name != null ? var.argo_kubernetes_manifest_field_manager_name : try(local.addon.argo_kubernetes_manifest_field_manager_name, null) + argo_kubernetes_manifest_wait_fields = var.argo_kubernetes_manifest_wait_fields != null ? var.argo_kubernetes_manifest_wait_fields : try(local.addon.argo_kubernetes_manifest_wait_fields, null) + argo_metadata = var.argo_metadata != null ? var.argo_metadata : try(local.addon.argo_metadata, null) + argo_name = local.addon_name + argo_namespace = var.argo_namespace != null ? var.argo_namespace : try(local.addon.argo_namespace, null) + argo_project = var.argo_project != null ? var.argo_project : try(local.addon.argo_project, null) + argo_spec = var.argo_spec != null ? var.argo_spec : try(local.addon.argo_spec, null) + argo_spec_override = var.argo_spec_override != null ? var.argo_spec_override : try(local.addon.argo_spec_override, null) + argo_sync_policy = var.argo_sync_policy != null ? var.argo_sync_policy : try(local.addon.argo_sync_policy, null) + argo_operation = var.argo_operation != null ? var.argo_operation : try(local.addon.argo_operation, null) + + settings = var.settings != null ? var.settings : try(local.addon.settings, null) + values = one(data.utils_deep_merge_yaml.values[*].output) +} + +data "utils_deep_merge_yaml" "values" { + count = var.enabled ? 1 : 0 + + input = compact([ + local.addon_values, + var.values + ]) +} + +output "addon" { + description = "The addon module outputs" + value = module.addon +} diff --git a/argo-helm.tf b/argo-helm.tf deleted file mode 100644 index d53fb46..0000000 --- a/argo-helm.tf +++ /dev/null @@ -1,170 +0,0 @@ -locals { - helm_argo_application_enabled = var.enabled && var.argo_enabled && var.argo_helm_enabled - helm_argo_application_wait_enabled = local.helm_argo_application_enabled && length(keys(var.argo_kubernetes_manifest_wait_fields)) > 0 - helm_argo_application_values = [ - one(data.utils_deep_merge_yaml.argo_helm_values[*].output), - var.argo_helm_values - ] -} - -data "utils_deep_merge_yaml" "argo_helm_values" { - count = local.helm_argo_application_enabled ? 1 : 0 - - input = compact([ - yamlencode({ - "apiVersion" : var.argo_apiversion - }), - yamlencode({ - "spec" : local.argo_application_values - }), - yamlencode({ - "spec" : var.argo_spec - }), - yamlencode( - local.argo_application_metadata - ), - yamlencode({ - "spec" : { "source" : { "helm" : { "releaseName" : local.helm_release_name } } } - }) - ]) -} - -resource "helm_release" "argo_application" { - count = local.helm_argo_application_enabled ? 1 : 0 - - chart = "${path.module}/helm/argocd-application" - name = local.helm_release_name - namespace = var.argo_namespace - - values = local.helm_argo_application_values - - lifecycle { - create_before_destroy = true - } -} - -resource "kubernetes_role" "helm_argo_application_wait" { - count = local.helm_argo_application_wait_enabled ? 1 : 0 - - metadata { - name = "${var.helm_release_name}-argo-application-wait" - namespace = var.argo_namespace - labels = local.argo_application_metadata.labels - annotations = local.argo_application_metadata.annotations - } - - rule { - api_groups = ["argoproj.io"] - resources = ["applications"] - verbs = ["get", "list", "watch"] - } -} - -resource "kubernetes_role_binding" "helm_argo_application_wait" { - count = local.helm_argo_application_wait_enabled ? 1 : 0 - - metadata { - name = "${var.helm_release_name}-argo-application-wait" - namespace = var.argo_namespace - labels = local.argo_application_metadata.labels - annotations = local.argo_application_metadata.annotations - } - - role_ref { - api_group = "rbac.authorization.k8s.io" - kind = "Role" - name = one(kubernetes_role.helm_argo_application_wait[*].metadata[0].name) - } - - subject { - kind = "ServiceAccount" - name = one(kubernetes_service_account.helm_argo_application_wait[*].metadata[0].name) - namespace = one(kubernetes_service_account.helm_argo_application_wait[*].metadata[0].namespace) - } -} - -resource "kubernetes_service_account" "helm_argo_application_wait" { - count = local.helm_argo_application_wait_enabled ? 1 : 0 - - metadata { - name = "${var.helm_release_name}-argo-application-wait" - namespace = var.argo_namespace - labels = local.argo_application_metadata.labels - annotations = local.argo_application_metadata.annotations - } -} - -resource "kubernetes_job" "helm_argo_application_wait" { - count = local.helm_argo_application_wait_enabled ? 1 : 0 - - metadata { - name = "${var.helm_release_name}-argo-application-wait" - namespace = var.argo_namespace - labels = local.argo_application_metadata.labels - annotations = local.argo_application_metadata.annotations - } - - spec { - template { - metadata { - name = "${var.helm_release_name}-argo-application-wait" - labels = local.argo_application_metadata.labels - annotations = local.argo_application_metadata.annotations - } - - spec { - service_account_name = one(kubernetes_service_account.helm_argo_application_wait[*].metadata[0].name) - - dynamic "container" { - for_each = var.argo_kubernetes_manifest_wait_fields - - content { - name = "${lower(replace(container.key, ".", "-"))}-${md5(jsonencode(local.helm_argo_application_values))}" # md5 suffix is a workaround for https://github.com/hashicorp/terraform-provider-kubernetes/issues/1325 - image = "bitnami/kubectl:latest" - command = ["/bin/bash", "-ecx"] - # Waits for ArgoCD Application to be "Healthy", see https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#wait - # i.e. kubectl wait --for=jsonpath='{.status.sync.status}'=Healthy application.argoproj.io <$addon-name> - args = [ - <<-EOT - kubectl wait \ - --namespace ${var.argo_namespace} \ - --for=jsonpath='{.${container.key}}'=${container.value} \ - --timeout=${var.argo_helm_wait_timeout} \ - application.argoproj.io ${local.helm_release_name} - EOT - ] - } - } - - node_selector = var.argo_helm_wait_node_selector - - dynamic "toleration" { - for_each = var.argo_helm_wait_tolerations - - content { - key = try(toleration.value.key, null) - operator = try(toleration.value.operator, null) - value = try(toleration.value.value, null) - effect = try(toleration.value.effect, null) - } - } - - # ArgoCD Application status fields might not be available immediately after creation - restart_policy = "OnFailure" - } - } - - backoff_limit = var.argo_helm_wait_backoff_limit - } - - wait_for_completion = true - - timeouts { - create = var.argo_helm_wait_timeout - update = var.argo_helm_wait_timeout - } - - depends_on = [ - helm_release.argo_application - ] -} diff --git a/argo.tf b/argo.tf deleted file mode 100644 index 0dfa922..0000000 --- a/argo.tf +++ /dev/null @@ -1,57 +0,0 @@ -locals { - argo_application_metadata = { - "labels" : try(var.argo_metadata.labels, {}), - "annotations" : try(var.argo_metadata.annotations, {}), - "finalizers" : try(var.argo_metadata.finalizers, []) - } - argo_application_values = { - "project" : var.argo_project - "source" : { - "repoURL" : var.helm_repo_url - "chart" : var.helm_chart_name - "targetRevision" : var.helm_chart_version - "helm" : { - "releaseName" : local.helm_release_name - "parameters" : [for k, v in var.settings : tomap({ "forceString" : true, "name" : k, "value" : v })] - "values" : var.enabled ? data.utils_deep_merge_yaml.values[0].output : "" - } - } - "destination" : { - "server" : var.argo_destination_server - "namespace" : var.namespace - } - "syncPolicy" : var.argo_sync_policy - "info" : var.argo_info - } -} - -resource "kubernetes_manifest" "this" { - count = var.enabled && var.argo_enabled && !var.argo_helm_enabled ? 1 : 0 - manifest = { - "apiVersion" = var.argo_apiversion - "kind" = "Application" - "metadata" = merge( - local.argo_application_metadata, - { "name" = local.helm_release_name }, - { "namespace" = var.argo_namespace }, - ) - "spec" = merge( - local.argo_application_values, - var.argo_spec - ) - } - computed_fields = var.argo_kubernetes_manifest_computed_fields - - field_manager { - name = var.argo_kubernetes_manifest_field_manager_name - force_conflicts = var.argo_kubernetes_manifest_field_manager_force_conflicts - } - - wait { - fields = var.argo_kubernetes_manifest_wait_fields - } - - lifecycle { - create_before_destroy = true - } -} diff --git a/docs/.addon.md b/docs/.addon.md new file mode 100644 index 0000000..156c110 --- /dev/null +++ b/docs/.addon.md @@ -0,0 +1,31 @@ + +--- + +## Related Projects + +Check out other [Terraform Kubernetes addons](https://github.com/orgs/lablabs/repositories?q=terraform-aws-eks&type=public&language=&sort=). + +[](https://lablabs.io/) + +We help companies build, run, deploy and scale software and infrastructure by embracing the right technologies and principles. Check out our website at . + +## Deployment methods + +### Helm +Deploy Helm chart via Helm resource (default method, set `enabled = true`) + +### Argo Kubernetes +Deploy Helm chart as ArgoCD Application via Kubernetes manifest resource (set `enabled = true` and `argo_enabled = true`) + +> **Warning** +> +> When deploying with ArgoCD application, Kubernetes terraform provider requires access to Kubernetes cluster API during plan time. This introduces potential issue when you want to deploy the cluster with this addon at the same time, during the same Terraform run. +> +> To overcome this issue, the module deploys the ArgoCD application object using the Helm provider, which does not require API access during plan. If you want to deploy the application using this workaround, you can set the `argo_helm_enabled` variable to `true`. + +### Argo Helm +Deploy Helm chart as ArgoCD Application via Helm resource (set `enabled = true`, `argo_enabled = true` and `argo_helm_enabled = true`) + +## Examples + +See [basic example](examples/basic) for further information. diff --git a/docs/.footer.md b/docs/.footer.md new file mode 100644 index 0000000..971db04 --- /dev/null +++ b/docs/.footer.md @@ -0,0 +1,37 @@ +## Contributing and reporting issues + +Feel free to create an issue in this repository if you have questions, suggestions or feature requests. + +### Validation, linters and pull-requests + +We want to provide high quality code and modules. For this reason we are using +several [pre-commit hooks](.pre-commit-config.yaml) and +[GitHub Actions workflows](.github/workflows/). A pull-request to the +main branch will trigger these validations and lints automatically. Please +check your code before you will create pull-requests. See +[pre-commit documentation](https://pre-commit.com/) and +[GitHub Actions documentation](https://docs.github.com/en/actions) for further +details. + +## License + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) + +See [LICENSE](LICENSE) for full details. + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. diff --git a/docs/.inputs.md b/docs/.inputs.md new file mode 100644 index 0000000..8e1763d --- /dev/null +++ b/docs/.inputs.md @@ -0,0 +1,2 @@ +> [!IMPORTANT] +> 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/examples/basic/.terraform.lock.hcl b/examples/basic/.terraform.lock.hcl new file mode 100644 index 0000000..1f7d58a --- /dev/null +++ b/examples/basic/.terraform.lock.hcl @@ -0,0 +1,161 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/cloudposse/utils" { + version = "1.29.0" + constraints = ">= 0.17.0" + hashes = [ + "h1:GaRpNTCeE+NpvOuH7f2oMHExVHWrjOYJtwwnEr5y2xs=", + "h1:MHQr6iEHmDIl8WNCoIb5YCikU00GgQgKlvz3LBD3TU8=", + "h1:oIaC6Qr0auYbczWtllf5wyghn+im3k15OTphfDAPJiQ=", + "zh:300b7caca5f3233592e0c76678d588889387d8fc5c48ed9fcda8aa74aba0969a", + "zh:30f41007b7f9206999c5e987ccf4929dc8672cd394667bdc5f06364a595afcb6", + "zh:5f0916666e34bc688d727de1bf3e94f4065344b617bc8bfc0f5526ee1e181577", + "zh:6146beb6ef937f4dcc052015eea3a5c0bb807dbd7e4c1a66abde58957dea1c3e", + "zh:80d9e0c6592baf5ef66a63a70e7c14d738ab0949e7be4c179c8f6cdc953e3248", + "zh:8ef5254a0bc231dbe103eb3af1e3005efb0e43318e26b422dd648c2bbe77691a", + "zh:95ff25a69c31089860895376f38809484a84c069419ac0617e68025dafc2a455", + "zh:a3a1da7b8d3c2c2cd4a4e49441b58c4743e17bbe152c99427203bd25b7070cc3", + "zh:a4062e056ba43c3897180d711ac347fa4c23d832cdd1cfae1d91929b7a2ef1c1", + "zh:bc3a389262bad67ea63deb1cd5bbcfff4aa0f444b5000a697fcf17fb19ce938b", + "zh:c0df1fbeaf34240513a66245208e80a7ac42d70e056120aa52ae575a65118c68", + "zh:c6663dcfab08990123b6e4efda12f4b2f4a1b1a67fff3e0e49efbf7f723c3017", + "zh:eb8a3680f83ff7db968eb2ce495f8a34163aac6bea3597157c0ad4d554e8cb5b", + "zh:f62e2bdb77768dff933a19e50897c5117d4825d9956cd01fdce89a902e4ce880", + ] +} + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.97.0" + constraints = ">= 3.0.0, ~> 5.0, >= 5.8.0, >= 5.74.0, >= 5.79.0" + hashes = [ + "h1:WwuqNl8roShq7eOWRKLd6FDFRrr90XwEBVDp+7/9MWU=", + "h1:lI0I9GziJsdymNBcj+MJloqwD8fbogJw3EiR60j5FYU=", + "h1:rUDE0OgA+6IiEA+w0cPp3/QQNH4SpjFjYcQ6p7byKS4=", + "zh:02790ad98b767d8f24d28e8be623f348bcb45590205708334d52de2fb14f5a95", + "zh:088b4398a161e45762dc28784fcc41c4fa95bd6549cb708b82de577f2d39ffc7", + "zh:0c381a457b7af391c43fc0167919443f6105ad2702bde4d02ddea9fd7c9d3539", + "zh:1a4b57a5043dcca64d8b8bae8b30ef4f6b98ed2144f792f39c4e816d3f1e2c56", + "zh:1bf00a67f39e67664337bde065180d41d952242801ebcd1c777061d4ffaa1cc1", + "zh:24c549f53d6bd022af31426d3e78f21264d8a72409821669e7fd41966ae68b2b", + "zh:3abda50bbddb35d86081fe39522e995280aea7f004582c4af22112c03ac8b375", + "zh:7388ed7f21ce2eb46bd9066626ce5f3e2a5705f67f643acce8ae71972f66eaf6", + "zh:96740f2ff94e5df2b2d29a5035a1a1026fe821f61712b2099b224fb2c2277663", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9f399f8e8683a3a3a6d63a41c7c3a5a5f266eedef40ea69eba75bacf03699879", + "zh:bcf2b288d4706ebd198f75d2159663d657535483331107f2cdef381f10688baf", + "zh:cc76c8a9fc3bad05a8779c1f80fe8c388734f1ec1dd0affa863343490527b466", + "zh:de4359cf1b057bfe7a563be93829ec64bf72e7a2b85a72d075238081ef5eb1db", + "zh:e208fa77051a1f9fa1eff6c5c58aabdcab0de1695b97cdea7b8dd81df3e0ed73", + ] +} + +provider "registry.terraform.io/hashicorp/helm" { + version = "2.17.0" + constraints = ">= 2.6.0" + hashes = [ + "h1:0LSHBFqJvHTzQesUwagpDLsrzVliY+t2c26nDJizHFM=", + "h1:K5FEjxvDnxb1JF1kG1xr8J3pNGxoaR3Z0IBG9Csm/Is=", + "h1:kQMkcPVvHOguOqnxoEU2sm1ND9vCHiT8TvZ2x6v/Rsw=", + "zh:06fb4e9932f0afc1904d2279e6e99353c2ddac0d765305ce90519af410706bd4", + "zh:104eccfc781fc868da3c7fec4385ad14ed183eb985c96331a1a937ac79c2d1a7", + "zh:129345c82359837bb3f0070ce4891ec232697052f7d5ccf61d43d818912cf5f3", + "zh:3956187ec239f4045975b35e8c30741f701aa494c386aaa04ebabffe7749f81c", + "zh:66a9686d92a6b3ec43de3ca3fde60ef3d89fb76259ed3313ca4eb9bb8c13b7dd", + "zh:88644260090aa621e7e8083585c468c8dd5e09a3c01a432fb05da5c4623af940", + "zh:a248f650d174a883b32c5b94f9e725f4057e623b00f171936dcdcc840fad0b3e", + "zh:aa498c1f1ab93be5c8fbf6d48af51dc6ef0f10b2ea88d67bcb9f02d1d80d3930", + "zh:bf01e0f2ec2468c53596e027d376532a2d30feb72b0b5b810334d043109ae32f", + "zh:c46fa84cc8388e5ca87eb575a534ebcf68819c5a5724142998b487cb11246654", + "zh:d0c0f15ffc115c0965cbfe5c81f18c2e114113e7a1e6829f6bfd879ce5744fbb", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "2.36.0" + constraints = ">= 2.20.0" + hashes = [ + "h1:94wlXkBzfXwyLVuJVhMdzK+VGjFnMjdmFkYhQ1RUFhI=", + "h1:GLR3jKampPSDrt77O+cjTQrcE/EpQIiIA6sreenoon0=", + "h1:vdY0sxo7ahwuz/y7flXTE04tSwn0Zhxyg6n62aTmAHI=", + "zh:07f38fcb7578984a3e2c8cf0397c880f6b3eb2a722a120a08a634a607ea495ca", + "zh:1adde61769c50dbb799d8bf8bfd5c8c504a37017dfd06c7820f82bcf44ca0d39", + "zh:39707f23ab58fd0e686967c0f973c0f5a39c14d6ccfc757f97c345fdd0cd4624", + "zh:4cc3dc2b5d06cc22d1c734f7162b0a8fdc61990ff9efb64e59412d65a7ccc92a", + "zh:8382dcb82ba7303715b5e67939e07dd1c8ecddbe01d12f39b82b2b7d7357e1d9", + "zh:88e8e4f90034186b8bfdea1b8d394621cbc46a064ff2418027e6dba6807d5227", + "zh:a6276a75ad170f76d88263fdb5f9558998bf3a3f7650d7bd3387b396410e59f3", + "zh:bc816c7e0606e5df98a0c7634b240bb0c8100c3107b8b17b554af702edc6a0c5", + "zh:cb2f31d58f37020e840af52755c18afd1f09a833c4903ac59270ab440fab57b7", + "zh:ee0d103b8d0089fb1918311683110b4492a9346f0471b136af46d3b019576b22", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f688b9ec761721e401f6859c19c083e3be20a650426f4747cd359cdc079d212a", + ] +} + +provider "registry.terraform.io/hashicorp/null" { + version = "3.2.4" + constraints = ">= 3.0.0" + hashes = [ + "h1:127ts0CG8hFk1bHIfrBsKxcnt9bAYQCq3udWM+AACH8=", + "h1:L5V05xwp/Gto1leRryuesxjMfgZwjb7oool4WS1UEFQ=", + "h1:hkf5w5B6q8e2A42ND2CjAvgvSN3puAosDmOJb3zCVQM=", + "zh:59f6b52ab4ff35739647f9509ee6d93d7c032985d9f8c6237d1f8a59471bbbe2", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:795c897119ff082133150121d39ff26cb5f89a730a2c8c26f3a9c1abf81a9c43", + "zh:7b9c7b16f118fbc2b05a983817b8ce2f86df125857966ad356353baf4bff5c0a", + "zh:85e33ab43e0e1726e5f97a874b8e24820b6565ff8076523cc2922ba671492991", + "zh:9d32ac3619cfc93eb3c4f423492a8e0f79db05fec58e449dee9b2d5873d5f69f", + "zh:9e15c3c9dd8e0d1e3731841d44c34571b6c97f5b95e8296a45318b94e5287a6e", + "zh:b4c2ab35d1b7696c30b64bf2c0f3a62329107bd1a9121ce70683dec58af19615", + "zh:c43723e8cc65bcdf5e0c92581dcbbdcbdcf18b8d2037406a5f2033b1e22de442", + "zh:ceb5495d9c31bfb299d246ab333f08c7fb0d67a4f82681fbf47f2a21c3e11ab5", + "zh:e171026b3659305c558d9804062762d168f50ba02b88b231d20ec99578a6233f", + "zh:ed0fe2acdb61330b01841fa790be00ec6beaac91d41f311fb8254f74eb6a711f", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.7.2" + constraints = ">= 2.0.0, >= 3.0.0" + hashes = [ + "h1:356j/3XnXEKr9nyicLUufzoF4Yr6hRy481KIxRVpK0c=", + "h1:KG4NuIBl1mRWU0KD/BGfCi1YN/j3F7H4YgeeM7iSdNs=", + "h1:hkKSY5xI4R1H4Yrg10HHbtOoxZif2dXa9HFPSbaVg5o=", + "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", + "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", + "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", + "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", + "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", + "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", + "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", + "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", + "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", + "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", + ] +} + +provider "registry.terraform.io/hashicorp/tls" { + version = "4.1.0" + constraints = ">= 3.1.0, != 4.0.0" + hashes = [ + "h1:Ka8mEwRFXBabR33iN/WTIEW6RP0z13vFsDlwn11Pf2I=", + "h1:uDtqTpFJOseNUlPDx4TT/lXf6ie3CarsimL7sYCiVH4=", + "h1:zEv9tY1KR5vaLSyp2lkrucNJ+Vq3c+sTFK9GyQGLtFs=", + "zh:14c35d89307988c835a7f8e26f1b83ce771e5f9b41e407f86a644c0152089ac2", + "zh:2fb9fe7a8b5afdbd3e903acb6776ef1be3f2e587fb236a8c60f11a9fa165faa8", + "zh:35808142ef850c0c60dd93dc06b95c747720ed2c40c89031781165f0c2baa2fc", + "zh:35b5dc95bc75f0b3b9c5ce54d4d7600c1ebc96fbb8dfca174536e8bf103c8cdc", + "zh:38aa27c6a6c98f1712aa5cc30011884dc4b128b4073a4a27883374bfa3ec9fac", + "zh:51fb247e3a2e88f0047cb97bb9df7c228254a3b3021c5534e4563b4007e6f882", + "zh:62b981ce491e38d892ba6364d1d0cdaadcee37cc218590e07b310b1dfa34be2d", + "zh:bc8e47efc611924a79f947ce072a9ad698f311d4a60d0b4dfff6758c912b7298", + "zh:c149508bd131765d1bc085c75a870abb314ff5a6d7f5ac1035a8892d686b6297", + "zh:d38d40783503d278b63858978d40e07ac48123a2925e1a6b47e62179c046f87a", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fb07f708e3316615f6d218cec198504984c0ce7000b9f1eebff7516e384f4b54", + ] +} diff --git a/examples/basic/README.md b/examples/basic/README.md deleted file mode 100644 index 82535f0..0000000 --- a/examples/basic/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# Basic example - -The code in this example shows how to use the module with basic configuration and minimal set of other resources. - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 4.19.0 | -| [helm](#requirement\_helm) | >= 2.6.0 | -| [kubernetes](#requirement\_kubernetes) | >= 2.11.0 | - -## Modules - -| Name | Source | Version | -|------|--------|---------| -| [addon\_installation\_argo\_helm](#module\_addon\_installation\_argo\_helm) | ../../ | n/a | -| [addon\_installation\_argo\_kubernetes](#module\_addon\_installation\_argo\_kubernetes) | ../../ | n/a | -| [addon\_installation\_disabled](#module\_addon\_installation\_disabled) | ../../ | n/a | -| [addon\_installation\_helm](#module\_addon\_installation\_helm) | ../../ | n/a | -| [eks\_cluster](#module\_eks\_cluster) | cloudposse/eks-cluster/aws | 2.3.0 | -| [eks\_node\_group](#module\_eks\_node\_group) | cloudposse/eks-node-group/aws | 2.4.0 | -| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | 4.0.0 | - -## Resources - -| Name | Type | -|------|------| -| [aws_eks_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster) | data source | -| [aws_eks_cluster_auth.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster_auth) | data source | - -## Inputs - -No inputs. - -## Outputs - -No outputs. - diff --git a/examples/basic/base.tf b/examples/basic/base.tf index fbb9f33..ac7d8f6 100644 --- a/examples/basic/base.tf +++ b/examples/basic/base.tf @@ -1,27 +1,39 @@ module "vpc" { source = "terraform-aws-modules/vpc/aws" - version = "4.0.0" + version = "5.21.0" - name = "cluster-autoscaler-vpc" - cidr = "10.0.0.0/16" - azs = ["eu-central-1a", "eu-central-1b"] - public_subnets = ["10.0.101.0/24", "10.0.102.0/24"] - enable_nat_gateway = true + name = "vpc" + cidr = "10.0.0.0/16" + azs = ["eu-central-1a", "eu-central-1b"] + private_subnets = ["10.0.1.0/24", "10.0.2.0/24"] + public_subnets = ["10.0.101.0/24", "10.0.102.0/24"] + enable_nat_gateway = true + map_public_ip_on_launch = true } module "eks_cluster" { source = "cloudposse/eks-cluster/aws" - version = "2.3.0" + version = "4.6.0" - region = "eu-central-1" + kubernetes_version = "1.31" + oidc_provider_enabled = true + + access_entry_map = { + (data.aws_iam_session_context.current.issuer_arn) = { + access_policy_associations = { + ClusterAdmin = {} + } + } + } + + name = "eks" + region = data.aws_region.this.name subnet_ids = module.vpc.public_subnets - vpc_id = module.vpc.vpc_id - name = "basic-example" } module "eks_node_group" { source = "cloudposse/eks-node-group/aws" - version = "2.4.0" + version = "3.3.0" cluster_name = module.eks_cluster.eks_cluster_id instance_types = ["t3.medium"] diff --git a/examples/basic/main.tf b/examples/basic/main.tf index 3577d99..d53ab5e 100644 --- a/examples/basic/main.tf +++ b/examples/basic/main.tf @@ -38,12 +38,11 @@ module "addon_installation_argo_kubernetes" { }) argo_sync_policy = { - "automated" : {} - "syncOptions" = ["CreateNamespace=true"] + automated = {} + syncOptions = ["CreateNamespace=true"] } } - module "addon_installation_argo_helm" { source = "../../" @@ -54,8 +53,12 @@ module "addon_installation_argo_helm" { cluster_identity_oidc_issuer = module.eks_cluster.eks_cluster_identity_oidc_issuer cluster_identity_oidc_issuer_arn = module.eks_cluster.eks_cluster_identity_oidc_issuer_arn + values = yamlencode({ + # insert sample values here + }) + argo_sync_policy = { - "automated" : {} - "syncOptions" = ["CreateNamespace=true"] + automated = {} + syncOptions = ["CreateNamespace=true"] } } diff --git a/examples/basic/providers.tf b/examples/basic/providers.tf index f18aaaa..25459bc 100644 --- a/examples/basic/providers.tf +++ b/examples/basic/providers.tf @@ -1,5 +1,9 @@ -provider "aws" { - region = "eu-central-1" +data "aws_region" "this" {} + +data "aws_caller_identity" "current" {} + +data "aws_iam_session_context" "current" { + arn = data.aws_caller_identity.current.arn } data "aws_eks_cluster" "this" { @@ -10,6 +14,10 @@ data "aws_eks_cluster_auth" "this" { name = module.eks_cluster.eks_cluster_id } +provider "aws" { + region = "eu-central-1" +} + provider "kubernetes" { host = data.aws_eks_cluster.this.endpoint token = data.aws_eks_cluster_auth.this.token diff --git a/examples/basic/versions.tf b/examples/basic/versions.tf index 3d58332..ccd47b8 100644 --- a/examples/basic/versions.tf +++ b/examples/basic/versions.tf @@ -1,14 +1,14 @@ terraform { - required_version = ">= 1.0" + required_version = ">= 1.5.0" required_providers { aws = { source = "hashicorp/aws" - version = ">= 4.19.0" + version = "~> 5" } kubernetes = { source = "hashicorp/kubernetes" - version = ">= 2.11.0" + version = ">= 2.20.0" } helm = { source = "hashicorp/helm" diff --git a/helm.tf b/helm.tf deleted file mode 100644 index 62dd11c..0000000 --- a/helm.tf +++ /dev/null @@ -1,68 +0,0 @@ -resource "helm_release" "this" { - count = var.enabled && !var.argo_enabled ? 1 : 0 - chart = var.helm_chart_name - create_namespace = var.helm_create_namespace - namespace = var.namespace - name = local.helm_release_name - version = var.helm_chart_version - repository = var.helm_repo_url - - repository_key_file = var.helm_repo_key_file - repository_cert_file = var.helm_repo_cert_file - repository_ca_file = var.helm_repo_ca_file - repository_username = var.helm_repo_username - repository_password = var.helm_repo_password - devel = var.helm_devel - verify = var.helm_package_verify - keyring = var.helm_keyring - timeout = var.helm_timeout - disable_webhooks = var.helm_disable_webhooks - reset_values = var.helm_reset_values - reuse_values = var.helm_reuse_values - force_update = var.helm_force_update - recreate_pods = var.helm_recreate_pods - cleanup_on_fail = var.helm_cleanup_on_fail - max_history = var.helm_release_max_history - atomic = var.helm_atomic - wait = var.helm_wait - wait_for_jobs = var.helm_wait_for_jobs - skip_crds = var.helm_skip_crds - render_subchart_notes = var.helm_render_subchart_notes - disable_openapi_validation = var.helm_disable_openapi_validation - dependency_update = var.helm_dependency_update - replace = var.helm_replace - description = var.helm_description - lint = var.helm_lint - - values = [ - data.utils_deep_merge_yaml.values[0].output, - jsonencode({ serviceAccount : { name : local.helm_release_name } }), - ] - - dynamic "set" { - for_each = var.settings - content { - name = set.key - value = set.value - } - } - - dynamic "set_sensitive" { - for_each = var.helm_set_sensitive - content { - name = set_sensitive.key - value = set_sensitive.value - } - } - - dynamic "postrender" { - for_each = var.helm_postrender - content { - binary_path = postrender.value - } - } - - lifecycle { - create_before_destroy = true - } -} diff --git a/helm/argocd-application/.helmignore b/helm/argocd-application/.helmignore deleted file mode 100644 index 0e8a0eb..0000000 --- a/helm/argocd-application/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*.orig -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ diff --git a/helm/argocd-application/Chart.yaml b/helm/argocd-application/Chart.yaml deleted file mode 100644 index b450f61..0000000 --- a/helm/argocd-application/Chart.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: v2 -name: argocd-application -description: Helm wrapper for deploying ArgoCD application object - -# A chart can be either an 'application' or a 'library' chart. -# -# Application charts are a collection of templates that can be packaged into versioned archives -# to be deployed. -# -# Library charts provide useful utilities or functions for the chart developer. They're included as -# a dependency of application charts to inject those utilities and functions into the rendering -# pipeline. Library charts do not define any templates and therefore cannot be deployed. -type: application - -# This is the chart version. This version number should be incremented each time you make changes -# to the chart and its templates, including the app version. -# Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 diff --git a/helm/argocd-application/templates/_helpers.tpl b/helm/argocd-application/templates/_helpers.tpl deleted file mode 100644 index 6dac3de..0000000 --- a/helm/argocd-application/templates/_helpers.tpl +++ /dev/null @@ -1,51 +0,0 @@ -{{/* -Expand the name of the chart. -*/}} -{{- define "argocd_application.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "argocd_application.fullname" -}} -{{- if .Values.fullnameOverride }} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- $name := default .Chart.Name .Values.nameOverride }} -{{- if contains $name .Release.Name }} -{{- .Release.Name | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- printf "%s" .Release.Name | trunc 63 | trimSuffix "-" }} -{{- end }} -{{- end }} -{{- end }} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "argocd_application.chart" -}} -{{- printf "%s" .Chart.Name | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "argocd_application.labels" -}} -helm.sh/chart: {{ include "argocd_application.chart" . }} -{{ include "argocd_application.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "argocd_application.selectorLabels" -}} -app.kubernetes.io/name: {{ include "argocd_application.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} diff --git a/helm/argocd-application/templates/application.yaml b/helm/argocd-application/templates/application.yaml deleted file mode 100644 index 3117c37..0000000 --- a/helm/argocd-application/templates/application.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: {{ .Values.apiVersion }} -kind: Application -metadata: - name: {{ include "argocd_application.fullname" . }} - labels: - {{- include "argocd_application.labels" . | nindent 4 }} - {{- if .Values.labels }} - {{ toYaml .Values.labels | nindent 4 }} - {{- end }} - annotations: - {{- if .Values.annotations }} - {{ toYaml .Values.annotations | indent 4 }} - {{- end }} - finalizers: - {{- if .Values.finalizers }} - {{ toYaml .Values.finalizers | indent 4 }} - {{- end }} -spec: - {{ toYaml .Values.spec | nindent 2 }} diff --git a/helm/argocd-application/values.yaml b/helm/argocd-application/values.yaml deleted file mode 100644 index 552d6da..0000000 --- a/helm/argocd-application/values.yaml +++ /dev/null @@ -1,2 +0,0 @@ -nameOverride: "" -fullnameOverride: "" diff --git a/iam.tf b/iam.tf deleted file mode 100644 index 634c022..0000000 --- a/iam.tf +++ /dev/null @@ -1,99 +0,0 @@ -locals { - irsa_role_create = var.enabled && var.rbac_create && var.service_account_create && var.irsa_role_create -} - -data "aws_iam_policy_document" "this" { - count = local.irsa_role_create && var.irsa_policy_enabled && !var.irsa_assume_role_enabled ? 1 : 0 - - # Example statement (modify it before using this module) - statement { - sid = "Autoscaling" - - actions = [ - "autoscaling:DescribeAutoScalingGroups", - "autoscaling:DescribeAutoScalingInstances", - "autoscaling:DescribeLaunchConfigurations", - "autoscaling:DescribeTags", - "autoscaling:SetDesiredCapacity", - "autoscaling:TerminateInstanceInAutoScalingGroup", - "ec2:DescribeLaunchTemplateVersions", - "ec2:DescribeInstanceTypes" - ] # checkov:skip=CKV_AWS_111 - - resources = [ - "*", - ] - - effect = "Allow" - } -} - -data "aws_iam_policy_document" "this_assume" { - count = local.irsa_role_create && var.irsa_assume_role_enabled ? 1 : 0 - - statement { - sid = "AllowAssume<$addon-name>Role" - effect = "Allow" - actions = [ - "sts:AssumeRole" - ] - resources = [ - var.irsa_assume_role_arn - ] - } -} - -resource "aws_iam_policy" "this" { - count = local.irsa_role_create && (var.irsa_policy_enabled || var.irsa_assume_role_enabled) ? 1 : 0 - - name = "${var.irsa_role_name_prefix}-${var.helm_chart_name}" - path = "/" - description = "Policy for <$addon-name> service" - policy = var.irsa_assume_role_enabled ? data.aws_iam_policy_document.this_assume[0].json : data.aws_iam_policy_document.this[0].json - - tags = var.irsa_tags -} - -data "aws_iam_policy_document" "this_irsa" { - count = local.irsa_role_create ? 1 : 0 - - statement { - actions = ["sts:AssumeRoleWithWebIdentity"] - - principals { - type = "Federated" - identifiers = [var.cluster_identity_oidc_issuer_arn] - } - - condition { - test = "StringEquals" - variable = "${replace(var.cluster_identity_oidc_issuer, "https://", "")}:sub" - - values = [ - "system:serviceaccount:${var.namespace}:${var.service_account_name}", - ] - } - - effect = "Allow" - } -} - -resource "aws_iam_role" "this" { - count = local.irsa_role_create ? 1 : 0 - name = "${var.irsa_role_name_prefix}-${var.helm_chart_name}" - assume_role_policy = data.aws_iam_policy_document.this_irsa[0].json - tags = var.irsa_tags -} - -resource "aws_iam_role_policy_attachment" "this" { - count = local.irsa_role_create && var.irsa_policy_enabled ? 1 : 0 - role = aws_iam_role.this[0].name - policy_arn = aws_iam_policy.this[0].arn -} - -resource "aws_iam_role_policy_attachment" "this_additional" { - for_each = local.irsa_role_create ? var.irsa_additional_policies : {} - - role = aws_iam_role.this[0].name - policy_arn = each.value -} diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..f0bca69 --- /dev/null +++ b/main.tf @@ -0,0 +1,31 @@ +/** + * # AWS EKS Node Local DNS Terraform module + * + * A Terraform module to deploy the [Node Local DNS](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/) on Amazon EKS cluster. The upgrade process of this module is using the `create before destroy` feature, and the already running DaemonSet will be terminated after the new one is already running. + * + * [![Terraform validate](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/validate.yaml/badge.svg)](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/validate.yaml) + * [![pre-commit](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/pre-commit.yml) + */ +locals { + addon = { + name = "node-local-dns" + namespace = "kube-system" + + helm_chart_version = "2.2.0" + helm_repo_url = "https://lablabs.github.io/k8s-nodelocaldns-helm" + } + + addon_irsa = { + (local.addon.name) = {} + } + + addon_values = yamlencode({ + serviceAccount = { + create = module.addon-irsa[local.addon.name].service_account_create + name = module.addon-irsa[local.addon.name].service_account_name + annotations = module.addon-irsa[local.addon.name].irsa_role_enabled ? { + "eks.amazonaws.com/role-arn" = module.addon-irsa[local.addon.name].iam_role_attributes.arn + } : tomap({}) + } + }) +} diff --git a/migrations.tf b/migrations.tf new file mode 100644 index 0000000..d471008 --- /dev/null +++ b/migrations.tf @@ -0,0 +1,24 @@ +moved { + from = kubernetes_manifest.this + to = module.addon.kubernetes_manifest.this +} + +moved { + from = helm_release.this + to = module.addon.helm_release.this +} + +moved { + from = helm_release.argo_application + to = module.addon.helm_release.argo_application +} + +moved { + from = aws_iam_role.this + to = module.addon-irsa["node-local-dns"].aws_iam_role.this +} + +moved { + from = aws_iam_role_policy_attachment.this_additional + to = module.addon-irsa["node-local-dns"].aws_iam_role_policy_attachment.this_additional +} diff --git a/outputs.tf b/outputs.tf deleted file mode 100644 index 9a231e6..0000000 --- a/outputs.tf +++ /dev/null @@ -1,19 +0,0 @@ -output "helm_release_metadata" { - description = "Helm release attributes" - value = try(helm_release.this[0].metadata, {}) -} - -output "helm_release_application_metadata" { - description = "Argo application helm release attributes" - value = try(helm_release.argo_application[0].metadata, {}) -} - -output "kubernetes_application_attributes" { - description = "Argo kubernetes manifest attributes" - value = try(kubernetes_manifest.this[0], {}) -} - -output "iam_role_attributes" { - description = "<$addon-name> IAM role atributes" - value = try(aws_iam_role.this[0], {}) -} diff --git a/requirements.txt b/requirements.txt index 41a7bea..fb17f43 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ -checkov==2.2.158 +python-hcl2==5.1.1 +Jinja2==3.1.6 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/values.tf b/values.tf deleted file mode 100644 index ab48e40..0000000 --- a/values.tf +++ /dev/null @@ -1,162 +0,0 @@ -locals { - values_default = yamlencode({ - "config" : { - "localDnsIp" : "169.254.20.11", - "zones" : { - ".:53" : { - "plugins" : { - "errors" : true, - "reload" : true, - "debug" : false, - "log" : { - "format" : "combined", - "classes" : "all" - }, - "cache" : { - "parameters" : 30, - "denial" : { - size : 0, - ttl : 1 - }, - "success" : {}, - "prefetch" : {}, - "serve_stale" : false - }, - "forward" : { - "parameters" : "172.20.0.10", - "force_tcp" : true, - "prefer_udp" : false, - "policy" : "", - "max_fails" : "", - "expire" : "", - "health_check" : "", - "except" : "" - }, - "prometheus" : true, - "health" : { - "port" : 8080 - } - } - }, - "ip6.arpa:53" : { - "plugins" : { - "errors" : true, - "reload" : true, - "debug" : false, - "log" : { - "classes" : "error" - }, - "cache" : { - "parameters" : 30 - }, - "forward" : { - "parameters" : "172.20.0.10", - "force_tcp" : true - }, - "prometheus" : true, - "health" : { - "port" : 8081 - } - } - }, - "in-addr.arpa:53" : { - "plugins" : { - "errors" : true, - "reload" : true, - "debug" : false, - "log" : { - "classes" : "error" - }, - "cache" : { - "parameters" : 30 - }, - "forward" : { - "parameters" : "172.20.0.10", - "force_tcp" : true - }, - "prometheus" : true, - "health" : { - "port" : 8082 - } - } - } - } - }, - "useHostNetwork" : true, - "priorityClassName" : "system-node-critical", - "podAnnotations" : {}, - "podSecurityContext" : {}, - "securityContext" : { - "privileged" : true - }, - "readinessProbe" : null, - "serviceAccount" : { - "create" : true, - "annotations" : { - "eks.amazonaws.com/role-arn" : "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${aws_iam_role.this[0].name}" - }, - "name" : var.service_account_name - }, - "affinity" : {}, - "tolerations" : [ - { - "key" : "CriticalAddonsOnly", - "operator" : "Exists" - }, - { - "effect" : "NoExecute", - "operator" : "Exists" - }, - { - "effect" : "NoSchedule", - "operator" : "Exists" - } - ], - "resources" : { - "requests" : { - "cpu" : "70m", - "memory" : "100Mi" - } - }, - }) - - metrics_port = yamlencode({ - "metrics" : { - "prometheusScrape" : "true", - "port" : random_integer.metrics_port[0].result - } - }) - - helm_release_name = "${var.helm_release_name}-${one(random_pet.release_name_suffix[*].id)}" - -} - -resource "random_integer" "metrics_port" { - count = var.enabled ? 1 : 0 - - min = 1025 - max = 32667 - - keepers = { - values = random_pet.release_name_suffix[count.index].id - } -} - -resource "random_pet" "release_name_suffix" { - count = var.enabled ? 1 : 0 - keepers = { - var_values = jsonencode(var.values), - default_values = jsonencode(local.values_default) - } -} - -data "aws_caller_identity" "current" {} - -data "utils_deep_merge_yaml" "values" { - count = var.enabled ? 1 : 0 - input = compact([ - local.values_default, - var.values, - local.metrics_port - ]) -} diff --git a/variables-addon-irsa.tf b/variables-addon-irsa.tf new file mode 100644 index 0000000..89cae66 --- /dev/null +++ b/variables-addon-irsa.tf @@ -0,0 +1,163 @@ +# 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. + +variable "cluster_identity_oidc_issuer" { + type = string + default = null + description = "The OIDC Identity issuer for the cluster (required for IRSA). Defaults to `\"\"`." +} + +variable "cluster_identity_oidc_issuer_arn" { + type = string + default = null + description = "The OIDC Identity issuer ARN for the cluster that can be used to associate IAM roles with a Service Account (required for IRSA). Defaults to `\"\"`." +} + +variable "rbac_create" { + type = bool + default = null + description = "Whether to create and use RBAC resources. Defaults to `true`." +} + +variable "service_account_create" { + type = bool + default = null + description = "Whether to create Service Account. Defaults to `true`." +} + +variable "service_account_name" { + type = string + default = null + description = "The Kubernetes Service Account name. Defaults to `\"\"`." +} + +variable "service_account_namespace" { + type = string + default = null + description = "The Kubernetes Service Account namespace. Defaults to `\"\"`." +} + +variable "irsa_role_create" { + type = bool + default = null + description = "Whether to create IRSA role and annotate Service Account. Defaults to `true`." +} + +variable "irsa_role_name_prefix" { + type = string + default = null + 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 `irsa_role_name_prefix`. Either `irsa_role_name` or `irsa_role_name_prefix` must be set. Defaults to `\"\"`." +} + +variable "irsa_policy_enabled" { + type = bool + default = null + description = "Whether to create IAM policy specified by `irsa_policy`. Mutually exclusive with `irsa_assume_role_enabled`. Defaults to `false`." +} + +variable "irsa_policy" { + type = string + default = null + 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" { + type = bool + default = null + description = "Whether IRSA is allowed to assume role defined by `irsa_assume_role_arn`. Mutually exclusive with `irsa_policy_enabled`. Defaults to `false`." +} + +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`. 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 `null`." +} + +variable "irsa_additional_policies" { + type = map(string) + default = null + description = "Map of the additional policies to be attached to IRSA role. Where key is arbitrary id and value is policy ARN. Defaults to `{}`." +} + +variable "irsa_tags" { + type = map(string) + 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 `[]`." +} + +variable "cluster_name" { + type = string + default = null + description = "The name of the cluster (required for pod identity). Defaults to `\"\"`." +} + +variable "pod_identity_role_create" { + type = bool + default = null + description = "Whether to create pod identity role and annotate Service Account. Defaults to `false`." +} + +variable "pod_identity_role_name_prefix" { + type = string + default = null + description = "Pod identity role name prefix. Either `pod_identity_role_name_prefix` or `pod_identity_role_name` must be set. Defaults to `\"\"`." +} + +variable "pod_identity_role_name" { + type = string + default = null + description = "Pod identity role name. The value is prefixed by `pod_identity_role_name_prefix`. Either `pod_identity_role_name` or `pod_identity_role_name_prefix` must be set. Defaults to `\"\"`." +} + +variable "pod_identity_policy_enabled" { + type = bool + default = null + description = "Whether to create IAM policy specified by `pod_identity_policy`. Defaults to `false`." +} + +variable "pod_identity_policy" { + type = string + default = null + description = "AWS IAM policy JSON document to be attached to the pod identity role. Applied only if `pod_identity_policy_enabled` is `true`. Defaults to `\"\"`." +} + +variable "pod_identity_permissions_boundary" { + type = string + default = null + description = "ARN of the policy that is used to set the permissions boundary for the pod identity role. Defaults to `null`." +} + +variable "pod_identity_additional_policies" { + type = map(string) + default = null + description = "Map of the additional policies to be attached to pod identity role. Where key is arbitrary id and value is policy ARN. Defaults to `{}`." +} + +variable "pod_identity_tags" { + type = map(string) + default = null + description = "Pod identity resources tags. Defaults to `{}`." +} diff --git a/variables-addon.tf b/variables-addon.tf new file mode 100644 index 0000000..a5ebced --- /dev/null +++ b/variables-addon.tf @@ -0,0 +1,385 @@ +# 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. + +variable "helm_enabled" { + type = bool + default = null + description = "Set to false to prevent installation of the module via Helm release. Defaults to `true`." +} + +variable "helm_chart_name" { + type = string + default = null + description = "Helm chart name to be installed. Required if `argo_source_type` is set to `helm`. Defaults to `\"\"`." +} + +variable "helm_chart_version" { + type = string + default = null + description = "Version of the Helm chart. Required if `argo_source_type` is set to `helm`. Defaults to `\"\"`." +} + +variable "helm_release_name" { + type = string + default = null + description = "Helm release name. Required if `argo_source_type` is set to `helm`. Defaults to `\"\"`." +} + +variable "helm_repo_url" { + type = string + default = null + description = "Helm repository. Required if `argo_source_type` is set to `helm`. Defaults to `\"\"`." +} + +variable "helm_create_namespace" { + type = bool + default = null + 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 (required)." +} + +variable "settings" { + type = map(any) + default = null + description = "Additional Helm sets which will be passed to the Helm chart values or Kustomize or directory configuration which will be passed to ArgoCD Application source. Defaults to `{}`." +} + +variable "values" { + type = string + default = null + description = "Additional YAML encoded values which will be passed to the Helm chart. Defaults to `\"\"`." +} + +variable "argo_name" { + type = string + default = null + description = "Name of the ArgoCD Application. Required if `argo_source_type` is set to `kustomize` or `directory`. If `argo_source_type` is set to `helm`, ArgoCD Application name will equal `helm_release_name`. Defaults to `\"\"`." +} + +variable "argo_namespace" { + type = string + default = null + description = "Namespace to deploy ArgoCD Application 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`." +} + +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`." +} + +variable "argo_helm_wait_timeout" { + type = string + default = null + description = "Timeout for ArgoCD Application Helm release wait job. Defaults to `10m`." +} + +variable "argo_helm_wait_node_selector" { + type = map(string) + default = null + description = "Node selector for ArgoCD Application Helm release wait job. Defaults to `{}`." +} + +variable "argo_helm_wait_tolerations" { + type = list(any) + default = null + description = "Tolerations for ArgoCD Application Helm release wait job. Defaults to `[]`." +} + +variable "argo_helm_wait_backoff_limit" { + type = number + default = null + description = "Backoff limit for ArgoCD Application Helm release wait job. Defaults to `6`." +} + +variable "argo_helm_wait_kubectl_version" { + type = string + default = null + description = "Version of kubectl to use for ArgoCD Application wait job. Defaults to `1.33.0`." +} + +variable "argo_source_type" { + type = string + default = null + description = "Source type for ArgoCD Application. Can be either `helm`, `kustomize`, or `directory`. Defaults to `helm`." +} + +variable "argo_source_repo_url" { + type = string + default = null + description = "ArgoCD Application source repo URL. Required if `argo_source_type` is set to `kustomize` or `directory`. Defaults to `\"\"`." +} + +variable "argo_source_target_revision" { + type = string + default = null + description = "ArgoCD Application source target revision. Required if `argo_source_type` is set to `kustomize` or `directory`. Defaults to `\"\"`." +} + +variable "argo_source_path" { + type = string + default = null + description = "ArgoCD Application source path. Required if `argo_source_type` is set to `kustomize` or `directory`. Defaults to `\"\"`." +} + +variable "argo_destination_server" { + type = string + default = null + description = "Destination server for ArgoCD Application. Defaults to `https://kubernetes.default.svc`." +} + +variable "argo_project" { + type = string + default = null + description = "ArgoCD Application project. Defaults to `default`." +} + +variable "argo_info" { + type = list(any) + default = null + description = "ArgoCD Application manifest info parameter. Defaults to `[{\"name\": \"terraform\", \"value\": \"true\"}]`." +} + +variable "argo_sync_policy" { + type = any + default = null + 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\"]}`." +} + +variable "argo_apiversion" { + type = string + default = null + description = "ArgoCD Application apiVersion. Defaults to `argoproj.io/v1alpha1`." +} + +variable "argo_spec" { + type = any + default = null + description = "ArgoCD Application spec configuration. Configuration is extended by deep merging with the default spec parameters. Defaults to `{}`." +} + +variable "argo_spec_override" { + type = any + default = null + description = "ArgoCD Application spec configuration. Configuration is overriden by merging natively with the default spec parameters. Defaults to `{}`." +} + +variable "argo_operation" { + type = any + default = null + description = "ArgoCD Application manifest operation parameter. Defaults to `{}`." +} + +variable "argo_helm_values" { + type = string + default = null + description = "Value overrides to use when deploying ArgoCD Application object with Helm. Defaults to `\"\"`." +} + +variable "argo_kubernetes_manifest_computed_fields" { + type = list(string) + default = null + description = "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\"]`." +} + +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`." +} + +variable "argo_kubernetes_manifest_field_manager_force_conflicts" { + type = bool + default = null + description = "Forcibly override any field manager conflicts when applying the kubernetes manifest resource. Defaults to `false`." +} + +variable "argo_kubernetes_manifest_wait_fields" { + type = map(string) + default = null + 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 `{}`." +} + +variable "helm_repo_key_file" { + type = string + default = null + description = "Helm repositories cert key file. Defaults to `\"\"`." +} + +variable "helm_repo_cert_file" { + type = string + default = null + description = "Helm repositories cert file. Defaults to `\"\"`." +} + +variable "helm_repo_ca_file" { + type = string + default = null + description = "Helm repositories CA cert file. Defaults to `\"\"`." +} + +variable "helm_repo_username" { + type = string + default = null + description = "Username for HTTP basic authentication against the Helm repository. Defaults to `\"\"`." +} + +variable "helm_repo_password" { + type = string + default = null + description = "Password for HTTP basic authentication against the Helm repository. Defaults to `\"\"`." +} + +variable "helm_devel" { + type = bool + default = null + description = "Use Helm chart development versions, too. Equivalent to version '>0.0.0-0'. If version is set, this is ignored. Defaults to `false`." +} + +variable "helm_package_verify" { + type = bool + default = null + description = "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`." +} + +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`." +} + +variable "helm_timeout" { + type = number + default = null + description = "Time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks). Defaults to `300`." +} + +variable "helm_disable_webhooks" { + type = bool + default = null + description = "Prevent Helm chart hooks from running. Defaults to `false`." +} + +variable "helm_reset_values" { + type = bool + default = null + description = "When upgrading, reset the values to the ones built into the Helm chart. Defaults to `false`." +} + +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`." +} + +variable "helm_force_update" { + type = bool + default = null + description = "Force Helm resource update through delete/recreate if needed. Defaults to `false`." +} + +variable "helm_recreate_pods" { + type = bool + default = null + description = "Perform pods restart during Helm upgrade/rollback. Defaults to `false`." +} + +variable "helm_cleanup_on_fail" { + type = bool + default = null + description = "Allow deletion of new resources created in this Helm upgrade when upgrade fails. Defaults to `false`." +} + +variable "helm_release_max_history" { + type = number + default = null + description = "Maximum number of release versions stored per release. Defaults to `0`." +} + +variable "helm_atomic" { + type = bool + default = null + description = "If set, installation process purges chart on fail. The wait flag will be set automatically if atomic is used. Defaults to `false`." +} + +variable "helm_wait" { + type = bool + default = null + description = "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`." +} + +variable "helm_wait_for_jobs" { + type = bool + default = null + description = "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`." +} + +variable "helm_skip_crds" { + type = bool + default = null + description = "If set, no CRDs will be installed before Helm release. Defaults to `false`." +} + +variable "helm_render_subchart_notes" { + type = bool + default = null + description = "If set, render Helm subchart notes along with the parent. Defaults to `true`." +} + +variable "helm_disable_openapi_validation" { + type = bool + default = null + description = "If set, the installation process will not validate rendered Helm templates against the Kubernetes OpenAPI Schema. Defaults to `false`." +} + +variable "helm_dependency_update" { + type = bool + default = null + description = "Runs Helm dependency update before installing the chart. Defaults to `false`." +} + +variable "helm_replace" { + type = bool + default = null + description = "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`." +} + +variable "helm_description" { + type = string + default = null + description = "Set Helm release description attribute (visible in the history). Defaults to `\"\"`." +} + +variable "helm_lint" { + type = bool + default = null + description = "Run the Helm chart linter during the plan. Defaults to `false`." +} + +variable "helm_set_sensitive" { + type = map(any) + default = null + description = "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 `{}`." +} + +variable "helm_postrender" { + type = map(any) + default = null + description = "Value block with a path to a binary file to run after Helm renders the manifest which can alter the manifest contents. Defaults to `{}`." +} diff --git a/variables.tf b/variables.tf index 1395bc6..27b64d8 100644 --- a/variables.tf +++ b/variables.tf @@ -1,429 +1,7 @@ +# IMPORTANT: Add addon specific variables here variable "enabled" { type = bool default = true - description = "Variable indicating whether deployment is enabled" -} - -variable "cluster_identity_oidc_issuer" { - type = string - description = "The OIDC Identity issuer for the cluster" -} - -variable "cluster_identity_oidc_issuer_arn" { - type = string - description = "The OIDC Identity issuer ARN for the cluster that can be used to associate IAM roles with a service account" -} - -# ================ common variables (required) ================ - -variable "helm_chart_name" { - type = string - default = "node-local-dns" - description = "Helm chart name to be installed" -} - -variable "helm_chart_version" { - type = string - default = "1.4.0" - description = "Version of the Helm chart" -} - -variable "helm_release_name" { - type = string - default = "node-local-dns" - description = "Helm release name" -} - -variable "helm_repo_url" { - type = string - default = "https://lablabs.github.io/k8s-nodelocaldns-helm/" - description = "Helm repository" -} - -variable "helm_create_namespace" { - type = bool - default = true - description = "Create the namespace if it does not yet exist" -} - -variable "namespace" { - type = string - default = "kube-system" - description = "The K8s namespace in which the kube-system service account has been created" -} - -variable "settings" { - type = map(any) - default = {} - description = "Additional helm sets which will be passed to the Helm chart values, see https://github.com/lablabs/k8s-nodelocaldns-helm/tree/master/charts/node-local-dns" -} - -variable "values" { - type = string - default = "" - description = "Additional yaml encoded values which will be passed to the Helm chart, see https://github.com/lablabs/k8s-nodelocaldns-helm/tree/master/charts/node-local-dns" -} - -# ================ IRSA variables (optional) ================ - -variable "rbac_create" { - type = bool - default = true - description = "Whether to create and use RBAC resources" -} - -variable "service_account_create" { - type = bool - default = true - description = "Whether to create Service Account" -} - -variable "service_account_name" { - type = string - default = "node-local-dns" - description = "The k8s node-local-dns service account name" -} - -variable "irsa_role_create" { - type = bool - default = true - description = "Whether to create IRSA role and annotate service account" -} - -variable "irsa_policy_enabled" { - type = bool - default = true - description = "Whether to create opinionated policy to allow operations on specified zones in `policy_allowed_zone_ids`." -} - -variable "irsa_assume_role_enabled" { - type = bool - default = false - description = "Whether IRSA is allowed to assume role defined by irsa_assume_role_arn." -} - -variable "irsa_assume_role_arn" { - type = string - default = "" - description = "Assume role arn. Assume role must be enabled." -} - -variable "irsa_additional_policies" { - type = map(string) - default = {} - description = "Map of the additional policies to be attached to default role. Where key is arbitrary id and value is policy arn." -} - -variable "irsa_role_name_prefix" { - type = string - default = "node-local-dns-irsa" - description = "The IRSA role name prefix for node-local-dns" -} - -variable "irsa_tags" { - type = map(string) - default = {} - description = "IRSA resources tags" -} - -# ================ argo variables (required) ================ - -variable "argo_namespace" { - type = string - default = "argo" - description = "Namespace to deploy ArgoCD application CRD to" -} - -variable "argo_enabled" { - type = bool - default = false - description = "If set to true, the module will be deployed as ArgoCD application, otherwise it will be deployed as a Helm release" -} - -variable "argo_helm_enabled" { - type = bool - default = 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" -} - -variable "argo_helm_wait_timeout" { - type = string - default = "10m" - description = "Timeout for ArgoCD Application Helm release wait job" -} - -variable "argo_helm_wait_node_selector" { - type = map(string) - default = {} - description = "Node selector for ArgoCD Application Helm release wait job" -} - -variable "argo_helm_wait_tolerations" { - type = list(any) - default = [] - description = "Tolerations for ArgoCD Application Helm release wait job" -} - -variable "argo_helm_wait_backoff_limit" { - type = number - default = 6 - description = "Backoff limit for ArgoCD Application Helm release wait job" -} - -variable "argo_destination_server" { - type = string - default = "https://kubernetes.default.svc" - description = "Destination server for ArgoCD Application" -} - -variable "argo_project" { - type = string - default = "default" - description = "ArgoCD Application project" -} - -variable "argo_info" { - type = list(object({ - name = string - value = string - })) - default = [{ - "name" = "terraform" - "value" = "true" - }] - description = "ArgoCD info manifest parameter" -} - -variable "argo_sync_policy" { - type = any - description = "ArgoCD syncPolicy manifest parameter" - default = {} -} - -variable "argo_metadata" { - type = any - default = { - "finalizers" : [ - "resources-finalizer.argocd.argoproj.io" - ] - } - description = "ArgoCD Application metadata configuration. Override or create additional metadata parameters" -} - -variable "argo_apiversion" { - type = string - default = "argoproj.io/v1alpha1" - description = "ArgoCD Appliction apiVersion" -} - -variable "argo_spec" { - type = any - default = {} - description = "ArgoCD Application spec configuration. Override or create additional spec parameters" -} - -variable "argo_helm_values" { - type = string - default = "" - description = "Value overrides to use when deploying argo application object with helm" -} - -# ================ argo kubernetes manifest variables (required) ================ - -variable "argo_kubernetes_manifest_computed_fields" { - type = list(string) - default = ["metadata.labels", "metadata.annotations", "metadata.finalizers"] - description = "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." -} - -variable "argo_kubernetes_manifest_field_manager_name" { - type = string - default = "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" { - type = bool - default = false - description = "Forcibly override any field manager conflicts when applying the kubernetes manifest resource" -} - -variable "argo_kubernetes_manifest_wait_fields" { - type = map(string) - default = { - "status.sync.status" = "Synced" - "status.health.status" = "Healthy" - "status.operationState.phase" = "Succeeded" - } - 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." -} - -# ================ helm release variables (required) ================ - -variable "helm_repo_key_file" { - type = string - default = "" - description = "Helm repositories cert key file" -} - -variable "helm_repo_cert_file" { - type = string - default = "" - description = "Helm repositories cert file" -} - -variable "helm_repo_ca_file" { - type = string - default = "" - description = "Helm repositories cert file" -} - -variable "helm_repo_username" { - type = string - default = "" - description = "Username for HTTP basic authentication against the helm repository" -} - -variable "helm_repo_password" { - type = string - default = "" - description = "Password for HTTP basic authentication against the helm repository" -} - -variable "helm_devel" { - type = bool - default = false - description = "Use helm chart development versions, too. Equivalent to version '>0.0.0-0'. If version is set, this is ignored" -} - -variable "helm_package_verify" { - type = bool - default = false - description = "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" -} - -variable "helm_keyring" { - type = string - default = "~/.gnupg/pubring.gpg" - description = "Location of public keys used for verification. Used only if helm_package_verify is true" -} - -variable "helm_timeout" { - type = number - default = 300 - description = "Time in seconds to wait for any individual kubernetes operation (like Jobs for hooks)" -} - -variable "helm_disable_webhooks" { - type = bool - default = false - description = "Prevent helm chart hooks from running" -} - -variable "helm_reset_values" { - type = bool - default = false - description = "When upgrading, reset the values to the ones built into the helm chart" -} - -variable "helm_reuse_values" { - type = bool - default = 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" -} - -variable "helm_force_update" { - type = bool - default = false - description = "Force helm resource update through delete/recreate if needed" -} - -variable "helm_recreate_pods" { - type = bool - default = false - description = "Perform pods restart during helm upgrade/rollback" -} - -variable "helm_cleanup_on_fail" { - type = bool - default = false - description = "Allow deletion of new resources created in this helm upgrade when upgrade fails" -} - -variable "helm_release_max_history" { - type = number - default = 0 - description = "Maximum number of release versions stored per release" -} - -variable "helm_atomic" { - type = bool - default = false - description = "If set, installation process purges chart on fail. The wait flag will be set automatically if atomic is used" -} - -variable "helm_wait" { - type = bool - default = true - description = "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" -} - -variable "helm_wait_for_jobs" { - type = bool - default = false - description = "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" -} - -variable "helm_skip_crds" { - type = bool - default = false - description = "If set, no CRDs will be installed before helm release" -} - -variable "helm_render_subchart_notes" { - type = bool - default = true - description = "If set, render helm subchart notes along with the parent" -} - -variable "helm_disable_openapi_validation" { - type = bool - default = false - description = "If set, the installation process will not validate rendered helm templates against the Kubernetes OpenAPI Schema" -} - -variable "helm_dependency_update" { - type = bool - default = false - description = "Runs helm dependency update before installing the chart" -} - -variable "helm_replace" { - type = bool - default = false - description = "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" -} - -variable "helm_description" { - type = string - default = "" - description = "Set helm release description attribute (visible in the history)" -} - -variable "helm_lint" { - type = bool - default = false - description = "Run the helm chart linter during the plan" -} - -variable "helm_set_sensitive" { - type = map(any) - default = {} - description = "Value block with custom sensitive values to be merged with the values yaml that won't be exposed in the plan's diff" -} - -variable "helm_postrender" { - type = map(any) - default = {} - description = "Value block with a path to a binary file to run after helm renders the manifest which can alter the manifest contents" + description = "Set to false to prevent the module from creating any resources." + nullable = false } diff --git a/versions.tf b/versions.tf index e8e232b..58a9f12 100644 --- a/versions.tf +++ b/versions.tf @@ -1,14 +1,15 @@ +# 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. terraform { - required_version = ">= 1.0" + required_version = ">= 1.5.0" required_providers { aws = { source = "hashicorp/aws" - version = ">= 4.19.0" + version = "~> 5" } kubernetes = { source = "hashicorp/kubernetes" - version = ">= 2.16.0" + version = ">= 2.20.0" } helm = { source = "hashicorp/helm" @@ -18,10 +19,5 @@ terraform { source = "cloudposse/utils" version = ">= 0.17.0" } - - random = { - source = "hashicorp/random" - version = ">= 3.4.3" - } } } From b1182a0fb22c0c2d35e1bfa7f716591bbdd56b3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Odstr=C4=8Dil=C3=ADk?= Date: Wed, 28 May 2025 10:27:20 +0200 Subject: [PATCH 2/6] feat: add DNS zones configuration to addon values --- main.tf | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/main.tf b/main.tf index f0bca69..14fce1a 100644 --- a/main.tf +++ b/main.tf @@ -20,6 +20,41 @@ locals { } addon_values = yamlencode({ + zones = { + ".:53" = { + plugins = { + cache = { + denial = { # disable negative caching + size = 0 + ttl = 1 + } + } + forward = { + force_tcp = true + } + } + } + "ip6.arpa:53" = { + plugins = { + log = { + classes = "error" + } + forward = { + force_tcp = true + } + } + } + "in-addr.arpa:53" = { + plugins = { + log = { + classes = "error" + } + forward = { + force_tcp = true + } + } + } + } serviceAccount = { create = module.addon-irsa[local.addon.name].service_account_create name = module.addon-irsa[local.addon.name].service_account_name From 7336478c64238ce00fc168d2a99e88378f7eca26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Odstr=C4=8Dil=C3=ADk?= Date: Wed, 28 May 2025 13:42:49 +0200 Subject: [PATCH 3/6] fix: correct structure of addon_values configuration in main.tf --- .github/workflows/release-drafter.yaml | 28 -- .pre-commit-config.yaml | 33 +- .templatesyncignore | 9 +- .terraform-docs.yml | 1 + .terraform.lock.hcl | 161 +++--- .tool-versions | 5 +- README.md | 35 +- addon-irsa.tf | 52 -- addon.tf | 130 ++--- docs/.intro.md | 8 + examples/basic/.terraform.lock.hcl | 106 ++-- examples/basic/main.tf | 12 - examples/basic/versions.tf | 8 +- main.tf | 109 +++-- migrations.tf | 10 - modules/addon/.terraform.lock.hcl | 95 ++++ modules/addon/argo-helm.tf | 170 +++++++ modules/addon/argo.tf | 104 ++++ modules/addon/helm.tf | 71 +++ .../addon/helm/argocd-application/.helmignore | 23 + .../addon/helm/argocd-application/Chart.yaml | 18 + .../argocd-application/templates/_helpers.tpl | 51 ++ .../templates/application.yaml | 19 + .../addon/helm/argocd-application/values.yaml | 2 + modules/addon/outputs.tf | 14 + modules/addon/validations.tf | 36 ++ modules/addon/variables.tf | 458 ++++++++++++++++++ modules/addon/versions.tf | 22 + requirements.txt | 2 - scripts/sync-variables.py | 95 ---- variables-addon-irsa.tf | 163 ------- variables-addon.tf | 10 +- versions.tf | 14 +- 33 files changed, 1442 insertions(+), 632 deletions(-) delete mode 100644 .github/workflows/release-drafter.yaml delete mode 100644 addon-irsa.tf create mode 100644 docs/.intro.md create mode 100644 modules/addon/.terraform.lock.hcl create mode 100644 modules/addon/argo-helm.tf create mode 100644 modules/addon/argo.tf create mode 100644 modules/addon/helm.tf create mode 100644 modules/addon/helm/argocd-application/.helmignore create mode 100644 modules/addon/helm/argocd-application/Chart.yaml create mode 100644 modules/addon/helm/argocd-application/templates/_helpers.tpl create mode 100644 modules/addon/helm/argocd-application/templates/application.yaml create mode 100644 modules/addon/helm/argocd-application/values.yaml create mode 100644 modules/addon/outputs.tf create mode 100644 modules/addon/validations.tf create mode 100644 modules/addon/variables.tf create mode 100644 modules/addon/versions.tf delete mode 100644 requirements.txt delete mode 100755 scripts/sync-variables.py delete mode 100644 variables-addon-irsa.tf diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml deleted file mode 100644 index 67303c3..0000000 --- a/.github/workflows/release-drafter.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: Release drafter - -on: - push: - branches: - - main - - master - - pull_request: - types: - - opened - - reopened - - synchronize - - labeled - -permissions: - contents: write - pull-requests: read - -jobs: - release-drafter: - runs-on: ubuntu-24.04 - steps: - - uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0 - with: - config-name: RELEASE_DRAFTER.yml - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 60a9cad..84badc1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - repo: https://github.com/antonbabenko/pre-commit-terraform # renovate: datasource=github-releases depName=antonbabenko/pre-commit-terraform - rev: 55d0143972eec4905fdaea2f444f1e88218f9dce # v1.96.3 # pragma: allowlist secret + rev: c0f51014b8ec51c4455a7dac40697be15e285668 # v1.99.5 # pragma: allowlist secret hooks: - id: terraform_validate - id: terraform_fmt @@ -29,7 +29,20 @@ repos: - id: terraform_checkov args: - "--args=--quiet --skip-check CKV_TF_1" # CKV_TF_1: "Ensure Terraform module sources use a commit hash" - - id: terraform_docs + + - repo: https://github.com/lablabs/luactl + # renovate: datasource=github-tags depName=lablabs/luactl + rev: 818d633e5f41c26a47bb31307535de89c6aba73d # v0.0.1 # pragma: allowlist secret + hooks: + - id: sync # should be run before terraform_docs + name: Luactl sync variables + files: addon.*\.tf$ + + - repo: https://github.com/antonbabenko/pre-commit-terraform + # renovate: datasource=github-releases depName=antonbabenko/pre-commit-terraform + rev: c0f51014b8ec51c4455a7dac40697be15e285668 # v1.99.5 # pragma: allowlist secret + hooks: + - id: terraform_docs # should be run after luactl sync args: - "--args=--config=.terraform-docs.yml" @@ -41,18 +54,8 @@ repos: args: ["--baseline", ".secrets.baseline"] exclude: terraform.tfstate - - repo: https://github.com/woodruffw/zizmor-pre-commit - # renovate: datasource=github-releases depName=woodruffw/zizmor-pre-commit - rev: 07a06156e31897fbb5ba0e22a961e8e3c2a0677b # v1.16.0 # pragma: allowlist secret + - repo: https://github.com/zizmorcore/zizmor-pre-commit + # renovate: datasource=github-releases depName=zizmorcore/zizmor-pre-commit + rev: 69fa534d69454f44ddd4451b5e2da7a1c48e525b # v1.11.0 # pragma: allowlist secret hooks: - id: zizmor - - - 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/.templatesyncignore b/.templatesyncignore index 7901ba9..0092412 100644 --- a/.templatesyncignore +++ b/.templatesyncignore @@ -1,4 +1,8 @@ -modules +modules/addon-oidc +modules/addon-irsa +modules/addon/argo-helm.tf +modules/addon/argo.tf +modules/addon/helm.tf examples/basic/main.tf main.tf variables.tf @@ -7,4 +11,7 @@ README.md .github/workflows/renovate.yaml renovate.json addon-oidc.tf +addon-irsa.tf variables-addon-oidc.tf +variables-addon-irsa.tf +versions.tf diff --git a/.terraform-docs.yml b/.terraform-docs.yml index d45d422..1868ba4 100644 --- a/.terraform-docs.yml +++ b/.terraform-docs.yml @@ -4,6 +4,7 @@ header-from: main.tf footer-from: docs/.footer.md content: |- + {{ include "docs/.intro.md" }} {{ .Header }} {{ include "docs/.addon.md" }} {{ .Requirements }} diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index a1b3c67..c282877 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -2,98 +2,115 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/cloudposse/utils" { - version = "1.19.2" - constraints = ">= 0.17.0" + version = "1.30.0" + constraints = ">= 1.0.0" hashes = [ - "h1:0Ch7BTulKB1jXOm0AV7d5f1bdMKEyZc1BA+PZ6cXkAY=", - "h1:gqYR81ADrA9HeWCMnEOg/x9RIMce6dwOXOC/DxjsYto=", - "h1:yy3kB4scsoyM81yyyUMPxuJXeFvexBL5KMrCKrjrUkE=", - "h1:zeLrxuXDYEA5+hArYpigYKZJiIB57WQ3nn7VGTc0QDc=", - "zh:1002d1c3f458b569119b31eb2f732c093922b7f86aa59d999d77c3f3ca297f53", - "zh:367ca0d95bf24db1ff6632da94affe1ac0b51679e00f6ca3f1b8f927b9724c3b", - "zh:3e48ef23e276d18a88405926f39b476d40fb543859f2fcfc316f70501071c1ed", - "zh:3fe9d58ee267423e65c9c52cb486dda1eb59973f42eea9d84fe4c842108fdb73", - "zh:5e9ee6099ee56c30c3dfec935f749b3cef9ad2d4c6d8ad2cf39ee87587fc496d", - "zh:6babf986f8af41c739f1e441a4c0512262ff8bc36892f9506839b126138fce25", - "zh:6d9e659f1e18e409149ed8090ced8894317f37cdf234b34fe86b5aba354d559b", - "zh:828109b900c0fa9240bd48358423034817ab3a81d706b29d84a0e10401766ae4", - "zh:aff0d59c6ba5713a09e11a4f14dad048d787569e92ed4d6aa4b7778d39f52d31", - "zh:b7f469e47d1f94b276590809388ac216f59e1f4fb2d6b950c3f9fcbe9e4e2161", - "zh:b9003915fcbdd74c9e02ba11935daa6110516bf434bfee58f738ae3f2a595c2b", - "zh:dea118d95fe434b9089321e6db7573a882bd8b36d89fe2527e9adefa538561e1", - "zh:e18ef6d2be2cee7b8d0ac03c5eec362fd132c8f2b48da3999a280a4d778ec6ea", - "zh:f317eb941a57e6a899afa44ed6dc12a5c51228fcdf1b3043823346f3887facc9", + "h1:KmKu9rXFQIAvaXbwKYLR4QSUm5UBoh0wpftRKkG34Co=", + "h1:be9bmaq5PJ1US+WtgVjhdUPU0eiWhQNYAIb81EI+/Dw=", + "h1:hZeJ9YpYk/0lI77My1Y3pBapD600B40cHwEkKA2u7CQ=", + "zh:093e70d2dc0def5f98b7175cf2a8da533ded1dbd1d3c9fb022a34d57e829e5e8", + "zh:1a7dba74c056e604d76a394ce608e139d8267d8fa15f6a1cd9777fb2a91b6741", + "zh:2b1d379d6bfa98505ef6aa641b336b55116310916b55f9443a0584411f66785b", + "zh:410d25642ce366a91448266b90c0f8cdcbb34f51d65d14ff24678fbc50850711", + "zh:6032e69a3795794c483b1894ae206ebd854904dd160d20fbc2f69227ad322598", + "zh:79b55690195641e52590a3bc7f66944e3855d388938f5cbc39a0cb000cdbeccf", + "zh:7d0754656079250e49c530bffa5d0339433372e36998eb1d9193eea3030392fa", + "zh:8a78560a872e3470c3afefb08c9739a45952de39097c2a244ce31453caf7d37d", + "zh:a2c508d780364004969ca1c080118af2292cbb0fb46a4b67d54dcc100a8132bc", + "zh:a528d7a7195427b976e353c41784300a51e9e34a922c035aa9596f3072c190d2", + "zh:aa60b3cc9b01711c906dbb64f929a3c22371365fc6f74878fa460cb5a0bf7c66", + "zh:c0fedc527db8505ebb796d8b2cd70af151f3fef7daeb09fff6d020bedc5d1154", + "zh:cd37b6d417187073a11db0592b4edd7098b14ea8882491cd7d4795a169aea98e", + "zh:e9895b026770104de264d4a80c227864460169dfc697132edd6089e5b1843880", ] } provider "registry.terraform.io/hashicorp/aws" { - version = "5.42.0" - constraints = "~> 5.0" + version = "5.100.0" + constraints = ">= 5.0.0" hashes = [ - "h1:0lkSSlK45Qil9fO1kFy8RXVC/k6qfC4LDZIaCKnWcUc=", - "h1:Gwe5HXZYD/3M5j6LwKhp8amb1SraCR9p+G96d381RVc=", - "h1:Wjmg0WFQxZ7J7OeZ/SY+NW4JRe/jKJEut5tVb51z++4=", - "h1:Yxsj34z606m8wssYDHyleuBlQ9i+94MHwRs38thQPZU=", - "zh:0fb12bd56a3ad777b29f957c56dd2119776dbc01b6074458f597990e368c82de", - "zh:16e99c13bef6e3777f67c240c916f57c01c9c142254cfb2720e08281ff906447", - "zh:218268f5fe73bcb19e9a996f781ab66df0da9e333d1c60612e3c51ad28a5105f", - "zh:220b17f7053d11548f35136669687d30ef1f1036e15393275325fd2b9654c715", - "zh:2256cfd74988ce05eada76b42efffc6fe2bf4d60b61f57e4db4fcf65ced4c666", - "zh:52da19f531e0cb9828f73bca620e30264e63a494bd7f9ce826aabcf010d3a241", - "zh:56069ce08d720280ba39aaf2fdd40c4357ffb54262c80e4d39c4e540a38e76af", - "zh:82c81398e68324029167f813fbb7c54fa3d233e99fa05001d85cbce8bdd08bb3", - "zh:82d6eaa87f5ab318959064e6c89adc2baabaf70b13f2f7de866f62416de05352", + "h1:Ijt7pOlB7Tr7maGQIqtsLFbl7pSMIj06TVdkoSBcYOw=", + "h1:edXOJWE4ORX8Fm+dpVpICzMZJat4AX0VRCAy/xkcOc0=", + "h1:hd45qFU5cFuJMpFGdUniU9mVIr5LYVWP1uMeunBpYYs=", + "zh:054b8dd49f0549c9a7cc27d159e45327b7b65cf404da5e5a20da154b90b8a644", + "zh:0b97bf8d5e03d15d83cc40b0530a1f84b459354939ba6f135a0086c20ebbe6b2", + "zh:1589a2266af699cbd5d80737a0fe02e54ec9cf2ca54e7e00ac51c7359056f274", + "zh:6330766f1d85f01ae6ea90d1b214b8b74cc8c1badc4696b165b36ddd4cc15f7b", + "zh:7c8c2e30d8e55291b86fcb64bdf6c25489d538688545eb48fd74ad622e5d3862", + "zh:99b1003bd9bd32ee323544da897148f46a527f622dc3971af63ea3e251596342", "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", - "zh:ade8490cfdd8de8b9a82986588595b67e0ad1048d9e2d3a6f5164320179c2cd0", - "zh:b094ef56ae9bfffd586f46d4f7fb0097798738df758a8f3c51578ee163495c7e", - "zh:bd5e68e1e454bae0f8d73cff8448e814a35855a561c33b745e1b8b525fb06c9f", - "zh:c111c6a854bf121facca1642d528bfa80fb4214554ac6c33e4a59c86bc605b71", - "zh:e04df69a557adbcdf8efc77eb45be748f0acbe800ccede1e0895393c87722a0f", + "zh:9f8b909d3ec50ade83c8062290378b1ec553edef6a447c56dadc01a99f4eaa93", + "zh:aaef921ff9aabaf8b1869a86d692ebd24fbd4e12c21205034bb679b9caf883a2", + "zh:ac882313207aba00dd5a76dbd572a0ddc818bb9cbf5c9d61b28fe30efaec951e", + "zh:bb64e8aff37becab373a1a0cc1080990785304141af42ed6aa3dd4913b000421", + "zh:dfe495f6621df5540d9c92ad40b8067376350b005c637ea6efac5dc15028add4", + "zh:f0ddf0eaf052766cfe09dea8200a946519f653c384ab4336e2a4a64fdd6310e9", + "zh:f1b7e684f4c7ae1eed272b6de7d2049bb87a0275cb04dbb7cda6636f600699c9", + "zh:ff461571e3f233699bf690db319dfe46aec75e58726636a0d97dd9ac6e32fb70", ] } provider "registry.terraform.io/hashicorp/helm" { - version = "2.12.1" + version = "2.17.0" constraints = ">= 2.6.0" hashes = [ - "h1:7wfYOAeSEchHB8idNl+2jf+OkFi9zFSOLWkEZFuTCik=", - "h1:aBfcqM4cbywa7TAxfT1YoFS+Cst9waerlm4XErFmJlk=", - "h1:sgYI7lwGqJqPopY3NGmhb1eQ0YbH8PIXaAZAmnJrAvw=", - "h1:xwHVa6ab/XVfDrZ3h35OzLJ6g0Zte4VAvSnyKw3f9AI=", - "zh:1d623fb1662703f2feb7860e3c795d849c77640eecbc5a776784d08807b15004", - "zh:253a5bc62ba2c4314875139e3fbd2feaad5ef6b0fb420302a474ab49e8e51a38", - "zh:282358f4ad4f20d0ccaab670b8645228bfad1c03ac0d0df5889f0aea8aeac01a", - "zh:4fd06af3091a382b3f0d8f0a60880f59640d2b6d9d6a31f9a873c6f1bde1ec50", - "zh:6816976b1830f5629ae279569175e88b497abbbac30ee809948a1f923c67a80d", - "zh:7d82c4150cdbf48cfeec867be94c7b9bd7682474d4df0ebb7e24e148f964844f", - "zh:83f062049eea2513118a4c6054fb06c8600bac96196f25aed2cc21898ec86e93", - "zh:a79eec0cf4c08fca79e44033ec6e470f25ff23c3e2c7f9bc707ed7771c1072c0", - "zh:b2b2d904b2821a6e579910320605bc478bbef063579a23fbfdd6fcb5871b81f8", - "zh:e91177ca06a15487fc570cb81ecef6359aa399459ea2aa7c4f7367ba86f6fcad", - "zh:e976bcb82996fc4968f8382bbcb6673efb1f586bf92074058a232028d97825b1", + "h1:0LSHBFqJvHTzQesUwagpDLsrzVliY+t2c26nDJizHFM=", + "h1:K5FEjxvDnxb1JF1kG1xr8J3pNGxoaR3Z0IBG9Csm/Is=", + "h1:kQMkcPVvHOguOqnxoEU2sm1ND9vCHiT8TvZ2x6v/Rsw=", + "zh:06fb4e9932f0afc1904d2279e6e99353c2ddac0d765305ce90519af410706bd4", + "zh:104eccfc781fc868da3c7fec4385ad14ed183eb985c96331a1a937ac79c2d1a7", + "zh:129345c82359837bb3f0070ce4891ec232697052f7d5ccf61d43d818912cf5f3", + "zh:3956187ec239f4045975b35e8c30741f701aa494c386aaa04ebabffe7749f81c", + "zh:66a9686d92a6b3ec43de3ca3fde60ef3d89fb76259ed3313ca4eb9bb8c13b7dd", + "zh:88644260090aa621e7e8083585c468c8dd5e09a3c01a432fb05da5c4623af940", + "zh:a248f650d174a883b32c5b94f9e725f4057e623b00f171936dcdcc840fad0b3e", + "zh:aa498c1f1ab93be5c8fbf6d48af51dc6ef0f10b2ea88d67bcb9f02d1d80d3930", + "zh:bf01e0f2ec2468c53596e027d376532a2d30feb72b0b5b810334d043109ae32f", + "zh:c46fa84cc8388e5ca87eb575a534ebcf68819c5a5724142998b487cb11246654", + "zh:d0c0f15ffc115c0965cbfe5c81f18c2e114113e7a1e6829f6bfd879ce5744fbb", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } provider "registry.terraform.io/hashicorp/kubernetes" { - version = "2.27.0" + version = "2.37.1" constraints = ">= 2.20.0" hashes = [ - "h1:/3kLyOR2jTaWS1MKso4xAztrocGBMxi8yVadWiqSWOg=", - "h1:GzU0FzYAT/+IgAhnSBcFH3bT+4I5N6oSga6iZgNJAus=", - "h1:TrlG/sofnDv8kAbzKOD5pIPeUiI5VQY61NuWH+cItDw=", - "h1:WuU4rl7szPJr9Nfu5OoQGF84k8yQf+gmS9zU2eZuxcc=", - "zh:3bdba30ae67c55dc7e9a317ac0da3b208ea7926fe9c2f0ae6587ee88dcc58d1f", - "zh:3f35138a831c00b188d2ffee27111dd0cf59afad2dd5653ed9e67d59646de12c", - "zh:64066d18f6ae9a316c2bc840ef3e641d7ab94e1ea3a41d12523e77345ad442ef", - "zh:653063d44b44881af3a480f7f8eaa94fa300e0229df2072d30f606bddcc9f025", - "zh:87f306e37efb61d13efa6da53a1e45e97e5996ebc0568b1caf8c3c5e54c05809", - "zh:8c428b9708f9634391e52300218771eab3fe942bb1295d8c0ad50ca4b33db3d9", - "zh:a44e87119a0337ded15479851786a13f412b413d9a463ba550d1210249206b0f", - "zh:aa2c4d110b0de6ef997c0d45f3f23f8a98f5530753095d6eff439a6d91a8ea31", - "zh:eb15ed8781ac6a0dec2f7d03cf090e23cfa05e3225806c6231ff2c574662fd63", - "zh:eb81c563f93bd3303f9620d11cd49f21f3f89ac3475c6d3e821b239feb9c217d", - "zh:f1a344a7f16131123577e4ec994d04a34ea458ec16c1ccac53fe7946bd817b18", + "h1:+37jC6JlkPyPvDHudK3qaj7ZVJ0Zy9zc9+oq8h1WayA=", + "h1:qo9Ue/rIEnvxOpiK9qizwRFV7rvb5gCziKVytIcZHyk=", + "h1:x4cNsR4InB/AEpSRCmv6SQEY/ChylNaPceNlyzvfv7c=", + "zh:0ed097413c7fc804479e325966886b405dc0b75ad2b4f54ce4df1d8e4802b397", + "zh:17dcf4a685a00d2d048671124e8a1a8e836b58ecd2ef628a1c666fe0ced2e598", + "zh:36891284e5bced57c438f12d0b27856b0d4b70b562bd200b01919a6a89545be9", + "zh:3e49d86b508e641ba122d1b0af24cdc4d8ffa2ec1b30022436fb1d7c6ba696ea", + "zh:40be623e116708bdcb0fac32989db43720f031c5fe9a4dc63395078185d24403", + "zh:44fc0ac3bc39e289b67f9dde7ee9fef29eb8192197e5e68fee69098573021722", + "zh:957aa451573bcde5d57f6f8338ea3139010c7f61fefe8f6a140a8c267f056511", + "zh:c55fd85b7e8acaac17e30670ac3574b88b3530820dd004bcd2a5daa8624a46e9", + "zh:c743f06843a1f5ecde2b8ef639f4d3db654a334ef248dee57261c719ea843f3a", + "zh:c93cc71c64b838d89522ac5fb60f68e0e1e7f2fc39db6b0ead7afd78795e79ed", + "zh:eda1163c2266905adc54bc78cc3e7b606a164fbc6b59be607db933b302015ccd", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } + +provider "registry.terraform.io/hashicorp/random" { + version = "3.7.2" + hashes = [ + "h1:356j/3XnXEKr9nyicLUufzoF4Yr6hRy481KIxRVpK0c=", + "h1:KG4NuIBl1mRWU0KD/BGfCi1YN/j3F7H4YgeeM7iSdNs=", + "h1:hkKSY5xI4R1H4Yrg10HHbtOoxZif2dXa9HFPSbaVg5o=", + "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", + "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", + "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", + "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", + "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", + "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", + "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", + "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", + "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", + "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", + ] +} diff --git a/.tool-versions b/.tool-versions index c9bf870..dfe1393 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,7 +1,6 @@ terraform 1.5.7 terraform-docs 0.20.0 tflint 0.50.3 -checkov 3.2.352 -awscli 2.27.4 +checkov 3.2.457 +awscli 2.27.62 pre-commit 4.2.0 -python 3.13.3 diff --git a/README.md b/README.md index 0fa8210..807a2a6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,12 @@ +[](https://lablabs.io/) + +**About us:**
+[Labyrinth Labs](https://lablabs.io/) is a one-stop-shop for **DevOps, Cloud & Kubernetes**! We specialize in creating **powerful**, **scalable** and **cloud-native platforms** tailored to elevate your business. + +[As a team of experienced DevOps engineers](https://lablabs.io/about/), we know how to help our customers start their journey in the cloud, address the issues they have in their current setups and provide a **strategic solution to transform their infrastructure**. + +---- # AWS EKS Node Local DNS Terraform module A Terraform module to deploy the [Node Local DNS](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/) on Amazon EKS cluster. The upgrade process of this module is using the `create before destroy` feature, and the already running DaemonSet will be terminated after the new one is already running. @@ -40,22 +48,24 @@ See [basic example](examples/basic) for further information. | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.5.0 | -| [aws](#requirement\_aws) | ~> 5 | -| [helm](#requirement\_helm) | >= 2.6.0 | -| [kubernetes](#requirement\_kubernetes) | >= 2.20.0 | -| [utils](#requirement\_utils) | >= 0.17.0 | +| [terraform](#requirement\_terraform) | >= 1.5 | +| [aws](#requirement\_aws) | >= 5 | +| [helm](#requirement\_helm) | >= 2.6 | +| [kubernetes](#requirement\_kubernetes) | >= 2.20 | +| [random](#requirement\_random) | >= 3 | +| [utils](#requirement\_utils) | >= 1 | ## Modules | Name | Source | Version | |------|--------|---------| -| [addon](#module\_addon) | git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon | v0.0.18 | -| [addon-irsa](#module\_addon-irsa) | git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon-irsa | v0.0.18 | +| [addon](#module\_addon) | ./modules/addon | n/a | ## Resources | Name | Type | |------|------| +| [random_integer.metrics_port](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) | resource | +| [random_pet.release_name_suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | | [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[-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). @@ -69,16 +79,16 @@ See [basic example](examples/basic) for further information. | [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\_kubectl\_version](#input\_argo\_helm\_wait\_kubectl\_version) | Version of kubectl to use for ArgoCD Application wait job. Defaults to `1.33.0`. | `string` | +| [argo\_helm\_wait\_kubectl\_version](#input\_argo\_helm\_wait\_kubectl\_version) | Version of kubectl to use for ArgoCD Application wait job. Defaults to `1.33.3`. | `string` | | [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\_tolerations](#input\_argo\_helm\_wait\_tolerations) | Tolerations for ArgoCD Application Helm release wait job. Defaults to `[]`. | `list(any)` | -| [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\_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\_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\_metadata](#input\_argo\_metadata) | ArgoCD Application metadata configuration. Override or create additional metadata parameters. Defaults to `{ finalizers = ["resources-finalizer.argocd.argoproj.io"] }`. | `any` | | [argo\_name](#input\_argo\_name) | Name of the ArgoCD Application. Required if `argo_source_type` is set to `kustomize` or `directory`. If `argo_source_type` is set to `helm`, ArgoCD Application name will equal `helm_release_name`. Defaults to `""`. | `string` | | [argo\_namespace](#input\_argo\_namespace) | Namespace to deploy ArgoCD Application to. Defaults to `argo`. | `string` | | [argo\_operation](#input\_argo\_operation) | ArgoCD Application manifest operation parameter. Defaults to `{}`. | `any` | @@ -86,7 +96,7 @@ See [basic example](examples/basic) for further information. | [argo\_source\_path](#input\_argo\_source\_path) | ArgoCD Application source path. Required if `argo_source_type` is set to `kustomize` or `directory`. Defaults to `""`. | `string` | | [argo\_source\_repo\_url](#input\_argo\_source\_repo\_url) | ArgoCD Application source repo URL. Required if `argo_source_type` is set to `kustomize` or `directory`. Defaults to `""`. | `string` | | [argo\_source\_target\_revision](#input\_argo\_source\_target\_revision) | ArgoCD Application source target revision. Required if `argo_source_type` is set to `kustomize` or `directory`. Defaults to `""`. | `string` | -| [argo\_source\_type](#input\_argo\_source\_type) | Source type for ArgoCD Application. Can be either `helm`, `kustomize`, or `directory`. Defaults to `helm`. | `string` | +| [argo\_source\_type](#input\_argo\_source\_type) | Source type for ArgoCD Application. Can be either `helm`, `kustomize`, `directory` or `helm-directory`. Defaults to `helm`. | `string` | | [argo\_spec](#input\_argo\_spec) | ArgoCD Application spec configuration. Configuration is extended by deep merging with the default spec parameters. Defaults to `{}`. | `any` | | [argo\_spec\_override](#input\_argo\_spec\_override) | ArgoCD Application spec configuration. Configuration is overriden by merging natively with the default spec parameters. Defaults to `{}`. | `any` | | [argo\_sync\_policy](#input\_argo\_sync\_policy) | ArgoCD Application manifest syncPolicy parameter. Defaults to `{}`. | `any` | @@ -160,7 +170,6 @@ See [basic example](examples/basic) for further information. | Name | Description | |------|-------------| | [addon](#output\_addon) | The addon module outputs | -| [addon\_irsa](#output\_addon\_irsa) | The addon IRSA module outputs | ## Contributing and reporting issues Feel free to create an issue in this repository if you have questions, suggestions or feature requests. diff --git a/addon-irsa.tf b/addon-irsa.tf deleted file mode 100644 index 969281c..0000000 --- a/addon-irsa.tf +++ /dev/null @@ -1,52 +0,0 @@ -# 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. -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.18" - - enabled = var.enabled - - rbac_create = var.rbac_create != null ? var.rbac_create : try(each.value.rbac_create, null) - service_account_create = var.service_account_create != null ? var.service_account_create : try(each.value.service_account_create, null) - service_account_name = var.service_account_name != null ? var.service_account_name : try(each.value.service_account_name, each.key) - service_account_namespace = var.service_account_namespace != null ? var.service_account_namespace : try(each.value.service_account_namespace, local.addon_namespace) - - # IRSA - cluster_identity_oidc_issuer = var.cluster_identity_oidc_issuer != null ? var.cluster_identity_oidc_issuer : try(each.value.cluster_identity_oidc_issuer, null) - cluster_identity_oidc_issuer_arn = var.cluster_identity_oidc_issuer_arn != null ? var.cluster_identity_oidc_issuer_arn : try(each.value.cluster_identity_oidc_issuer_arn, null) - - irsa_role_create = var.irsa_role_create != null ? var.irsa_role_create : try(each.value.irsa_role_create, null) - irsa_role_name_prefix = var.irsa_role_name_prefix != null ? var.irsa_role_name_prefix : try(each.value.irsa_role_name_prefix, "${each.key}-irsa") - irsa_role_name = var.irsa_role_name != null ? var.irsa_role_name : try(each.value.irsa_role_name, local.addon_name) - - irsa_policy_enabled = var.irsa_policy_enabled != null ? var.irsa_policy_enabled : try(each.value.irsa_policy_enabled, null) - irsa_policy = var.irsa_policy != null ? var.irsa_policy : try(each.value.irsa_policy, null) - irsa_assume_role_enabled = var.irsa_assume_role_enabled != null ? var.irsa_assume_role_enabled : try(each.value.irsa_assume_role_enabled, null) - irsa_assume_role_arns = var.irsa_assume_role_arns != null ? var.irsa_assume_role_arns : try(each.value.irsa_assume_role_arns, null) - 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 : lookup(each.value, "irsa_additional_policies", null) - - 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, null) - 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, null) - - irsa_tags = var.irsa_tags != null ? var.irsa_tags : try(each.value.irsa_tags, null) - - # Pod identity - cluster_name = var.cluster_name != null ? var.cluster_name : try(each.value.cluster_name, null) - - pod_identity_role_create = var.pod_identity_role_create != null ? var.pod_identity_role_create : try(each.value.pod_identity_role_create, null) - pod_identity_role_name_prefix = var.pod_identity_role_name_prefix != null ? var.pod_identity_role_name_prefix : try(each.value.pod_identity_role_name_prefix, "${each.key}-pi") - pod_identity_role_name = var.pod_identity_role_name != null ? var.pod_identity_role_name : try(each.value.pod_identity_role_name, local.addon_name) - - pod_identity_policy_enabled = var.pod_identity_policy_enabled != null ? var.pod_identity_policy_enabled : try(each.value.pod_identity_policy_enabled, null) - pod_identity_policy = var.pod_identity_policy != null ? var.pod_identity_policy : try(each.value.pod_identity_policy, null) - pod_identity_permissions_boundary = var.pod_identity_permissions_boundary != null ? var.pod_identity_permissions_boundary : try(each.value.pod_identity_permissions_boundary, null) - pod_identity_additional_policies = var.pod_identity_additional_policies != null ? var.pod_identity_additional_policies : lookup(each.value, "pod_identity_additional_policies", null) - - pod_identity_tags = var.pod_identity_tags != null ? var.pod_identity_tags : try(each.value.pod_identity_tags, null) -} - -output "addon_irsa" { - description = "The addon IRSA module outputs" - value = module.addon-irsa -} diff --git a/addon.tf b/addon.tf index 92ce9e9..b6eb12f 100644 --- a/addon.tf +++ b/addon.tf @@ -1,89 +1,94 @@ # 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. locals { addon_argo_source_type = var.argo_source_type != null ? var.argo_source_type : try(local.addon.argo_source_type, "helm") - addon_argo_source_helm_enabled = local.addon_argo_source_type == "helm" + addon_argo_source_helm_enabled = local.addon_argo_source_type == "helm" || local.addon_argo_source_type == "helm-directory" addon_argo_name = var.argo_name != null ? var.argo_name : try(local.addon.argo_name, local.addon.name) addon_helm_release_name = var.helm_release_name != null ? var.helm_release_name : try(local.addon.helm_release_name, local.addon.name) - addon_name = local.addon_argo_source_helm_enabled ? local.addon_helm_release_name : local.addon_argo_name + # CUSTOM config: We need to generate a unique name for the addon name to be able to deploy multiple instances + addon_name = "${local.addon_argo_source_helm_enabled ? local.addon_helm_release_name : local.addon_argo_name}-${one(random_pet.release_name_suffix[*].id)}" addon_namespace = var.namespace != null ? var.namespace : try(local.addon.namespace, local.addon.name) } module "addon" { - source = "git::https://github.com/lablabs/terraform-aws-eks-universal-addon.git//modules/addon?ref=v0.0.18" + source = "./modules/addon" # CUSTOM config: relative path to the addon module with create_before_destroy lifecycle enabled = var.enabled # variable priority var.* (provided by the module user) > local.addon.* (universal addon default override) > default (universal addon default) namespace = local.addon_namespace - helm_enabled = var.helm_enabled != null ? var.helm_enabled : try(local.addon.helm_enabled, null) + helm_enabled = var.helm_enabled != null ? var.helm_enabled : lookup(local.addon, "helm_enabled", null) helm_release_name = local.addon_name - helm_chart_name = var.helm_chart_name != null ? var.helm_chart_name : try(local.addon.helm_chart_name, local.addon.name) - helm_chart_version = var.helm_chart_version != null ? var.helm_chart_version : try(local.addon.helm_chart_version, null) - helm_atomic = var.helm_atomic != null ? var.helm_atomic : try(local.addon.helm_atomic, null) - helm_cleanup_on_fail = var.helm_cleanup_on_fail != null ? var.helm_cleanup_on_fail : try(local.addon.helm_cleanup_on_fail, null) - helm_create_namespace = var.helm_create_namespace != null ? var.helm_create_namespace : try(local.addon.helm_create_namespace, null) - helm_dependency_update = var.helm_dependency_update != null ? var.helm_dependency_update : try(local.addon.helm_dependency_update, null) - helm_description = var.helm_description != null ? var.helm_description : try(local.addon.helm_description, null) - helm_devel = var.helm_devel != null ? var.helm_devel : try(local.addon.helm_devel, null) - helm_disable_openapi_validation = var.helm_disable_openapi_validation != null ? var.helm_disable_openapi_validation : try(local.addon.helm_disable_openapi_validation, null) - helm_disable_webhooks = var.helm_disable_webhooks != null ? var.helm_disable_webhooks : try(local.addon.helm_disable_webhooks, null) - helm_force_update = var.helm_force_update != null ? var.helm_force_update : try(local.addon.helm_force_update, null) - helm_keyring = var.helm_keyring != null ? var.helm_keyring : try(local.addon.helm_keyring, null) - helm_lint = var.helm_lint != null ? var.helm_lint : try(local.addon.helm_lint, null) - helm_package_verify = var.helm_package_verify != null ? var.helm_package_verify : try(local.addon.helm_package_verify, null) - helm_postrender = var.helm_postrender != null ? var.helm_postrender : try(local.addon.helm_postrender, null) - helm_recreate_pods = var.helm_recreate_pods != null ? var.helm_recreate_pods : try(local.addon.helm_recreate_pods, null) - helm_release_max_history = var.helm_release_max_history != null ? var.helm_release_max_history : try(local.addon.helm_release_max_history, null) - helm_render_subchart_notes = var.helm_render_subchart_notes != null ? var.helm_render_subchart_notes : try(local.addon.helm_render_subchart_notes, null) - helm_replace = var.helm_replace != null ? var.helm_replace : try(local.addon.helm_replace, null) - helm_repo_ca_file = var.helm_repo_ca_file != null ? var.helm_repo_ca_file : try(local.addon.helm_repo_ca_file, null) - helm_repo_cert_file = var.helm_repo_cert_file != null ? var.helm_repo_cert_file : try(local.addon.helm_repo_cert_file, null) - helm_repo_key_file = var.helm_repo_key_file != null ? var.helm_repo_key_file : try(local.addon.helm_repo_key_file, null) - helm_repo_password = var.helm_repo_password != null ? var.helm_repo_password : try(local.addon.helm_repo_password, null) - helm_repo_url = var.helm_repo_url != null ? var.helm_repo_url : try(local.addon.helm_repo_url, null) - helm_repo_username = var.helm_repo_username != null ? var.helm_repo_username : try(local.addon.helm_repo_username, null) - helm_reset_values = var.helm_reset_values != null ? var.helm_reset_values : try(local.addon.helm_reset_values, null) - helm_reuse_values = var.helm_reuse_values != null ? var.helm_reuse_values : try(local.addon.helm_reuse_values, null) - helm_set_sensitive = var.helm_set_sensitive != null ? var.helm_set_sensitive : try(local.addon.helm_set_sensitive, null) - helm_skip_crds = var.helm_skip_crds != null ? var.helm_skip_crds : try(local.addon.helm_skip_crds, null) - helm_timeout = var.helm_timeout != null ? var.helm_timeout : try(local.addon.helm_timeout, null) - helm_wait = var.helm_wait != null ? var.helm_wait : try(local.addon.helm_wait, null) - helm_wait_for_jobs = var.helm_wait_for_jobs != null ? var.helm_wait_for_jobs : try(local.addon.helm_wait_for_jobs, null) + helm_chart_name = var.helm_chart_name != null ? var.helm_chart_name : lookup(local.addon, "helm_chart_name", local.addon.name) + helm_chart_version = var.helm_chart_version != null ? var.helm_chart_version : lookup(local.addon, "helm_chart_version", null) + helm_atomic = var.helm_atomic != null ? var.helm_atomic : lookup(local.addon, "helm_atomic", null) + helm_cleanup_on_fail = var.helm_cleanup_on_fail != null ? var.helm_cleanup_on_fail : lookup(local.addon, "helm_cleanup_on_fail", null) + helm_create_namespace = var.helm_create_namespace != null ? var.helm_create_namespace : lookup(local.addon, "helm_create_namespace", null) + helm_dependency_update = var.helm_dependency_update != null ? var.helm_dependency_update : lookup(local.addon, "helm_dependency_update", null) + helm_description = var.helm_description != null ? var.helm_description : lookup(local.addon, "helm_description", null) + helm_devel = var.helm_devel != null ? var.helm_devel : lookup(local.addon, "helm_devel", null) + helm_disable_openapi_validation = var.helm_disable_openapi_validation != null ? var.helm_disable_openapi_validation : lookup(local.addon, "helm_disable_openapi_validation", null) + helm_disable_webhooks = var.helm_disable_webhooks != null ? var.helm_disable_webhooks : lookup(local.addon, "helm_disable_webhooks", null) + helm_force_update = var.helm_force_update != null ? var.helm_force_update : lookup(local.addon, "helm_force_update", null) + helm_keyring = var.helm_keyring != null ? var.helm_keyring : lookup(local.addon, "helm_keyring", null) + helm_lint = var.helm_lint != null ? var.helm_lint : lookup(local.addon, "helm_lint", null) + helm_package_verify = var.helm_package_verify != null ? var.helm_package_verify : lookup(local.addon, "helm_package_verify", null) + helm_postrender = var.helm_postrender != null ? var.helm_postrender : lookup(local.addon, "helm_postrender", null) + helm_recreate_pods = var.helm_recreate_pods != null ? var.helm_recreate_pods : lookup(local.addon, "helm_recreate_pods", null) + helm_release_max_history = var.helm_release_max_history != null ? var.helm_release_max_history : lookup(local.addon, "helm_release_max_history", null) + helm_render_subchart_notes = var.helm_render_subchart_notes != null ? var.helm_render_subchart_notes : lookup(local.addon, "helm_render_subchart_notes", null) + helm_replace = var.helm_replace != null ? var.helm_replace : lookup(local.addon, "helm_replace", null) + helm_repo_ca_file = var.helm_repo_ca_file != null ? var.helm_repo_ca_file : lookup(local.addon, "helm_repo_ca_file", null) + helm_repo_cert_file = var.helm_repo_cert_file != null ? var.helm_repo_cert_file : lookup(local.addon, "helm_repo_cert_file", null) + helm_repo_key_file = var.helm_repo_key_file != null ? var.helm_repo_key_file : lookup(local.addon, "helm_repo_key_file", null) + helm_repo_password = var.helm_repo_password != null ? var.helm_repo_password : lookup(local.addon, "helm_repo_password", null) + helm_repo_url = var.helm_repo_url != null ? var.helm_repo_url : lookup(local.addon, "helm_repo_url", null) + helm_repo_username = var.helm_repo_username != null ? var.helm_repo_username : lookup(local.addon, "helm_repo_username", null) + helm_reset_values = var.helm_reset_values != null ? var.helm_reset_values : lookup(local.addon, "helm_reset_values", null) + helm_reuse_values = var.helm_reuse_values != null ? var.helm_reuse_values : lookup(local.addon, "helm_reuse_values", null) + helm_set_sensitive = var.helm_set_sensitive != null ? var.helm_set_sensitive : lookup(local.addon, "helm_set_sensitive", null) + helm_skip_crds = var.helm_skip_crds != null ? var.helm_skip_crds : lookup(local.addon, "helm_skip_crds", null) + helm_timeout = var.helm_timeout != null ? var.helm_timeout : lookup(local.addon, "helm_timeout", null) + helm_wait = var.helm_wait != null ? var.helm_wait : lookup(local.addon, "helm_wait", null) + helm_wait_for_jobs = var.helm_wait_for_jobs != null ? var.helm_wait_for_jobs : lookup(local.addon, "helm_wait_for_jobs", null) argo_source_type = local.addon_argo_source_type - argo_source_repo_url = var.argo_source_repo_url != null ? var.argo_source_repo_url : try(local.addon.argo_source_repo_url, null) - argo_source_target_revision = var.argo_source_target_revision != null ? var.argo_source_target_revision : try(local.addon.argo_source_target_revision, null) - argo_source_path = var.argo_source_path != null ? var.argo_source_path : try(local.addon.argo_source_path, null) + argo_source_repo_url = var.argo_source_repo_url != null ? var.argo_source_repo_url : lookup(local.addon, "argo_source_repo_url", null) + argo_source_target_revision = var.argo_source_target_revision != null ? var.argo_source_target_revision : lookup(local.addon, "argo_source_target_revision", null) + argo_source_path = var.argo_source_path != null ? var.argo_source_path : lookup(local.addon, "argo_source_path", null) - argo_apiversion = var.argo_apiversion != null ? var.argo_apiversion : try(local.addon.argo_apiversion, null) - argo_destination_server = var.argo_destination_server != null ? var.argo_destination_server : try(local.addon.argo_destination_server, null) - argo_enabled = var.argo_enabled != null ? var.argo_enabled : try(local.addon.argo_enabled, null) - argo_helm_enabled = var.argo_helm_enabled != null ? var.argo_helm_enabled : try(local.addon.argo_helm_enabled, null) - argo_helm_values = var.argo_helm_values != null ? var.argo_helm_values : try(local.addon.argo_helm_values, null) - argo_helm_wait_backoff_limit = var.argo_helm_wait_backoff_limit != null ? var.argo_helm_wait_backoff_limit : try(local.addon.argo_helm_wait_backoff_limit, null) - argo_helm_wait_node_selector = var.argo_helm_wait_node_selector != null ? var.argo_helm_wait_node_selector : try(local.addon.argo_helm_wait_node_selector, null) - argo_helm_wait_timeout = var.argo_helm_wait_timeout != null ? var.argo_helm_wait_timeout : try(local.addon.argo_helm_wait_timeout, null) - argo_helm_wait_tolerations = var.argo_helm_wait_tolerations != null ? var.argo_helm_wait_tolerations : try(local.addon.argo_helm_wait_tolerations, null) - argo_helm_wait_kubectl_version = var.argo_helm_wait_kubectl_version != null ? var.argo_helm_wait_kubectl_version : try(local.addon.argo_helm_wait_kubectl_version, null) - argo_info = var.argo_info != null ? var.argo_info : try(local.addon.argo_info, null) - argo_kubernetes_manifest_computed_fields = var.argo_kubernetes_manifest_computed_fields != null ? var.argo_kubernetes_manifest_computed_fields : try(local.addon.argo_kubernetes_manifest_computed_fields, null) - argo_kubernetes_manifest_field_manager_force_conflicts = var.argo_kubernetes_manifest_field_manager_force_conflicts != null ? var.argo_kubernetes_manifest_field_manager_force_conflicts : try(local.addon.argo_kubernetes_manifest_field_manager_force_conflicts, null) - argo_kubernetes_manifest_field_manager_name = var.argo_kubernetes_manifest_field_manager_name != null ? var.argo_kubernetes_manifest_field_manager_name : try(local.addon.argo_kubernetes_manifest_field_manager_name, null) - argo_kubernetes_manifest_wait_fields = var.argo_kubernetes_manifest_wait_fields != null ? var.argo_kubernetes_manifest_wait_fields : try(local.addon.argo_kubernetes_manifest_wait_fields, null) - argo_metadata = var.argo_metadata != null ? var.argo_metadata : try(local.addon.argo_metadata, null) + argo_apiversion = var.argo_apiversion != null ? var.argo_apiversion : lookup(local.addon, "argo_apiversion", null) + argo_destination_server = var.argo_destination_server != null ? var.argo_destination_server : lookup(local.addon, "argo_destination_server", null) + argo_enabled = var.argo_enabled != null ? var.argo_enabled : lookup(local.addon, "argo_enabled", null) + argo_helm_enabled = var.argo_helm_enabled != null ? var.argo_helm_enabled : lookup(local.addon, "argo_helm_enabled", null) + argo_helm_values = var.argo_helm_values != null ? var.argo_helm_values : lookup(local.addon, "argo_helm_values", null) + argo_helm_wait_backoff_limit = var.argo_helm_wait_backoff_limit != null ? var.argo_helm_wait_backoff_limit : lookup(local.addon, "argo_helm_wait_backoff_limit", null) + argo_helm_wait_node_selector = var.argo_helm_wait_node_selector != null ? var.argo_helm_wait_node_selector : lookup(local.addon, "argo_helm_wait_node_selector", null) + argo_helm_wait_timeout = var.argo_helm_wait_timeout != null ? var.argo_helm_wait_timeout : lookup(local.addon, "argo_helm_wait_timeout", null) + argo_helm_wait_tolerations = var.argo_helm_wait_tolerations != null ? var.argo_helm_wait_tolerations : lookup(local.addon, "argo_helm_wait_tolerations", null) + argo_helm_wait_kubectl_version = var.argo_helm_wait_kubectl_version != null ? var.argo_helm_wait_kubectl_version : lookup(local.addon, "argo_helm_wait_kubectl_version", null) + argo_info = var.argo_info != null ? var.argo_info : lookup(local.addon, "argo_info", null) + argo_kubernetes_manifest_computed_fields = var.argo_kubernetes_manifest_computed_fields != null ? var.argo_kubernetes_manifest_computed_fields : lookup(local.addon, "argo_kubernetes_manifest_computed_fields", null) + argo_kubernetes_manifest_field_manager_force_conflicts = var.argo_kubernetes_manifest_field_manager_force_conflicts != null ? var.argo_kubernetes_manifest_field_manager_force_conflicts : lookup(local.addon, "argo_kubernetes_manifest_field_manager_force_conflicts", null) + argo_kubernetes_manifest_field_manager_name = var.argo_kubernetes_manifest_field_manager_name != null ? var.argo_kubernetes_manifest_field_manager_name : lookup(local.addon, "argo_kubernetes_manifest_field_manager_name", null) + argo_kubernetes_manifest_wait_fields = var.argo_kubernetes_manifest_wait_fields != null ? var.argo_kubernetes_manifest_wait_fields : lookup(local.addon, "argo_kubernetes_manifest_wait_fields", null) + argo_metadata = var.argo_metadata != null ? var.argo_metadata : lookup(local.addon, "argo_metadata", null) argo_name = local.addon_name - argo_namespace = var.argo_namespace != null ? var.argo_namespace : try(local.addon.argo_namespace, null) - argo_project = var.argo_project != null ? var.argo_project : try(local.addon.argo_project, null) - argo_spec = var.argo_spec != null ? var.argo_spec : try(local.addon.argo_spec, null) - argo_spec_override = var.argo_spec_override != null ? var.argo_spec_override : try(local.addon.argo_spec_override, null) - argo_sync_policy = var.argo_sync_policy != null ? var.argo_sync_policy : try(local.addon.argo_sync_policy, null) - argo_operation = var.argo_operation != null ? var.argo_operation : try(local.addon.argo_operation, null) + argo_namespace = var.argo_namespace != null ? var.argo_namespace : lookup(local.addon, "argo_namespace", null) + argo_project = var.argo_project != null ? var.argo_project : lookup(local.addon, "argo_project", null) + argo_spec = var.argo_spec != null ? var.argo_spec : lookup(local.addon, "argo_spec", null) + argo_spec_override = var.argo_spec_override != null ? var.argo_spec_override : lookup(local.addon, "argo_spec_override", null) + argo_sync_policy = var.argo_sync_policy != null ? var.argo_sync_policy : lookup(local.addon, "argo_sync_policy", null) + argo_operation = var.argo_operation != null ? var.argo_operation : lookup(local.addon, "argo_operation", null) - settings = var.settings != null ? var.settings : try(local.addon.settings, null) + settings = var.settings != null ? var.settings : lookup(local.addon, "settings", null) values = one(data.utils_deep_merge_yaml.values[*].output) + + depends_on = [ + local.addon_depends_on + ] } data "utils_deep_merge_yaml" "values" { @@ -91,6 +96,7 @@ data "utils_deep_merge_yaml" "values" { input = compact([ local.addon_values, + local.addon_metrics_values, # CUSTOM config: see main.tf for details var.values ]) } diff --git a/docs/.intro.md b/docs/.intro.md new file mode 100644 index 0000000..8107b9f --- /dev/null +++ b/docs/.intro.md @@ -0,0 +1,8 @@ +[](https://lablabs.io/) + +**About us:**
+[Labyrinth Labs](https://lablabs.io/) is a one-stop-shop for **DevOps, Cloud & Kubernetes**! We specialize in creating **powerful**, **scalable** and **cloud-native platforms** tailored to elevate your business. + +[As a team of experienced DevOps engineers](https://lablabs.io/about/), we know how to help our customers start their journey in the cloud, address the issues they have in their current setups and provide a **strategic solution to transform their infrastructure**. + +---- diff --git a/examples/basic/.terraform.lock.hcl b/examples/basic/.terraform.lock.hcl index 1f7d58a..b265a45 100644 --- a/examples/basic/.terraform.lock.hcl +++ b/examples/basic/.terraform.lock.hcl @@ -2,51 +2,51 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/cloudposse/utils" { - version = "1.29.0" - constraints = ">= 0.17.0" + version = "1.30.0" + constraints = ">= 1.0.0" hashes = [ - "h1:GaRpNTCeE+NpvOuH7f2oMHExVHWrjOYJtwwnEr5y2xs=", - "h1:MHQr6iEHmDIl8WNCoIb5YCikU00GgQgKlvz3LBD3TU8=", - "h1:oIaC6Qr0auYbczWtllf5wyghn+im3k15OTphfDAPJiQ=", - "zh:300b7caca5f3233592e0c76678d588889387d8fc5c48ed9fcda8aa74aba0969a", - "zh:30f41007b7f9206999c5e987ccf4929dc8672cd394667bdc5f06364a595afcb6", - "zh:5f0916666e34bc688d727de1bf3e94f4065344b617bc8bfc0f5526ee1e181577", - "zh:6146beb6ef937f4dcc052015eea3a5c0bb807dbd7e4c1a66abde58957dea1c3e", - "zh:80d9e0c6592baf5ef66a63a70e7c14d738ab0949e7be4c179c8f6cdc953e3248", - "zh:8ef5254a0bc231dbe103eb3af1e3005efb0e43318e26b422dd648c2bbe77691a", - "zh:95ff25a69c31089860895376f38809484a84c069419ac0617e68025dafc2a455", - "zh:a3a1da7b8d3c2c2cd4a4e49441b58c4743e17bbe152c99427203bd25b7070cc3", - "zh:a4062e056ba43c3897180d711ac347fa4c23d832cdd1cfae1d91929b7a2ef1c1", - "zh:bc3a389262bad67ea63deb1cd5bbcfff4aa0f444b5000a697fcf17fb19ce938b", - "zh:c0df1fbeaf34240513a66245208e80a7ac42d70e056120aa52ae575a65118c68", - "zh:c6663dcfab08990123b6e4efda12f4b2f4a1b1a67fff3e0e49efbf7f723c3017", - "zh:eb8a3680f83ff7db968eb2ce495f8a34163aac6bea3597157c0ad4d554e8cb5b", - "zh:f62e2bdb77768dff933a19e50897c5117d4825d9956cd01fdce89a902e4ce880", + "h1:KmKu9rXFQIAvaXbwKYLR4QSUm5UBoh0wpftRKkG34Co=", + "h1:be9bmaq5PJ1US+WtgVjhdUPU0eiWhQNYAIb81EI+/Dw=", + "h1:hZeJ9YpYk/0lI77My1Y3pBapD600B40cHwEkKA2u7CQ=", + "zh:093e70d2dc0def5f98b7175cf2a8da533ded1dbd1d3c9fb022a34d57e829e5e8", + "zh:1a7dba74c056e604d76a394ce608e139d8267d8fa15f6a1cd9777fb2a91b6741", + "zh:2b1d379d6bfa98505ef6aa641b336b55116310916b55f9443a0584411f66785b", + "zh:410d25642ce366a91448266b90c0f8cdcbb34f51d65d14ff24678fbc50850711", + "zh:6032e69a3795794c483b1894ae206ebd854904dd160d20fbc2f69227ad322598", + "zh:79b55690195641e52590a3bc7f66944e3855d388938f5cbc39a0cb000cdbeccf", + "zh:7d0754656079250e49c530bffa5d0339433372e36998eb1d9193eea3030392fa", + "zh:8a78560a872e3470c3afefb08c9739a45952de39097c2a244ce31453caf7d37d", + "zh:a2c508d780364004969ca1c080118af2292cbb0fb46a4b67d54dcc100a8132bc", + "zh:a528d7a7195427b976e353c41784300a51e9e34a922c035aa9596f3072c190d2", + "zh:aa60b3cc9b01711c906dbb64f929a3c22371365fc6f74878fa460cb5a0bf7c66", + "zh:c0fedc527db8505ebb796d8b2cd70af151f3fef7daeb09fff6d020bedc5d1154", + "zh:cd37b6d417187073a11db0592b4edd7098b14ea8882491cd7d4795a169aea98e", + "zh:e9895b026770104de264d4a80c227864460169dfc697132edd6089e5b1843880", ] } provider "registry.terraform.io/hashicorp/aws" { - version = "5.97.0" - constraints = ">= 3.0.0, ~> 5.0, >= 5.8.0, >= 5.74.0, >= 5.79.0" + version = "5.100.0" + constraints = ">= 3.0.0, >= 5.0.0, >= 5.8.0, >= 5.74.0, >= 5.79.0" hashes = [ - "h1:WwuqNl8roShq7eOWRKLd6FDFRrr90XwEBVDp+7/9MWU=", - "h1:lI0I9GziJsdymNBcj+MJloqwD8fbogJw3EiR60j5FYU=", - "h1:rUDE0OgA+6IiEA+w0cPp3/QQNH4SpjFjYcQ6p7byKS4=", - "zh:02790ad98b767d8f24d28e8be623f348bcb45590205708334d52de2fb14f5a95", - "zh:088b4398a161e45762dc28784fcc41c4fa95bd6549cb708b82de577f2d39ffc7", - "zh:0c381a457b7af391c43fc0167919443f6105ad2702bde4d02ddea9fd7c9d3539", - "zh:1a4b57a5043dcca64d8b8bae8b30ef4f6b98ed2144f792f39c4e816d3f1e2c56", - "zh:1bf00a67f39e67664337bde065180d41d952242801ebcd1c777061d4ffaa1cc1", - "zh:24c549f53d6bd022af31426d3e78f21264d8a72409821669e7fd41966ae68b2b", - "zh:3abda50bbddb35d86081fe39522e995280aea7f004582c4af22112c03ac8b375", - "zh:7388ed7f21ce2eb46bd9066626ce5f3e2a5705f67f643acce8ae71972f66eaf6", - "zh:96740f2ff94e5df2b2d29a5035a1a1026fe821f61712b2099b224fb2c2277663", + "h1:Ijt7pOlB7Tr7maGQIqtsLFbl7pSMIj06TVdkoSBcYOw=", + "h1:edXOJWE4ORX8Fm+dpVpICzMZJat4AX0VRCAy/xkcOc0=", + "h1:hd45qFU5cFuJMpFGdUniU9mVIr5LYVWP1uMeunBpYYs=", + "zh:054b8dd49f0549c9a7cc27d159e45327b7b65cf404da5e5a20da154b90b8a644", + "zh:0b97bf8d5e03d15d83cc40b0530a1f84b459354939ba6f135a0086c20ebbe6b2", + "zh:1589a2266af699cbd5d80737a0fe02e54ec9cf2ca54e7e00ac51c7359056f274", + "zh:6330766f1d85f01ae6ea90d1b214b8b74cc8c1badc4696b165b36ddd4cc15f7b", + "zh:7c8c2e30d8e55291b86fcb64bdf6c25489d538688545eb48fd74ad622e5d3862", + "zh:99b1003bd9bd32ee323544da897148f46a527f622dc3971af63ea3e251596342", "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", - "zh:9f399f8e8683a3a3a6d63a41c7c3a5a5f266eedef40ea69eba75bacf03699879", - "zh:bcf2b288d4706ebd198f75d2159663d657535483331107f2cdef381f10688baf", - "zh:cc76c8a9fc3bad05a8779c1f80fe8c388734f1ec1dd0affa863343490527b466", - "zh:de4359cf1b057bfe7a563be93829ec64bf72e7a2b85a72d075238081ef5eb1db", - "zh:e208fa77051a1f9fa1eff6c5c58aabdcab0de1695b97cdea7b8dd81df3e0ed73", + "zh:9f8b909d3ec50ade83c8062290378b1ec553edef6a447c56dadc01a99f4eaa93", + "zh:aaef921ff9aabaf8b1869a86d692ebd24fbd4e12c21205034bb679b9caf883a2", + "zh:ac882313207aba00dd5a76dbd572a0ddc818bb9cbf5c9d61b28fe30efaec951e", + "zh:bb64e8aff37becab373a1a0cc1080990785304141af42ed6aa3dd4913b000421", + "zh:dfe495f6621df5540d9c92ad40b8067376350b005c637ea6efac5dc15028add4", + "zh:f0ddf0eaf052766cfe09dea8200a946519f653c384ab4336e2a4a64fdd6310e9", + "zh:f1b7e684f4c7ae1eed272b6de7d2049bb87a0275cb04dbb7cda6636f600699c9", + "zh:ff461571e3f233699bf690db319dfe46aec75e58726636a0d97dd9ac6e32fb70", ] } @@ -73,24 +73,24 @@ provider "registry.terraform.io/hashicorp/helm" { } provider "registry.terraform.io/hashicorp/kubernetes" { - version = "2.36.0" + version = "2.37.1" constraints = ">= 2.20.0" hashes = [ - "h1:94wlXkBzfXwyLVuJVhMdzK+VGjFnMjdmFkYhQ1RUFhI=", - "h1:GLR3jKampPSDrt77O+cjTQrcE/EpQIiIA6sreenoon0=", - "h1:vdY0sxo7ahwuz/y7flXTE04tSwn0Zhxyg6n62aTmAHI=", - "zh:07f38fcb7578984a3e2c8cf0397c880f6b3eb2a722a120a08a634a607ea495ca", - "zh:1adde61769c50dbb799d8bf8bfd5c8c504a37017dfd06c7820f82bcf44ca0d39", - "zh:39707f23ab58fd0e686967c0f973c0f5a39c14d6ccfc757f97c345fdd0cd4624", - "zh:4cc3dc2b5d06cc22d1c734f7162b0a8fdc61990ff9efb64e59412d65a7ccc92a", - "zh:8382dcb82ba7303715b5e67939e07dd1c8ecddbe01d12f39b82b2b7d7357e1d9", - "zh:88e8e4f90034186b8bfdea1b8d394621cbc46a064ff2418027e6dba6807d5227", - "zh:a6276a75ad170f76d88263fdb5f9558998bf3a3f7650d7bd3387b396410e59f3", - "zh:bc816c7e0606e5df98a0c7634b240bb0c8100c3107b8b17b554af702edc6a0c5", - "zh:cb2f31d58f37020e840af52755c18afd1f09a833c4903ac59270ab440fab57b7", - "zh:ee0d103b8d0089fb1918311683110b4492a9346f0471b136af46d3b019576b22", + "h1:+37jC6JlkPyPvDHudK3qaj7ZVJ0Zy9zc9+oq8h1WayA=", + "h1:qo9Ue/rIEnvxOpiK9qizwRFV7rvb5gCziKVytIcZHyk=", + "h1:x4cNsR4InB/AEpSRCmv6SQEY/ChylNaPceNlyzvfv7c=", + "zh:0ed097413c7fc804479e325966886b405dc0b75ad2b4f54ce4df1d8e4802b397", + "zh:17dcf4a685a00d2d048671124e8a1a8e836b58ecd2ef628a1c666fe0ced2e598", + "zh:36891284e5bced57c438f12d0b27856b0d4b70b562bd200b01919a6a89545be9", + "zh:3e49d86b508e641ba122d1b0af24cdc4d8ffa2ec1b30022436fb1d7c6ba696ea", + "zh:40be623e116708bdcb0fac32989db43720f031c5fe9a4dc63395078185d24403", + "zh:44fc0ac3bc39e289b67f9dde7ee9fef29eb8192197e5e68fee69098573021722", + "zh:957aa451573bcde5d57f6f8338ea3139010c7f61fefe8f6a140a8c267f056511", + "zh:c55fd85b7e8acaac17e30670ac3574b88b3530820dd004bcd2a5daa8624a46e9", + "zh:c743f06843a1f5ecde2b8ef639f4d3db654a334ef248dee57261c719ea843f3a", + "zh:c93cc71c64b838d89522ac5fb60f68e0e1e7f2fc39db6b0ead7afd78795e79ed", + "zh:eda1163c2266905adc54bc78cc3e7b606a164fbc6b59be607db933b302015ccd", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", - "zh:f688b9ec761721e401f6859c19c083e3be20a650426f4747cd359cdc079d212a", ] } diff --git a/examples/basic/main.tf b/examples/basic/main.tf index d53ab5e..93f80be 100644 --- a/examples/basic/main.tf +++ b/examples/basic/main.tf @@ -2,9 +2,6 @@ module "addon_installation_disabled" { source = "../../" enabled = false - - cluster_identity_oidc_issuer = module.eks_cluster.eks_cluster_identity_oidc_issuer - cluster_identity_oidc_issuer_arn = module.eks_cluster.eks_cluster_identity_oidc_issuer_arn } module "addon_installation_helm" { @@ -14,9 +11,6 @@ module "addon_installation_helm" { argo_enabled = false argo_helm_enabled = false - cluster_identity_oidc_issuer = module.eks_cluster.eks_cluster_identity_oidc_issuer - cluster_identity_oidc_issuer_arn = module.eks_cluster.eks_cluster_identity_oidc_issuer_arn - values = yamlencode({ # insert sample values here }) @@ -30,9 +24,6 @@ module "addon_installation_argo_kubernetes" { argo_enabled = true argo_helm_enabled = false - cluster_identity_oidc_issuer = module.eks_cluster.eks_cluster_identity_oidc_issuer - cluster_identity_oidc_issuer_arn = module.eks_cluster.eks_cluster_identity_oidc_issuer_arn - values = yamlencode({ # insert sample values here }) @@ -50,9 +41,6 @@ module "addon_installation_argo_helm" { argo_enabled = true argo_helm_enabled = true - cluster_identity_oidc_issuer = module.eks_cluster.eks_cluster_identity_oidc_issuer - cluster_identity_oidc_issuer_arn = module.eks_cluster.eks_cluster_identity_oidc_issuer_arn - values = yamlencode({ # insert sample values here }) diff --git a/examples/basic/versions.tf b/examples/basic/versions.tf index ccd47b8..f77a76d 100644 --- a/examples/basic/versions.tf +++ b/examples/basic/versions.tf @@ -1,18 +1,18 @@ terraform { - required_version = ">= 1.5.0" + required_version = ">= 1.5" required_providers { aws = { source = "hashicorp/aws" - version = "~> 5" + version = ">= 5" } kubernetes = { source = "hashicorp/kubernetes" - version = ">= 2.20.0" + version = ">= 2.20" } helm = { source = "hashicorp/helm" - version = ">= 2.6.0" + version = ">= 2.6" } } } diff --git a/main.tf b/main.tf index 14fce1a..e6040ea 100644 --- a/main.tf +++ b/main.tf @@ -11,56 +11,91 @@ locals { name = "node-local-dns" namespace = "kube-system" - helm_chart_version = "2.2.0" + helm_chart_version = "2.1.0" helm_repo_url = "https://lablabs.github.io/k8s-nodelocaldns-helm" } - addon_irsa = { - (local.addon.name) = {} - } - addon_values = yamlencode({ - zones = { - ".:53" = { - plugins = { - cache = { - denial = { # disable negative caching - size = 0 - ttl = 1 + podAnnotations = { + "checksum/configmaps" = "" # when a ConfigMap is updated a new instance of the DaemonSet is created + } + config = { + zones = { + ".:53" = { + plugins = { + log = { + classes = "error" + } + cache = { + denial = { # disable negative caching + size = 0 + ttl = 1 + } + } + forward = { + force_tcp = true + } + health = { + port = 8080 } - } - forward = { - force_tcp = true } } - } - "ip6.arpa:53" = { - plugins = { - log = { - classes = "error" - } - forward = { - force_tcp = true + "ip6.arpa:53" = { + plugins = { + log = { + classes = "error" + } + forward = { + force_tcp = true + } + health = { + port = 8081 + } } } - } - "in-addr.arpa:53" = { - plugins = { - log = { - classes = "error" - } - forward = { - force_tcp = true + "in-addr.arpa:53" = { + plugins = { + log = { + classes = "error" + } + forward = { + force_tcp = true + } + health = { + port = 8082 + } } } } } - serviceAccount = { - create = module.addon-irsa[local.addon.name].service_account_create - name = module.addon-irsa[local.addon.name].service_account_name - annotations = module.addon-irsa[local.addon.name].irsa_role_enabled ? { - "eks.amazonaws.com/role-arn" = module.addon-irsa[local.addon.name].iam_role_attributes.arn - } : tomap({}) + }) + + # CUSTOM config: Prometheus port is not using SO_REUSEPORT so additional instance can't bind to the same port + addon_metrics_values = yamlencode({ + metrics = { + port = one(random_integer.metrics_port[*].result) } }) + + addon_depends_on = [] +} + +resource "random_pet" "release_name_suffix" { + count = var.enabled ? 1 : 0 + + keepers = { + version = coalesce(var.helm_chart_version, local.addon.helm_chart_version) + values = yamlencode([local.addon_values, var.values]) + } +} + +resource "random_integer" "metrics_port" { + count = var.enabled ? 1 : 0 + + min = 1025 + max = 32667 + + keepers = { + values = one(random_pet.release_name_suffix[*].id) + } } diff --git a/migrations.tf b/migrations.tf index d471008..54c5b26 100644 --- a/migrations.tf +++ b/migrations.tf @@ -12,13 +12,3 @@ moved { from = helm_release.argo_application to = module.addon.helm_release.argo_application } - -moved { - from = aws_iam_role.this - to = module.addon-irsa["node-local-dns"].aws_iam_role.this -} - -moved { - from = aws_iam_role_policy_attachment.this_additional - to = module.addon-irsa["node-local-dns"].aws_iam_role_policy_attachment.this_additional -} diff --git a/modules/addon/.terraform.lock.hcl b/modules/addon/.terraform.lock.hcl new file mode 100644 index 0000000..0eb6e91 --- /dev/null +++ b/modules/addon/.terraform.lock.hcl @@ -0,0 +1,95 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/cloudposse/utils" { + version = "1.30.0" + constraints = "~> 1.0" + hashes = [ + "h1:KmKu9rXFQIAvaXbwKYLR4QSUm5UBoh0wpftRKkG34Co=", + "h1:be9bmaq5PJ1US+WtgVjhdUPU0eiWhQNYAIb81EI+/Dw=", + "h1:hZeJ9YpYk/0lI77My1Y3pBapD600B40cHwEkKA2u7CQ=", + "zh:093e70d2dc0def5f98b7175cf2a8da533ded1dbd1d3c9fb022a34d57e829e5e8", + "zh:1a7dba74c056e604d76a394ce608e139d8267d8fa15f6a1cd9777fb2a91b6741", + "zh:2b1d379d6bfa98505ef6aa641b336b55116310916b55f9443a0584411f66785b", + "zh:410d25642ce366a91448266b90c0f8cdcbb34f51d65d14ff24678fbc50850711", + "zh:6032e69a3795794c483b1894ae206ebd854904dd160d20fbc2f69227ad322598", + "zh:79b55690195641e52590a3bc7f66944e3855d388938f5cbc39a0cb000cdbeccf", + "zh:7d0754656079250e49c530bffa5d0339433372e36998eb1d9193eea3030392fa", + "zh:8a78560a872e3470c3afefb08c9739a45952de39097c2a244ce31453caf7d37d", + "zh:a2c508d780364004969ca1c080118af2292cbb0fb46a4b67d54dcc100a8132bc", + "zh:a528d7a7195427b976e353c41784300a51e9e34a922c035aa9596f3072c190d2", + "zh:aa60b3cc9b01711c906dbb64f929a3c22371365fc6f74878fa460cb5a0bf7c66", + "zh:c0fedc527db8505ebb796d8b2cd70af151f3fef7daeb09fff6d020bedc5d1154", + "zh:cd37b6d417187073a11db0592b4edd7098b14ea8882491cd7d4795a169aea98e", + "zh:e9895b026770104de264d4a80c227864460169dfc697132edd6089e5b1843880", + ] +} + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.100.0" + constraints = "~> 5.0" + hashes = [ + "h1:Ijt7pOlB7Tr7maGQIqtsLFbl7pSMIj06TVdkoSBcYOw=", + "h1:edXOJWE4ORX8Fm+dpVpICzMZJat4AX0VRCAy/xkcOc0=", + "h1:hd45qFU5cFuJMpFGdUniU9mVIr5LYVWP1uMeunBpYYs=", + "zh:054b8dd49f0549c9a7cc27d159e45327b7b65cf404da5e5a20da154b90b8a644", + "zh:0b97bf8d5e03d15d83cc40b0530a1f84b459354939ba6f135a0086c20ebbe6b2", + "zh:1589a2266af699cbd5d80737a0fe02e54ec9cf2ca54e7e00ac51c7359056f274", + "zh:6330766f1d85f01ae6ea90d1b214b8b74cc8c1badc4696b165b36ddd4cc15f7b", + "zh:7c8c2e30d8e55291b86fcb64bdf6c25489d538688545eb48fd74ad622e5d3862", + "zh:99b1003bd9bd32ee323544da897148f46a527f622dc3971af63ea3e251596342", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9f8b909d3ec50ade83c8062290378b1ec553edef6a447c56dadc01a99f4eaa93", + "zh:aaef921ff9aabaf8b1869a86d692ebd24fbd4e12c21205034bb679b9caf883a2", + "zh:ac882313207aba00dd5a76dbd572a0ddc818bb9cbf5c9d61b28fe30efaec951e", + "zh:bb64e8aff37becab373a1a0cc1080990785304141af42ed6aa3dd4913b000421", + "zh:dfe495f6621df5540d9c92ad40b8067376350b005c637ea6efac5dc15028add4", + "zh:f0ddf0eaf052766cfe09dea8200a946519f653c384ab4336e2a4a64fdd6310e9", + "zh:f1b7e684f4c7ae1eed272b6de7d2049bb87a0275cb04dbb7cda6636f600699c9", + "zh:ff461571e3f233699bf690db319dfe46aec75e58726636a0d97dd9ac6e32fb70", + ] +} + +provider "registry.terraform.io/hashicorp/helm" { + version = "2.17.0" + constraints = "~> 2.6" + hashes = [ + "h1:0LSHBFqJvHTzQesUwagpDLsrzVliY+t2c26nDJizHFM=", + "h1:K5FEjxvDnxb1JF1kG1xr8J3pNGxoaR3Z0IBG9Csm/Is=", + "h1:kQMkcPVvHOguOqnxoEU2sm1ND9vCHiT8TvZ2x6v/Rsw=", + "zh:06fb4e9932f0afc1904d2279e6e99353c2ddac0d765305ce90519af410706bd4", + "zh:104eccfc781fc868da3c7fec4385ad14ed183eb985c96331a1a937ac79c2d1a7", + "zh:129345c82359837bb3f0070ce4891ec232697052f7d5ccf61d43d818912cf5f3", + "zh:3956187ec239f4045975b35e8c30741f701aa494c386aaa04ebabffe7749f81c", + "zh:66a9686d92a6b3ec43de3ca3fde60ef3d89fb76259ed3313ca4eb9bb8c13b7dd", + "zh:88644260090aa621e7e8083585c468c8dd5e09a3c01a432fb05da5c4623af940", + "zh:a248f650d174a883b32c5b94f9e725f4057e623b00f171936dcdcc840fad0b3e", + "zh:aa498c1f1ab93be5c8fbf6d48af51dc6ef0f10b2ea88d67bcb9f02d1d80d3930", + "zh:bf01e0f2ec2468c53596e027d376532a2d30feb72b0b5b810334d043109ae32f", + "zh:c46fa84cc8388e5ca87eb575a534ebcf68819c5a5724142998b487cb11246654", + "zh:d0c0f15ffc115c0965cbfe5c81f18c2e114113e7a1e6829f6bfd879ce5744fbb", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "2.38.0" + constraints = "~> 2.20" + hashes = [ + "h1:5CkveFo5ynsLdzKk+Kv+r7+U9rMrNjfZPT3a0N/fhgE=", + "h1:7nJdsd1RMPBtOjDXidB37+KSDN5VcOWkbkow69qJVGc=", + "h1:soK8Lt0SZ6dB+HsypFRDzuX/npqlMU6M0fvyaR1yW0k=", + "zh:0af928d776eb269b192dc0ea0f8a3f0f5ec117224cd644bdacdc682300f84ba0", + "zh:1be998e67206f7cfc4ffe77c01a09ac91ce725de0abaec9030b22c0a832af44f", + "zh:326803fe5946023687d603f6f1bab24de7af3d426b01d20e51d4e6fbe4e7ec1b", + "zh:4a99ec8d91193af961de1abb1f824be73df07489301d62e6141a656b3ebfff12", + "zh:5136e51765d6a0b9e4dbcc3b38821e9736bd2136cf15e9aac11668f22db117d2", + "zh:63fab47349852d7802fb032e4f2b6a101ee1ce34b62557a9ad0f0f0f5b6ecfdc", + "zh:924fb0257e2d03e03e2bfe9c7b99aa73c195b1f19412ca09960001bee3c50d15", + "zh:b63a0be5e233f8f6727c56bed3b61eb9456ca7a8bb29539fba0837f1badf1396", + "zh:d39861aa21077f1bc899bc53e7233262e530ba8a3a2d737449b100daeb303e4d", + "zh:de0805e10ebe4c83ce3b728a67f6b0f9d18be32b25146aa89116634df5145ad4", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:faf23e45f0090eef8ba28a8aac7ec5d4fdf11a36c40a8d286304567d71c1e7db", + ] +} diff --git a/modules/addon/argo-helm.tf b/modules/addon/argo-helm.tf new file mode 100644 index 0000000..b339b0b --- /dev/null +++ b/modules/addon/argo-helm.tf @@ -0,0 +1,170 @@ +locals { + helm_argo_application_enabled = var.enabled == true && var.argo_enabled == true && var.argo_helm_enabled == true + helm_argo_application_wait_enabled = local.helm_argo_application_enabled && try(length(keys(var.argo_kubernetes_manifest_wait_fields)) > 0, false) + helm_argo_application_values = compact([ + one(data.utils_deep_merge_yaml.argo_helm_values[*].output), + var.argo_helm_values + ]) +} + +data "utils_deep_merge_yaml" "argo_helm_values" { + count = local.helm_argo_application_enabled ? 1 : 0 + + input = compact([ + yamlencode({ + apiVersion = var.argo_apiversion + }), + yamlencode({ + spec = merge( + local.argo_application_spec, + var.argo_spec_override + ) + }), + yamlencode({ + spec = var.argo_spec + }), + yamlencode( + local.argo_application_metadata + ) + ]) +} + +resource "helm_release" "argo_application" { + count = local.helm_argo_application_enabled ? 1 : 0 + + chart = "${path.module}/helm/argocd-application" + name = local.argo_application_name + namespace = var.argo_namespace + + max_history = var.helm_release_max_history + + values = local.helm_argo_application_values + + lifecycle { + create_before_destroy = true # CUSTOM config: We need to spawn a new ArgoCD Application before destroying the old one to avoid downtime + } +} + +resource "kubernetes_role" "helm_argo_application_wait" { + count = local.helm_argo_application_wait_enabled ? 1 : 0 + + metadata { + name = "${local.argo_application_name}-argo-application-wait" + namespace = var.argo_namespace + labels = local.argo_application_metadata.labels + annotations = local.argo_application_metadata.annotations + } + + rule { + api_groups = ["argoproj.io"] + resources = ["applications"] + verbs = ["get", "list", "watch"] + } +} + +resource "kubernetes_role_binding" "helm_argo_application_wait" { + count = local.helm_argo_application_wait_enabled ? 1 : 0 + + metadata { + name = "${local.argo_application_name}-argo-application-wait" + namespace = var.argo_namespace + labels = local.argo_application_metadata.labels + annotations = local.argo_application_metadata.annotations + } + + role_ref { + api_group = "rbac.authorization.k8s.io" + kind = "Role" + name = one(kubernetes_role.helm_argo_application_wait[*].metadata[0].name) + } + + subject { + kind = "ServiceAccount" + name = one(kubernetes_service_account.helm_argo_application_wait[*].metadata[0].name) + namespace = one(kubernetes_service_account.helm_argo_application_wait[*].metadata[0].namespace) + } +} + +resource "kubernetes_service_account" "helm_argo_application_wait" { + count = local.helm_argo_application_wait_enabled ? 1 : 0 + + metadata { + name = "${local.argo_application_name}-argo-application-wait" + namespace = var.argo_namespace + labels = local.argo_application_metadata.labels + annotations = local.argo_application_metadata.annotations + } +} + +resource "kubernetes_job" "helm_argo_application_wait" { + count = local.helm_argo_application_wait_enabled ? 1 : 0 + + metadata { + generate_name = "${local.argo_application_name}-argo-application-wait-" + namespace = var.argo_namespace + labels = local.argo_application_metadata.labels + annotations = local.argo_application_metadata.annotations + } + + spec { + template { + metadata { + labels = local.argo_application_metadata.labels + annotations = local.argo_application_metadata.annotations + } + + spec { + service_account_name = one(kubernetes_service_account.helm_argo_application_wait[*].metadata[0].name) + + dynamic "container" { + for_each = var.argo_kubernetes_manifest_wait_fields + + content { + name = "${lower(replace(container.key, ".", "-"))}-${md5(jsonencode(local.helm_argo_application_values))}" # md5 suffix is a workaround for https://github.com/hashicorp/terraform-provider-kubernetes/issues/1325 + image = "registry.k8s.io/kubectl:v${trim(var.argo_helm_wait_kubectl_version, "v")}" + # Waits for ArgoCD Application to be "Healthy", see https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#wait + # i.e. kubectl wait --for=jsonpath={.status.sync.status}=Healthy application.argoproj.io <$addon-name> + args = [ + "wait", + "--namespace=${var.argo_namespace}", + "--for=jsonpath={.${container.key}}=${container.value}", + "--timeout=${var.argo_helm_wait_timeout}", + "--v=1", # https://kubernetes.io/docs/reference/kubectl/quick-reference/#kubectl-output-verbosity-and-debugging + "application.argoproj.io", + local.argo_application_name + ] + } + } + + node_selector = var.argo_helm_wait_node_selector + + dynamic "toleration" { + for_each = var.argo_helm_wait_tolerations + + content { + key = try(toleration.value.key, null) + operator = try(toleration.value.operator, null) + value = try(toleration.value.value, null) + effect = try(toleration.value.effect, null) + } + } + + # ArgoCD Application status fields might not be available immediately after creation + restart_policy = "OnFailure" + } + } + + backoff_limit = var.argo_helm_wait_backoff_limit + } + + wait_for_completion = true + + timeouts { + create = var.argo_helm_wait_timeout + update = var.argo_helm_wait_timeout + } + + depends_on = [ + helm_release.argo_application + ] +} diff --git a/modules/addon/argo.tf b/modules/addon/argo.tf new file mode 100644 index 0000000..82dee1f --- /dev/null +++ b/modules/addon/argo.tf @@ -0,0 +1,104 @@ +locals { + argo_application_enabled = var.enabled == true && var.argo_enabled == true && var.argo_helm_enabled == false ? 1 : 0 + + argo_application_source_helm_enabled = var.argo_source_type == "helm" ? true : false + argo_application_source_kustomize_enabled = var.argo_source_type == "kustomize" ? true : false + argo_application_source_directory_enabled = var.argo_source_type == "directory" ? true : false + argo_application_source_helm_directory_enabled = var.argo_source_type == "helm-directory" ? true : false + argo_application_source_helm_based = local.argo_application_source_helm_enabled || local.argo_application_source_helm_directory_enabled + + argo_application_name = local.argo_application_source_helm_based ? var.helm_release_name : var.argo_name + argo_application_source = { + repoURL = local.argo_application_source_helm_based ? var.helm_repo_url : var.argo_source_repo_url + targetRevision = local.argo_application_source_helm_based ? var.helm_chart_version : var.argo_source_target_revision + + # Helm source + chart = local.argo_application_source_helm_enabled ? var.helm_chart_name : null + helm = local.argo_application_source_helm_based ? merge( + { + releaseName = var.helm_release_name + skipCrds = var.helm_skip_crds + values = var.values + }, + length(var.settings) > 0 ? { + parameters = [for k, v in var.settings : tomap({ forceString = true, name = k, value = v })] + } : {} + ) : null + + # Kustomize, Helm directory or directory source + path = !local.argo_application_source_helm_enabled ? var.argo_source_path : null + kustomize = local.argo_application_source_kustomize_enabled ? length(var.settings) > 0 ? var.settings : null : null + directory = local.argo_application_source_directory_enabled ? length(var.settings) > 0 ? var.settings : null : null + } + argo_application_source_normalized = { + for k, v in local.argo_application_source : k => v if v != null # remove null values to avoid empty keys confusing ArgoCD source type + } + + argo_application_metadata = { + labels = try(var.argo_metadata.labels, {}), + annotations = try(var.argo_metadata.annotations, {}), + finalizers = try(var.argo_metadata.finalizers, []) + } + argo_application_spec = { + project = var.argo_project + source = local.argo_application_source_normalized + destination = { + server = var.argo_destination_server + namespace = var.namespace + } + syncPolicy = var.argo_sync_policy + info = var.argo_info + } +} + +data "utils_deep_merge_yaml" "argo_application_spec" { + count = local.argo_application_enabled + + input = compact([ + yamlencode( + merge( + local.argo_application_spec, + var.argo_spec_override + ) + ), + yamlencode(var.argo_spec), + ]) +} + +resource "kubernetes_manifest" "this" { + count = local.argo_application_enabled + + manifest = merge( + # the whole manifest cannot be deep merged (defers result to apply phase) due to kuberenetes_manifest CRD validation is happenning during the plan phase + { + apiVersion = var.argo_apiversion + kind = "Application" + metadata = merge( + local.argo_application_metadata, + { + name = local.argo_application_name + namespace = var.argo_namespace + }, + ) + spec = yamldecode(data.utils_deep_merge_yaml.argo_application_spec[0].output) + }, + length(var.argo_operation) > 0 ? { + operation = var.argo_operation + } : {} + ) + + computed_fields = var.argo_kubernetes_manifest_computed_fields + + field_manager { + name = var.argo_kubernetes_manifest_field_manager_name + force_conflicts = var.argo_kubernetes_manifest_field_manager_force_conflicts + } + + wait { + fields = var.argo_kubernetes_manifest_wait_fields + } + + lifecycle { + create_before_destroy = true # CUSTOM config: We need to spawn a new ArgoCD Application before destroying the old one to avoid downtime + } +} diff --git a/modules/addon/helm.tf b/modules/addon/helm.tf new file mode 100644 index 0000000..5f70d43 --- /dev/null +++ b/modules/addon/helm.tf @@ -0,0 +1,71 @@ +resource "helm_release" "this" { + count = var.enabled == true && var.helm_enabled == true && var.argo_enabled == false ? 1 : 0 + + chart = var.helm_chart_name + create_namespace = var.helm_create_namespace + namespace = var.namespace + name = var.helm_release_name + version = var.helm_chart_version + repository = var.helm_repo_url + + repository_key_file = var.helm_repo_key_file + repository_cert_file = var.helm_repo_cert_file + repository_ca_file = var.helm_repo_ca_file + repository_username = var.helm_repo_username + repository_password = var.helm_repo_password + devel = var.helm_devel + verify = var.helm_package_verify + keyring = var.helm_keyring + timeout = var.helm_timeout + disable_webhooks = var.helm_disable_webhooks + reset_values = var.helm_reset_values + reuse_values = var.helm_reuse_values + force_update = var.helm_force_update + recreate_pods = var.helm_recreate_pods + cleanup_on_fail = var.helm_cleanup_on_fail + max_history = var.helm_release_max_history + atomic = var.helm_atomic + wait = var.helm_wait + wait_for_jobs = var.helm_wait_for_jobs + skip_crds = var.helm_skip_crds + render_subchart_notes = var.helm_render_subchart_notes + disable_openapi_validation = var.helm_disable_openapi_validation + dependency_update = var.helm_dependency_update + replace = var.helm_replace + description = var.helm_description + lint = var.helm_lint + + values = compact([ + var.values + ]) + + dynamic "set" { + for_each = var.settings + + content { + name = set.key + value = set.value + } + } + + dynamic "set_sensitive" { + for_each = var.helm_set_sensitive + + content { + name = set_sensitive.key + value = set_sensitive.value + } + } + + dynamic "postrender" { + for_each = var.helm_postrender + + content { + binary_path = postrender.value + } + } + + lifecycle { + create_before_destroy = true # CUSTOM config: We need to spawn a new Helm release before destroying the old one to avoid downtime + } +} diff --git a/modules/addon/helm/argocd-application/.helmignore b/modules/addon/helm/argocd-application/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/modules/addon/helm/argocd-application/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/modules/addon/helm/argocd-application/Chart.yaml b/modules/addon/helm/argocd-application/Chart.yaml new file mode 100644 index 0000000..b450f61 --- /dev/null +++ b/modules/addon/helm/argocd-application/Chart.yaml @@ -0,0 +1,18 @@ +apiVersion: v2 +name: argocd-application +description: Helm wrapper for deploying ArgoCD application object + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 diff --git a/modules/addon/helm/argocd-application/templates/_helpers.tpl b/modules/addon/helm/argocd-application/templates/_helpers.tpl new file mode 100644 index 0000000..6dac3de --- /dev/null +++ b/modules/addon/helm/argocd-application/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "argocd_application.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "argocd_application.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" .Release.Name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "argocd_application.chart" -}} +{{- printf "%s" .Chart.Name | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "argocd_application.labels" -}} +helm.sh/chart: {{ include "argocd_application.chart" . }} +{{ include "argocd_application.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "argocd_application.selectorLabels" -}} +app.kubernetes.io/name: {{ include "argocd_application.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/modules/addon/helm/argocd-application/templates/application.yaml b/modules/addon/helm/argocd-application/templates/application.yaml new file mode 100644 index 0000000..3117c37 --- /dev/null +++ b/modules/addon/helm/argocd-application/templates/application.yaml @@ -0,0 +1,19 @@ +apiVersion: {{ .Values.apiVersion }} +kind: Application +metadata: + name: {{ include "argocd_application.fullname" . }} + labels: + {{- include "argocd_application.labels" . | nindent 4 }} + {{- if .Values.labels }} + {{ toYaml .Values.labels | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.annotations }} + {{ toYaml .Values.annotations | indent 4 }} + {{- end }} + finalizers: + {{- if .Values.finalizers }} + {{ toYaml .Values.finalizers | indent 4 }} + {{- end }} +spec: + {{ toYaml .Values.spec | nindent 2 }} diff --git a/modules/addon/helm/argocd-application/values.yaml b/modules/addon/helm/argocd-application/values.yaml new file mode 100644 index 0000000..552d6da --- /dev/null +++ b/modules/addon/helm/argocd-application/values.yaml @@ -0,0 +1,2 @@ +nameOverride: "" +fullnameOverride: "" diff --git a/modules/addon/outputs.tf b/modules/addon/outputs.tf new file mode 100644 index 0000000..4315b9e --- /dev/null +++ b/modules/addon/outputs.tf @@ -0,0 +1,14 @@ +output "helm_release_metadata" { + description = "Helm release attributes" + value = try(helm_release.this[0].metadata, {}) +} + +output "helm_release_application_metadata" { + description = "ArgoCD Application Helm release attributes" + value = try(helm_release.argo_application[0].metadata, {}) +} + +output "kubernetes_application_attributes" { + description = "ArgoCD Kubernetes manifest attributes" + value = try(kubernetes_manifest.this[0], {}) +} diff --git a/modules/addon/validations.tf b/modules/addon/validations.tf new file mode 100644 index 0000000..f940859 --- /dev/null +++ b/modules/addon/validations.tf @@ -0,0 +1,36 @@ +resource "terraform_data" "validations" { + lifecycle { + precondition { + condition = !local.argo_application_source_helm_enabled || ( + var.helm_repo_url != "" + && var.helm_chart_name != "" + && var.helm_chart_version != "" + && var.helm_release_name != "" + ) + error_message = "The `helm_repo_url`, `helm_chart_name`, `helm_chart_version`, and `helm_release_name` variables must be set when argo_source_type is set to `helm`." + } + + precondition { + condition = ( + !local.argo_application_source_kustomize_enabled + && !local.argo_application_source_directory_enabled + ) || ( + var.argo_source_repo_url != "" + && var.argo_source_path != "" + && var.argo_source_target_revision != "" + && var.argo_name != "" + ) + error_message = "The `argo_source_repo_url`, `argo_source_path`, `argo_source_target_revision` and `argo_name` variables must be set when argo_source_type is set to `kustomize` or `directory`." + } + + precondition { + condition = !local.argo_application_source_helm_directory_enabled || ( + var.helm_repo_url != "" + && var.argo_source_path != "" + && var.helm_chart_version != "" + && var.helm_release_name != "" + ) + error_message = "The `helm_repo_url`, `argo_source_path`, `helm_chart_version`, and `helm_release_name` variables must be set when argo_source_type is set to `helm-directory`." + } + } +} diff --git a/modules/addon/variables.tf b/modules/addon/variables.tf new file mode 100644 index 0000000..6be0291 --- /dev/null +++ b/modules/addon/variables.tf @@ -0,0 +1,458 @@ +variable "enabled" { + type = bool + default = true + description = "Set to false to prevent the module from creating any resources." + nullable = false +} + +variable "helm_enabled" { + type = bool + default = true + description = "Set to false to prevent installation of the module via Helm release." + nullable = false +} + +variable "helm_chart_name" { + type = string + default = "" + description = "Helm chart name to be installed. Required if `argo_source_type` is set to `helm`." + nullable = false +} + +variable "helm_chart_version" { + type = string + default = "" + description = "Version of the Helm chart. Required if `argo_source_type` is set to `helm`." + nullable = false +} + +variable "helm_release_name" { + type = string + default = "" + description = "Helm release name. Required if `argo_source_type` is set to `helm`." + nullable = false +} + +variable "helm_repo_url" { + type = string + default = "" + description = "Helm repository. Required if `argo_source_type` is set to `helm`." + nullable = false +} + +variable "helm_create_namespace" { + type = bool + default = true + description = "Create the Namespace if it does not yet exist." + nullable = false +} + +variable "namespace" { + type = string + description = "The Kubernetes Namespace in which the Helm chart will be installed (required)." + nullable = false +} + +variable "settings" { + type = map(any) + default = {} + description = "Additional Helm sets which will be passed to the Helm chart values or Kustomize or directory configuration which will be passed to ArgoCD Application source." + nullable = false +} + +variable "values" { + type = string + default = "" + description = "Additional YAML encoded values which will be passed to the Helm chart." + nullable = false +} + +variable "argo_name" { + type = string + default = "" + description = "Name of the ArgoCD Application. Required if `argo_source_type` is set to `kustomize` or `directory`. If `argo_source_type` is set to `helm`, ArgoCD Application name will equal `helm_release_name`." + nullable = false +} + +variable "argo_namespace" { + type = string + default = "argo" + description = "Namespace to deploy ArgoCD Application to." + nullable = false +} + +variable "argo_enabled" { + type = bool + default = false + description = "If set to `true`, the module will be deployed as ArgoCD Application, otherwise it will be deployed as a Helm release." + nullable = false +} + +variable "argo_helm_enabled" { + type = bool + default = 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." + nullable = false +} + +variable "argo_helm_wait_timeout" { + type = string + default = "10m" + description = "Timeout for ArgoCD Application Helm release wait job." + nullable = false +} + +variable "argo_helm_wait_node_selector" { + type = map(string) + default = {} + description = "Node selector for ArgoCD Application Helm release wait job." + nullable = false +} + +variable "argo_helm_wait_tolerations" { + type = list(any) + default = [] + description = "Tolerations for ArgoCD Application Helm release wait job." + nullable = false +} + +variable "argo_helm_wait_backoff_limit" { + type = number + default = 6 + description = "Backoff limit for ArgoCD Application Helm release wait job." + nullable = false +} + +variable "argo_helm_wait_kubectl_version" { + type = string + default = "1.33.3" # renovate: datasource=github-releases depName=kubernetes/kubernetes + description = "Version of kubectl to use for ArgoCD Application wait job." + nullable = false +} + +variable "argo_source_type" { + type = string + default = "helm" + description = "Source type for ArgoCD Application. Can be either `helm`, `kustomize`, `directory` or `helm-directory`." + nullable = false + + validation { + condition = contains(["helm", "kustomize", "directory", "helm-directory"], var.argo_source_type) + error_message = "Source type must be either `helm`, `kustomize`, `directory` or `helm-directory`." + } +} + +variable "argo_source_repo_url" { + type = string + default = "" + description = "ArgoCD Application source repo URL. Required if `argo_source_type` is set to `kustomize` or `directory`." + nullable = false +} + +variable "argo_source_target_revision" { + type = string + default = "" + description = "ArgoCD Application source target revision. Required if `argo_source_type` is set to `kustomize` or `directory`." + nullable = false +} + +variable "argo_source_path" { + type = string + default = "" + description = "ArgoCD Application source path. Required if `argo_source_type` is set to `kustomize` or `directory`." + nullable = false +} + +variable "argo_destination_server" { + type = string + default = "https://kubernetes.default.svc" + description = "Destination server for ArgoCD Application." + nullable = false +} + +variable "argo_project" { + type = string + default = "default" + description = "ArgoCD Application project." + nullable = false +} + +variable "argo_info" { + type = list(any) + default = [{ name = "terraform", value = "true" }] + description = "ArgoCD Application manifest info parameter." + nullable = false +} + +variable "argo_sync_policy" { + type = any + default = {} + description = "ArgoCD Application manifest syncPolicy parameter." + nullable = false +} + +variable "argo_metadata" { + type = any + default = { finalizers = ["resources-finalizer.argocd.argoproj.io"] } + description = "ArgoCD Application metadata configuration. Override or create additional metadata parameters." + nullable = false +} + +variable "argo_apiversion" { + type = string + default = "argoproj.io/v1alpha1" + description = "ArgoCD Application apiVersion." + nullable = false +} + +variable "argo_spec" { + type = any + default = {} + description = "ArgoCD Application spec configuration. Configuration is extended by deep merging with the default spec parameters." + nullable = false +} + +variable "argo_spec_override" { + type = any + default = {} + description = "ArgoCD Application spec configuration. Configuration is overriden by merging natively with the default spec parameters." + nullable = false +} + +variable "argo_operation" { + type = any + default = {} + description = "ArgoCD Application manifest operation parameter." + nullable = false +} + +variable "argo_helm_values" { + type = string + default = "" + description = "Value overrides to use when deploying ArgoCD Application object with Helm." + nullable = false +} + +variable "argo_kubernetes_manifest_computed_fields" { + type = list(string) + default = ["metadata.labels", "metadata.annotations", "metadata.finalizers"] + description = "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." + nullable = false +} + +variable "argo_kubernetes_manifest_field_manager_name" { + type = string + default = "Terraform" + description = "The name of the field manager to use when applying the Kubernetes manifest resource." + nullable = false +} + +variable "argo_kubernetes_manifest_field_manager_force_conflicts" { + type = bool + default = false + description = "Forcibly override any field manager conflicts when applying the kubernetes manifest resource." + nullable = false +} + +variable "argo_kubernetes_manifest_wait_fields" { + type = map(string) + default = {} + 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." + nullable = false +} + +variable "helm_repo_key_file" { + type = string + default = "" + description = "Helm repositories cert key file." + nullable = false +} + +variable "helm_repo_cert_file" { + type = string + default = "" + description = "Helm repositories cert file." + nullable = false +} + +variable "helm_repo_ca_file" { + type = string + default = "" + description = "Helm repositories CA cert file." + nullable = false +} + +variable "helm_repo_username" { + type = string + default = "" + description = "Username for HTTP basic authentication against the Helm repository." + nullable = false +} + +variable "helm_repo_password" { + type = string + default = "" + description = "Password for HTTP basic authentication against the Helm repository." + nullable = false +} + +variable "helm_devel" { + type = bool + default = false + description = "Use Helm chart development versions, too. Equivalent to version '>0.0.0-0'. If version is set, this is ignored." + nullable = false +} + +variable "helm_package_verify" { + type = bool + default = false + description = "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." + nullable = false +} + +variable "helm_keyring" { + type = string + default = "~/.gnupg/pubring.gpg" + description = "Location of public keys used for verification. Used only if `helm_package_verify` is `true`." + nullable = false +} + +variable "helm_timeout" { + type = number + default = 300 + description = "Time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)." + nullable = false +} + +variable "helm_disable_webhooks" { + type = bool + default = false + description = "Prevent Helm chart hooks from running." + nullable = false +} + +variable "helm_reset_values" { + type = bool + default = false + description = "When upgrading, reset the values to the ones built into the Helm chart." + nullable = false +} + +variable "helm_reuse_values" { + type = bool + default = 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." + nullable = false +} + +variable "helm_force_update" { + type = bool + default = false + description = "Force Helm resource update through delete/recreate if needed." + nullable = false +} + +variable "helm_recreate_pods" { + type = bool + default = false + description = "Perform pods restart during Helm upgrade/rollback." + nullable = false +} + +variable "helm_cleanup_on_fail" { + type = bool + default = false + description = "Allow deletion of new resources created in this Helm upgrade when upgrade fails." + nullable = false +} + +variable "helm_release_max_history" { + type = number + default = 0 + description = "Maximum number of release versions stored per release." + nullable = false +} + +variable "helm_atomic" { + type = bool + default = false + description = "If set, installation process purges chart on fail. The wait flag will be set automatically if atomic is used." + nullable = false +} + +variable "helm_wait" { + type = bool + default = false + description = "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." + nullable = false +} + +variable "helm_wait_for_jobs" { + type = bool + default = false + description = "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." + nullable = false +} + +variable "helm_skip_crds" { + type = bool + default = false + description = "If set, no CRDs will be installed before Helm release." + nullable = false +} + +variable "helm_render_subchart_notes" { + type = bool + default = true + description = "If set, render Helm subchart notes along with the parent." + nullable = false +} + +variable "helm_disable_openapi_validation" { + type = bool + default = false + description = "If set, the installation process will not validate rendered Helm templates against the Kubernetes OpenAPI Schema." + nullable = false +} + +variable "helm_dependency_update" { + type = bool + default = false + description = "Runs Helm dependency update before installing the chart." + nullable = false +} + +variable "helm_replace" { + type = bool + default = false + description = "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." + nullable = false +} + +variable "helm_description" { + type = string + default = "" + description = "Set Helm release description attribute (visible in the history)." + nullable = false +} + +variable "helm_lint" { + type = bool + default = false + description = "Run the Helm chart linter during the plan." + nullable = false +} + +variable "helm_set_sensitive" { + type = map(any) + default = {} + description = "Value block with custom sensitive values to be merged with the values yaml that won't be exposed in the plan's diff." + nullable = false +} + +variable "helm_postrender" { + type = map(any) + default = {} + description = "Value block with a path to a binary file to run after Helm renders the manifest which can alter the manifest contents." + nullable = false +} diff --git a/modules/addon/versions.tf b/modules/addon/versions.tf new file mode 100644 index 0000000..033f46d --- /dev/null +++ b/modules/addon/versions.tf @@ -0,0 +1,22 @@ +terraform { + required_version = ">= 1.5" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = ">= 2.20" + } + helm = { + source = "hashicorp/helm" + version = ">= 2.6" + } + utils = { + source = "cloudposse/utils" + version = ">= 1" + } + } +} diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index fb17f43..0000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -python-hcl2==5.1.1 -Jinja2==3.1.6 diff --git a/scripts/sync-variables.py b/scripts/sync-variables.py deleted file mode 100755 index 6786b71..0000000 --- a/scripts/sync-variables.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/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 deleted file mode 100644 index 89cae66..0000000 --- a/variables-addon-irsa.tf +++ /dev/null @@ -1,163 +0,0 @@ -# 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. - -variable "cluster_identity_oidc_issuer" { - type = string - default = null - description = "The OIDC Identity issuer for the cluster (required for IRSA). Defaults to `\"\"`." -} - -variable "cluster_identity_oidc_issuer_arn" { - type = string - default = null - description = "The OIDC Identity issuer ARN for the cluster that can be used to associate IAM roles with a Service Account (required for IRSA). Defaults to `\"\"`." -} - -variable "rbac_create" { - type = bool - default = null - description = "Whether to create and use RBAC resources. Defaults to `true`." -} - -variable "service_account_create" { - type = bool - default = null - description = "Whether to create Service Account. Defaults to `true`." -} - -variable "service_account_name" { - type = string - default = null - description = "The Kubernetes Service Account name. Defaults to `\"\"`." -} - -variable "service_account_namespace" { - type = string - default = null - description = "The Kubernetes Service Account namespace. Defaults to `\"\"`." -} - -variable "irsa_role_create" { - type = bool - default = null - description = "Whether to create IRSA role and annotate Service Account. Defaults to `true`." -} - -variable "irsa_role_name_prefix" { - type = string - default = null - 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 `irsa_role_name_prefix`. Either `irsa_role_name` or `irsa_role_name_prefix` must be set. Defaults to `\"\"`." -} - -variable "irsa_policy_enabled" { - type = bool - default = null - description = "Whether to create IAM policy specified by `irsa_policy`. Mutually exclusive with `irsa_assume_role_enabled`. Defaults to `false`." -} - -variable "irsa_policy" { - type = string - default = null - 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" { - type = bool - default = null - description = "Whether IRSA is allowed to assume role defined by `irsa_assume_role_arn`. Mutually exclusive with `irsa_policy_enabled`. Defaults to `false`." -} - -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`. 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 `null`." -} - -variable "irsa_additional_policies" { - type = map(string) - default = null - description = "Map of the additional policies to be attached to IRSA role. Where key is arbitrary id and value is policy ARN. Defaults to `{}`." -} - -variable "irsa_tags" { - type = map(string) - 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 `[]`." -} - -variable "cluster_name" { - type = string - default = null - description = "The name of the cluster (required for pod identity). Defaults to `\"\"`." -} - -variable "pod_identity_role_create" { - type = bool - default = null - description = "Whether to create pod identity role and annotate Service Account. Defaults to `false`." -} - -variable "pod_identity_role_name_prefix" { - type = string - default = null - description = "Pod identity role name prefix. Either `pod_identity_role_name_prefix` or `pod_identity_role_name` must be set. Defaults to `\"\"`." -} - -variable "pod_identity_role_name" { - type = string - default = null - description = "Pod identity role name. The value is prefixed by `pod_identity_role_name_prefix`. Either `pod_identity_role_name` or `pod_identity_role_name_prefix` must be set. Defaults to `\"\"`." -} - -variable "pod_identity_policy_enabled" { - type = bool - default = null - description = "Whether to create IAM policy specified by `pod_identity_policy`. Defaults to `false`." -} - -variable "pod_identity_policy" { - type = string - default = null - description = "AWS IAM policy JSON document to be attached to the pod identity role. Applied only if `pod_identity_policy_enabled` is `true`. Defaults to `\"\"`." -} - -variable "pod_identity_permissions_boundary" { - type = string - default = null - description = "ARN of the policy that is used to set the permissions boundary for the pod identity role. Defaults to `null`." -} - -variable "pod_identity_additional_policies" { - type = map(string) - default = null - description = "Map of the additional policies to be attached to pod identity role. Where key is arbitrary id and value is policy ARN. Defaults to `{}`." -} - -variable "pod_identity_tags" { - type = map(string) - default = null - description = "Pod identity resources tags. Defaults to `{}`." -} diff --git a/variables-addon.tf b/variables-addon.tf index a5ebced..b14592b 100644 --- a/variables-addon.tf +++ b/variables-addon.tf @@ -105,13 +105,13 @@ variable "argo_helm_wait_backoff_limit" { variable "argo_helm_wait_kubectl_version" { type = string default = null - description = "Version of kubectl to use for ArgoCD Application wait job. Defaults to `1.33.0`." + description = "Version of kubectl to use for ArgoCD Application wait job. Defaults to `1.33.3`." } variable "argo_source_type" { type = string default = null - description = "Source type for ArgoCD Application. Can be either `helm`, `kustomize`, or `directory`. Defaults to `helm`." + description = "Source type for ArgoCD Application. Can be either `helm`, `kustomize`, `directory` or `helm-directory`. Defaults to `helm`." } variable "argo_source_repo_url" { @@ -147,7 +147,7 @@ variable "argo_project" { variable "argo_info" { type = list(any) default = null - description = "ArgoCD Application manifest info parameter. Defaults to `[{\"name\": \"terraform\", \"value\": \"true\"}]`." + description = "ArgoCD Application manifest info parameter. Defaults to `[{ name = \"terraform\", value = \"true\" }]`." } variable "argo_sync_policy" { @@ -159,7 +159,7 @@ variable "argo_sync_policy" { 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" { @@ -195,7 +195,7 @@ variable "argo_helm_values" { variable "argo_kubernetes_manifest_computed_fields" { type = list(string) default = null - description = "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\"]`." + description = "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\"]`." } variable "argo_kubernetes_manifest_field_manager_name" { diff --git a/versions.tf b/versions.tf index 58a9f12..8d6c6e3 100644 --- a/versions.tf +++ b/versions.tf @@ -1,23 +1,27 @@ # 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. terraform { - required_version = ">= 1.5.0" + required_version = ">= 1.5" required_providers { aws = { source = "hashicorp/aws" - version = "~> 5" + version = ">= 5" } kubernetes = { source = "hashicorp/kubernetes" - version = ">= 2.20.0" + version = ">= 2.20" } helm = { source = "hashicorp/helm" - version = ">= 2.6.0" + version = ">= 2.6" } utils = { source = "cloudposse/utils" - version = ">= 0.17.0" + version = ">= 1" + } + random = { + source = "hashicorp/random" + version = ">= 3" } } } From e31b1bd6f76273b9df24740611a46cc50dec9516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Odstr=C4=8Dil=C3=ADk?= Date: Fri, 8 Aug 2025 14:50:04 +0200 Subject: [PATCH 4/6] refactor: remove unused input variables from README.md --- README.md | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/README.md b/README.md index 807a2a6..2810bd8 100644 --- a/README.md +++ b/README.md @@ -100,9 +100,6 @@ See [basic example](examples/basic) for further information. | [argo\_spec](#input\_argo\_spec) | ArgoCD Application spec configuration. Configuration is extended by deep merging with the default spec parameters. Defaults to `{}`. | `any` | | [argo\_spec\_override](#input\_argo\_spec\_override) | ArgoCD Application spec configuration. Configuration is overriden by merging natively with the default spec parameters. 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 for IRSA). Defaults to `""`. | `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 for IRSA). Defaults to `""`. | `string` | -| [cluster\_name](#input\_cluster\_name) | The name of the cluster (required for pod identity). Defaults to `""`. | `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. Required if `argo_source_type` is set to `helm`. Defaults to `""`. | `string` | @@ -138,31 +135,7 @@ See [basic example](examples/basic) for further information. | [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`. 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\_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 `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 (required). | `string` | -| [pod\_identity\_additional\_policies](#input\_pod\_identity\_additional\_policies) | Map of the additional policies to be attached to pod identity role. Where key is arbitrary id and value is policy ARN. Defaults to `{}`. | `map(string)` | -| [pod\_identity\_permissions\_boundary](#input\_pod\_identity\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the pod identity role. Defaults to `null`. | `string` | -| [pod\_identity\_policy](#input\_pod\_identity\_policy) | AWS IAM policy JSON document to be attached to the pod identity role. Applied only if `pod_identity_policy_enabled` is `true`. Defaults to `""`. | `string` | -| [pod\_identity\_policy\_enabled](#input\_pod\_identity\_policy\_enabled) | Whether to create IAM policy specified by `pod_identity_policy`. Defaults to `false`. | `bool` | -| [pod\_identity\_role\_create](#input\_pod\_identity\_role\_create) | Whether to create pod identity role and annotate Service Account. Defaults to `false`. | `bool` | -| [pod\_identity\_role\_name](#input\_pod\_identity\_role\_name) | Pod identity role name. The value is prefixed by `pod_identity_role_name_prefix`. Either `pod_identity_role_name` or `pod_identity_role_name_prefix` must be set. Defaults to `""`. | `string` | -| [pod\_identity\_role\_name\_prefix](#input\_pod\_identity\_role\_name\_prefix) | Pod identity role name prefix. Either `pod_identity_role_name_prefix` or `pod_identity_role_name` must be set. Defaults to `""`. | `string` | -| [pod\_identity\_tags](#input\_pod\_identity\_tags) | Pod identity 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 `""`. | `string` | -| [service\_account\_namespace](#input\_service\_account\_namespace) | The Kubernetes Service Account namespace. Defaults to `""`. | `string` | | [settings](#input\_settings) | Additional Helm sets which will be passed to the Helm chart values or Kustomize or directory configuration which will be passed to ArgoCD Application source. Defaults to `{}`. | `map(any)` | | [values](#input\_values) | Additional YAML encoded values which will be passed to the Helm chart. Defaults to `""`. | `string` | ## Outputs From e376be202da46508b7aa094db3d383b658ac504f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Odstr=C4=8Dil=C3=ADk?= Date: Fri, 8 Aug 2025 15:04:54 +0200 Subject: [PATCH 5/6] feat: add cache warmup workflow and update ASDF version in existing workflows --- .github/workflows/cache-warmup.yaml | 57 ++++++++++++++++++++++++++++ .github/workflows/pre-commit.yaml | 26 ++++++------- .github/workflows/pull-request.yml | 31 +++++++++++++++ .github/workflows/template-sync.yaml | 25 +++++------- .github/workflows/validate.yaml | 2 +- 5 files changed, 112 insertions(+), 29 deletions(-) create mode 100644 .github/workflows/cache-warmup.yaml create mode 100644 .github/workflows/pull-request.yml diff --git a/.github/workflows/cache-warmup.yaml b/.github/workflows/cache-warmup.yaml new file mode 100644 index 0000000..6215b8e --- /dev/null +++ b/.github/workflows/cache-warmup.yaml @@ -0,0 +1,57 @@ +name: Cache Warmup + +on: + push: + branches: + - main # caches from the main branch are shared with all other branches and pull requests + +permissions: {} + +env: + # renovate: datasource=github-releases depName=asdf-vm/asdf + ASDF_VERSION: 0.18.0 + +jobs: + pre-commit: + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + + - name: Setup ASDF + uses: asdf-vm/actions/setup@1902764435ca0dd2f3388eea723a4f92a4eb8302 # v4.0.0 + with: + asdf_version: ${{ env.ASDF_VERSION }} + + - name: Cache ASDF + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + id: asdf-cache + with: + # https://github.com/asdf-vm/asdf/blob/master/.gitignore + path: | + ~/.asdf/installs + ~/.asdf/plugins + ~/.asdf/shims + ~/.cache/pip + key: ${{ runner.os }}-asdf-${{ hashFiles('.tool-versions') }}-warmup + restore-keys: ${{ runner.os }}-asdf- + + - name: Install ASDF + uses: asdf-vm/actions/install@1902764435ca0dd2f3388eea723a4f92a4eb8302 # v4.0.0 + if: ${{ steps.asdf-cache.outputs.cache-hit != 'true' }} + with: + asdf_version: ${{ env.ASDF_VERSION }} + + - name: Cache pre-commit + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + with: + path: ~/.cache/pre-commit + key: ${{ runner.os }}-pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}-warmup + restore-keys: ${{ runner.os }}-pre-commit- + + - name: Run pre-commit + run: pre-commit install --install-hooks + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # required for GH API calls quota diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index 17688c8..8035265 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -16,7 +16,7 @@ concurrency: env: # renovate: datasource=github-releases depName=asdf-vm/asdf - ASDF_VERSION: 31e8c93004abd76253d186b8896785895069749b # v0.15.0 # pragma: allowlist secret + ASDF_VERSION: 0.18.0 jobs: pre-commit: @@ -28,7 +28,9 @@ jobs: persist-credentials: false - name: Setup ASDF - uses: asdf-vm/actions/setup@05e0d2ed97b598bfce82fd30daf324ae0c4570e6 # v3.0.2 + uses: asdf-vm/actions/setup@1902764435ca0dd2f3388eea723a4f92a4eb8302 # v4.0.0 + with: + asdf_version: ${{ env.ASDF_VERSION }} - name: Cache ASDF uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 @@ -39,31 +41,29 @@ jobs: ~/.asdf/installs ~/.asdf/plugins ~/.asdf/shims + ~/.cache/pip key: ${{ runner.os }}-asdf-${{ hashFiles('.tool-versions') }} - restore-keys: ${{ runner.os }}-asdf- + restore-keys: ${{ runner.os }}-asdf-${{ hashFiles('.tool-versions') }}- - name: Install ASDF - uses: asdf-vm/actions/install@05e0d2ed97b598bfce82fd30daf324ae0c4570e6 # v3.0.2 + uses: asdf-vm/actions/install@1902764435ca0dd2f3388eea723a4f92a4eb8302 # v4.0.0 if: ${{ steps.asdf-cache.outputs.cache-hit != 'true' }} with: - asdf_branch: ${{ env.ASDF_VERSION }} + asdf_version: ${{ env.ASDF_VERSION }} - name: Reshim installed ASDF tools shell: bash run: asdf reshim - - name: Cache pip + - name: Cache pre-commit uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 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 + path: ~/.cache/pre-commit + key: ${{ runner.os }}-pre-commit-${{ hashFiles('.pre-commit-config.yaml') }} + restore-keys: ${{ runner.os }}-pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}- - name: Run pre-commit run: pre-commit run --show-diff-on-failure --color=always --all-files env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # required for GH API calls quota GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # required for zizmor diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000..107ccd1 --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,31 @@ +name: Pull Request + +on: + pull_request: + types: + - opened + - edited + - reopened + - synchronize + +permissions: + pull-requests: read + +jobs: + semantic-title: + runs-on: ubuntu-24.04 + steps: + - uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 # v5.5.3 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + types: | + chore + ci + docs + feat + fix + refactor + style + requireScope: true + subjectPattern: "^.{0,120}$" diff --git a/.github/workflows/template-sync.yaml b/.github/workflows/template-sync.yaml index 6425d0f..4aa77b3 100644 --- a/.github/workflows/template-sync.yaml +++ b/.github/workflows/template-sync.yaml @@ -13,7 +13,7 @@ concurrency: env: # renovate: datasource=github-releases depName=asdf-vm/asdf - ASDF_VERSION: 31e8c93004abd76253d186b8896785895069749b # v0.15.0 # pragma: allowlist secret + ASDF_VERSION: 0.18.0 jobs: universal-addon: @@ -22,7 +22,7 @@ jobs: steps: - name: Generate GitHub App token id: template-sync-app-token - uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2 + uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6 with: app-id: ${{ secrets.LARA_TEMPLATE_SYNC_APP_ID }} private-key: ${{ secrets.LARA_TEMPLATE_SYNC_APP_PRIVATE_KEY }} @@ -36,7 +36,7 @@ jobs: persist-credentials: false - name: Sync universal-addon template - uses: AndreasAugustin/actions-template-sync@bcb94410a4f1dffdfe5eaabc8234c3b8e76ebc5b # v2.5.1 + uses: AndreasAugustin/actions-template-sync@8ec19a5f2721ffb81ff809aa340ddf75e6a85ea6 # v2.5.2 with: source_gh_token: ${{ steps.template-sync-app-token.outputs.token }} source_repo_path: lablabs/terraform-aws-eks-universal-addon @@ -54,7 +54,9 @@ jobs: is_pr_cleanup: true - name: Setup ASDF - uses: asdf-vm/actions/setup@05e0d2ed97b598bfce82fd30daf324ae0c4570e6 # v3.0.2 + uses: asdf-vm/actions/setup@1902764435ca0dd2f3388eea723a4f92a4eb8302 # v4.0.0 + with: + asdf_version: ${{ env.ASDF_VERSION }} - name: Cache ASDF uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 @@ -65,27 +67,20 @@ jobs: ~/.asdf/installs ~/.asdf/plugins ~/.asdf/shims + ~/.cache/pip key: ${{ runner.os }}-asdf-${{ hashFiles('.tool-versions') }} - restore-keys: ${{ runner.os }}-asdf- + restore-keys: ${{ runner.os }}-asdf-${{ hashFiles('.tool-versions') }}- - name: Install ASDF - uses: asdf-vm/actions/install@05e0d2ed97b598bfce82fd30daf324ae0c4570e6 # v3.0.2 + uses: asdf-vm/actions/install@1902764435ca0dd2f3388eea723a4f92a4eb8302 # v4.0.0 if: ${{ steps.asdf-cache.outputs.cache-hit != 'true' }} with: - asdf_branch: ${{ env.ASDF_VERSION }} + asdf_version: ${{ env.ASDF_VERSION }} - name: Reshim installed ASDF tools shell: bash run: asdf reshim - - name: Cache pip - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - with: - path: ~/.cache/pip/ - key: ${{ runner.os }}-pip-${{ hashFiles('.pre-commit-config.yaml') }} - restore-keys: | - ${{ runner.os }}-pip- - - name: Update README.md run: pre-commit run --show-diff-on-failure --color=always terraform_docs --all-files || true diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index b7463fe..bb76f41 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -23,7 +23,7 @@ jobs: - name: Extract Terraform min/max versions id: terraform-min-max - uses: clowdhaus/terraform-min-max@f489335873df04c3ce04b5e73f385a726d910039 # v1.3.2 + uses: clowdhaus/terraform-min-max@04440fe3b2a1e64eb5ad115f8f7c57c4d6a54333 # v1.4.1 with: directory: . outputs: From 12f16d02616b205904a0c5aa903618aca0886631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Odstr=C4=8Dil=C3=ADk?= Date: Mon, 11 Aug 2025 10:26:00 +0200 Subject: [PATCH 6/6] fix: update pre-commit workflow badge URL in README.md and main.tf --- README.md | 2 +- main.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2810bd8..383ac23 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ A Terraform module to deploy the [Node Local DNS](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/) on Amazon EKS cluster. The upgrade process of this module is using the `create before destroy` feature, and the already running DaemonSet will be terminated after the new one is already running. [![Terraform validate](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/validate.yaml/badge.svg)](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/validate.yaml) -[![pre-commit](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/pre-commit.yml) +[![pre-commit](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/pre-commit.yaml/badge.svg)](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/pre-commit.yaml) --- diff --git a/main.tf b/main.tf index e6040ea..ff3b24a 100644 --- a/main.tf +++ b/main.tf @@ -4,7 +4,7 @@ * A Terraform module to deploy the [Node Local DNS](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/) on Amazon EKS cluster. The upgrade process of this module is using the `create before destroy` feature, and the already running DaemonSet will be terminated after the new one is already running. * * [![Terraform validate](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/validate.yaml/badge.svg)](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/validate.yaml) - * [![pre-commit](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/pre-commit.yml) + * [![pre-commit](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/pre-commit.yaml/badge.svg)](https://github.com/lablabs/terraform-aws-eks-node-local-dns/actions/workflows/pre-commit.yaml) */ locals { addon = {