From 93da3524a3fdb66381b0a2eaa8c9c316c1531401 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Thu, 1 Aug 2024 21:29:46 -0400 Subject: [PATCH 01/40] ci(base): add repo features --- .cz.yaml | 8 ++ .github/dependabot.yml | 11 +++ .pre-commit-config.yaml | 99 +++++++++++++++++++++++ .pre-commit-hooks.yaml | 170 ++++++++++++++++++++++++++++++++++++++++ .releaserc.json | 36 +++++++++ .terraform-docs.yml | 44 +++++++++++ .tflint.hcl | 29 +++++++ 7 files changed, 397 insertions(+) create mode 100644 .cz.yaml create mode 100644 .github/dependabot.yml create mode 100644 .pre-commit-config.yaml create mode 100644 .pre-commit-hooks.yaml create mode 100644 .releaserc.json create mode 100644 .terraform-docs.yml create mode 100644 .tflint.hcl diff --git a/.cz.yaml b/.cz.yaml new file mode 100644 index 0000000..35aa66f --- /dev/null +++ b/.cz.yaml @@ -0,0 +1,8 @@ +--- +commitizen: + major_version_zero: true + name: cz_gitmoji + tag_format: $version + update_changelog_on_bump: true + version: 0.0.1 + version_scheme: semver2 diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..867570d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "terraform" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "daily" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..4fb8e19 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,99 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + # Git style + - id: check-added-large-files + - id: check-merge-conflict + - id: check-vcs-permalinks + - id: forbid-new-submodules + - id: no-commit-to-branch + + # Common errors + - id: end-of-file-fixer + - id: trailing-whitespace + args: [--markdown-linebreak-ext=md] + exclude: CHANGELOG.md + - id: check-yaml + - id: check-merge-conflict + - id: check-executables-have-shebangs + + # Cross platform + - id: check-case-conflict + - id: mixed-line-ending + args: [--fix=lf] + + # Security + - id: detect-aws-credentials + args: ['--allow-missing-credentials'] + - id: detect-private-key + +# JSON5 Linter +- repo: https://github.com/pre-commit/mirrors-prettier + rev: v4.0.0-alpha.8 + hooks: + - id: prettier + # https://prettier.io/docs/en/options.html#parser + files: '.json5$' + +# Terraform Hooks +- repo: https://github.com/antonbabenko/pre-commit-terraform + rev: v1.92.0 # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases + hooks: + - id: terraform_fmt + args: + - --hook-config=--parallelism-ci-cpu-cores=2 + - id: terraform_docs + args: + - --hook-config=--parallelism-ci-cpu-cores=2 + - id: terraform_tflint + name: Terraform validate with tflint + description: Validates all Terraform configuration files with TFLint. + require_serial: true + entry: hooks/terraform_tflint.sh + language: script + files: (\.tf|\.tfvars)$ + exclude: \.(terraform/.*|terragrunt-cache)$ + args: + - --hook-config=--parallelism-ci-cpu-cores=2 + - id: terragrunt_fmt + name: Terragrunt fmt + description: Rewrites all Terragrunt configuration files to a canonical format. + entry: hooks/terragrunt_fmt.sh + language: script + files: (\.hcl)$ + exclude: \.(terraform/.*|terragrunt-cache)$ + args: + - --hook-config=--parallelism-ci-cpu-cores=2 + - id: terragrunt_validate + name: Terragrunt validate + description: Validates all Terragrunt configuration files. + entry: hooks/terragrunt_validate.sh + language: script + files: (\.hcl)$ + exclude: \.(terraform/.*|terragrunt-cache)$ + args: + - --hook-config=--parallelism-ci-cpu-cores=2 + - id: terragrunt_validate_inputs + name: Terragrunt validate inputs + description: Validates Terragrunt unused and undefined inputs. + entry: hooks/terragrunt_validate_inputs.sh + language: script + files: (\.hcl)$ + exclude: \.(terraform/.*|terragrunt-cache)$ + args: + - --hook-config=--parallelism-ci-cpu-cores=2 + - id: terragrunt_providers_lock + name: Terragrunt providers lock + description: Updates provider signatures in dependency lock files using terragrunt. + entry: hooks/terragrunt_providers_lock.sh + language: script + files: (terragrunt|\.terraform\.lock)\.hcl$ + exclude: \.(terraform/.*|terragrunt-cache)$ + args: + - --hook-config=--parallelism-ci-cpu-cores=2 + +- repo: https://github.com/ljnsn/cz-conventional-gitmoji + rev: v0.3.2 + hooks: + - id: conventional-gitmoji diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml new file mode 100644 index 0000000..266f0c7 --- /dev/null +++ b/.pre-commit-hooks.yaml @@ -0,0 +1,170 @@ +#### THESE ARE NOT ENABLED, THEY ARE FOR REFERENCE +# - id: infracost_breakdown +# name: Infracost breakdown +# description: Check terraform infrastructure cost +# entry: hooks/infracost_breakdown.sh +# language: script +# require_serial: true +# files: \.(tf(vars)?|hcl)$ +# exclude: \.terraform/.*$ + +# - id: terraform_fmt +# name: Terraform fmt +# description: Rewrites all Terraform configuration files to a canonical format. +# entry: hooks/terraform_fmt.sh +# language: script +# files: (\.tf|\.tfvars)$ +# exclude: \.terraform/.*$ + +# - id: terraform_docs +# name: Terraform docs +# description: Inserts input and output documentation into README.md (using terraform-docs). +# require_serial: true +# entry: hooks/terraform_docs.sh +# language: script +# files: (\.tf|\.terraform\.lock\.hcl)$ +# exclude: \.terraform/.*$ + +# - id: terraform_docs_without_aggregate_type_defaults +# name: Terraform docs (without aggregate type defaults) +# description: Inserts input and output documentation into README.md (using terraform-docs). Identical to terraform_docs. +# require_serial: true +# entry: hooks/terraform_docs.sh +# language: script +# files: (\.tf)$ +# exclude: \.terraform/.*$ + +# - id: terraform_docs_replace +# name: Terraform docs (overwrite README.md) +# description: Overwrite content of README.md with terraform-docs. +# require_serial: true +# entry: terraform_docs_replace +# language: python +# files: (\.tf)$ +# exclude: \.terraform/.*$ + +# - id: terraform_validate +# name: Terraform validate +# description: Validates all Terraform configuration files. +# require_serial: true +# entry: hooks/terraform_validate.sh +# language: script +# files: \.(tf(vars)?|terraform\.lock\.hcl)$ +# exclude: \.terraform/.*$ + +# - id: terraform_providers_lock +# name: Lock terraform provider versions +# description: Updates provider signatures in dependency lock files. +# require_serial: true +# entry: hooks/terraform_providers_lock.sh +# language: script +# files: (\.terraform\.lock\.hcl)$ +# exclude: \.terraform/.*$ + +# - id: terraform_tflint +# name: Terraform validate with tflint +# description: Validates all Terraform configuration files with TFLint. +# require_serial: true +# entry: hooks/terraform_tflint.sh +# language: script +# files: (\.tf|\.tfvars)$ +# exclude: \.terraform/.*$ + +# - id: terragrunt_fmt +# name: Terragrunt fmt +# description: Rewrites all Terragrunt configuration files to a canonical format. +# entry: hooks/terragrunt_fmt.sh +# language: script +# files: (\.hcl)$ +# exclude: \.terraform/.*$ + +# - id: terragrunt_validate +# name: Terragrunt validate +# description: Validates all Terragrunt configuration files. +# entry: hooks/terragrunt_validate.sh +# language: script +# files: (\.hcl)$ +# exclude: \.terraform/.*$ + +# - id: terragrunt_validate_inputs +# name: Terragrunt validate inputs +# description: Validates Terragrunt unused and undefined inputs. +# entry: hooks/terragrunt_validate_inputs.sh +# language: script +# files: (\.hcl)$ +# exclude: \.terraform/.*$ + +# - id: terragrunt_providers_lock +# name: Terragrunt providers lock +# description: Updates provider signatures in dependency lock files using terragrunt. +# entry: hooks/terragrunt_providers_lock.sh +# language: script +# files: (terragrunt|\.terraform\.lock)\.hcl$ +# exclude: \.(terraform/.*|terragrunt-cache)$ + +# - id: terraform_tfsec +# name: Terraform validate with tfsec (deprecated, use "terraform_trivy") +# description: Static analysis of Terraform templates to spot potential security issues. +# require_serial: true +# entry: hooks/terraform_tfsec.sh +# files: \.tf(vars)?$ +# language: script + +# - id: terraform_trivy +# name: Terraform validate with trivy +# description: Static analysis of Terraform templates to spot potential security issues. +# require_serial: true +# entry: hooks/terraform_trivy.sh +# files: \.tf(vars)?$ +# language: script + +# - id: checkov +# name: checkov (deprecated, use "terraform_checkov") +# description: Runs checkov on Terraform templates. +# entry: checkov -d . +# language: python +# pass_filenames: false +# always_run: false +# files: \.tf$ +# exclude: \.terraform/.*$ +# require_serial: true + +# - id: terraform_checkov +# name: Checkov +# description: Runs checkov on Terraform templates. +# entry: hooks/terraform_checkov.sh +# language: script +# always_run: false +# files: \.tf$ +# exclude: \.terraform/.*$ +# require_serial: true + +# - id: terraform_wrapper_module_for_each +# name: Terraform wrapper with for_each in module +# description: Generate Terraform wrappers with for_each in module. +# entry: hooks/terraform_wrapper_module_for_each.sh +# language: script +# pass_filenames: false +# always_run: false +# require_serial: true +# files: \.tf$ +# exclude: \.terraform/.*$ + +# - id: terrascan +# name: terrascan +# description: Runs terrascan on Terraform templates. +# language: script +# entry: hooks/terrascan.sh +# files: \.tf$ +# exclude: \.terraform/.*$ +# require_serial: true + +# - id: tfupdate +# name: tfupdate +# description: Runs tfupdate on Terraform templates. +# language: script +# entry: hooks/tfupdate.sh +# args: +# - --args=terraform +# files: \.tf$ +# require_serial: true diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 0000000..6e39031 --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,36 @@ +{ + "branches": [ + "main", + "master" + ], + "ci": false, + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + [ + "@semantic-release/github", + { + "successComment": + "This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} :tada:", + "labels": false, + "releasedLabels": false + } + ], + [ + "@semantic-release/changelog", + { + "changelogFile": "CHANGELOG.md", + "changelogTitle": "# Changelog\n\nAll notable changes to this project will be documented in this file." + } + ], + [ + "@semantic-release/git", + { + "assets": [ + "CHANGELOG.md" + ], + "message": "chore(release): version ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + } + ] + ] +} diff --git a/.terraform-docs.yml b/.terraform-docs.yml new file mode 100644 index 0000000..fabfb8d --- /dev/null +++ b/.terraform-docs.yml @@ -0,0 +1,44 @@ +formatter: markdown table + +header-from: main.tf +footer-from: "" + +sections: +## hide: [] + show: + - data-sources + - header + - footer + - inputs + - modules + - outputs + - providers + - requirements + - resources + +output: + file: README.md + mode: inject + template: |- + + {{ .Content }} + + +output-values: + enabled: false + from: "" + +sort: + enabled: true + by: name + +settings: + anchor: true + color: true + default: true + description: true + escape: true + indent: 2 + required: true + sensitive: true + type: true diff --git a/.tflint.hcl b/.tflint.hcl new file mode 100644 index 0000000..30b0d2c --- /dev/null +++ b/.tflint.hcl @@ -0,0 +1,29 @@ +config { + module = true + force = false + disabled_by_default = false + + # ignore_module = { + # "terraform-aws-modules/vpc/aws" = true + # "terraform-aws-modules/security-group/aws" = true + # } + + # varfile = ["example1.tfvars", "example2.tfvars"] + # variables = ["foo=bar", "bar=[\"baz\"]"] +} + +rule "aws_instance_invalid_type" { + enabled = true +} + +plugin "aws" { + enabled = true + version = "0.32.0" + source = "github.com/terraform-linters/tflint-ruleset-aws" +} + +plugin "terraform" { + enabled = true + version = "0.9.0" + source = "github.com/terraform-linters/tflint-ruleset-terraform" +} From fb8470dc1bb73479499d688289c24f0a93bd3b1b Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Thu, 1 Aug 2024 23:58:35 -0400 Subject: [PATCH 02/40] lints --- .gitignore | 2 +- .pre-commit-config.yaml | 68 +++++++++++-------- .tflint.hcl | 8 --- EC2NodePool.yaml.tpl | 22 ------ README.md | 25 ++++--- ...eClass.yaml.tpl => ec2_node_class.yaml.tpl | 7 +- ec2_node_pool.yaml.tpl | 40 +++++++++++ examples/simple/README.md | 12 ++-- examples/simple/karpenter.tf | 2 +- examples/simple/providers.tf | 17 ++++- examples/simple/variables.tf | 2 +- main.tf | 30 ++++---- outputs.tf | 4 +- requirements.tf | 5 -- terragrunt.hcl | 24 +++++++ version.tf | 4 +- 16 files changed, 167 insertions(+), 105 deletions(-) delete mode 100644 EC2NodePool.yaml.tpl rename EC2NodeClass.yaml.tpl => ec2_node_class.yaml.tpl (75%) create mode 100644 ec2_node_pool.yaml.tpl create mode 100644 terragrunt.hcl diff --git a/.gitignore b/.gitignore index 7c1cae9..98d790c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Local .terraform directories **/.terraform/* +**/.terragrunt-cache/* # terraform lock file. **/.terraform.lock.hcl @@ -35,4 +36,3 @@ override.tf.json # Ignore CLI configuration files .terraformrc terraform.rc - diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4fb8e19..d6091dd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,6 +8,17 @@ repos: - id: check-vcs-permalinks - id: forbid-new-submodules - id: no-commit-to-branch + - id: check-byte-order-marker + - id: check-case-conflict + - id: check-json + - id: check-merge-conflict + - id: check-symlinks + - id: check-vcs-permalinks + - id: check-toml + - id: check-xml + - id: detect-private-key + - id: requirements-txt-fixer + - id: sort-simple-yaml # Common errors - id: end-of-file-fixer @@ -38,7 +49,7 @@ repos: # Terraform Hooks - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.92.0 # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases + rev: v1.92.1 # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases hooks: - id: terraform_fmt args: @@ -65,33 +76,34 @@ repos: exclude: \.(terraform/.*|terragrunt-cache)$ args: - --hook-config=--parallelism-ci-cpu-cores=2 - - id: terragrunt_validate - name: Terragrunt validate - description: Validates all Terragrunt configuration files. - entry: hooks/terragrunt_validate.sh - language: script - files: (\.hcl)$ - exclude: \.(terraform/.*|terragrunt-cache)$ - args: - - --hook-config=--parallelism-ci-cpu-cores=2 - - id: terragrunt_validate_inputs - name: Terragrunt validate inputs - description: Validates Terragrunt unused and undefined inputs. - entry: hooks/terragrunt_validate_inputs.sh - language: script - files: (\.hcl)$ - exclude: \.(terraform/.*|terragrunt-cache)$ - args: - - --hook-config=--parallelism-ci-cpu-cores=2 - - id: terragrunt_providers_lock - name: Terragrunt providers lock - description: Updates provider signatures in dependency lock files using terragrunt. - entry: hooks/terragrunt_providers_lock.sh - language: script - files: (terragrunt|\.terraform\.lock)\.hcl$ - exclude: \.(terraform/.*|terragrunt-cache)$ - args: - - --hook-config=--parallelism-ci-cpu-cores=2 + # Will require dependency mocks + # - id: terragrunt_validate + # name: Terragrunt validate + # description: Validates all Terragrunt configuration files. + # entry: hooks/terragrunt_validate.sh + # language: script + # files: (\.hcl)$ + # exclude: \.(terraform/.*|terragrunt-cache)$ + # args: + # - --hook-config=--parallelism-ci-cpu-cores=2 + # - id: terragrunt_validate_inputs + # name: Terragrunt validate inputs + # description: Validates Terragrunt unused and undefined inputs. + # entry: hooks/terragrunt_validate_inputs.sh + # language: script + # files: (\.hcl)$ + # exclude: \.(terraform/.*|terragrunt-cache)$ + # args: + # - --hook-config=--parallelism-ci-cpu-cores=2 + # - id: terragrunt_providers_lock + # name: Terragrunt providers lock + # description: Updates provider signatures in dependency lock files using terragrunt. + # entry: hooks/terragrunt_providers_lock.sh + # language: script + # files: (terragrunt|\.terraform\.lock)\.hcl$ + # exclude: \.(terraform/.*|terragrunt-cache)$ + # args: + # - --hook-config=--parallelism-ci-cpu-cores=2 - repo: https://github.com/ljnsn/cz-conventional-gitmoji rev: v0.3.2 diff --git a/.tflint.hcl b/.tflint.hcl index 30b0d2c..684d807 100644 --- a/.tflint.hcl +++ b/.tflint.hcl @@ -2,14 +2,6 @@ config { module = true force = false disabled_by_default = false - - # ignore_module = { - # "terraform-aws-modules/vpc/aws" = true - # "terraform-aws-modules/security-group/aws" = true - # } - - # varfile = ["example1.tfvars", "example2.tfvars"] - # variables = ["foo=bar", "bar=[\"baz\"]"] } rule "aws_instance_invalid_type" { diff --git a/EC2NodePool.yaml.tpl b/EC2NodePool.yaml.tpl deleted file mode 100644 index 538f282..0000000 --- a/EC2NodePool.yaml.tpl +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: karpenter.sh/v1beta1 -kind: NodePool -metadata: - name: default -spec: - template: - spec: - requirements: - - key: karpenter.sh/capacity-type - operator: In - values: ["spot", "on-demand"] - - key: "node.kubernetes.io/instance-type" - operator: In - values: ["t3a.xlarge", "t3.xlarge", "c5.large", "m5.large", "r5.large", "m5.xlarge"] - nodeClassRef: - name: default - limits: - cpu: 1000 - memory: 1000Gi - disruption: - consolidationPolicy: WhenUnderutilized - expireAfter: 24h # 30 * 24h = 720h diff --git a/README.md b/README.md index acf93ce..ee74d02 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ref: [Karpenter Best Practices](https://aws.github.io/aws-eks-best-practices/kar NOTE: Deploying Karpenter after deploying Istio is not recommended because it disrupts the handling of sidecars to pods on Karpenter managed nodes. As long as Karpenter is deployed first, there is no issue. -The module deploys Karpenter needed AWS resources, namely in IAM. It copies the Karpenter controller from the public registry to local ECR, deploys Karpenter via Helm and deploys a single default Karpenter Nodepool with EC2NodeClass. +The module deploys Karpenter needed AWS resources, namely in IAM. It copies the Karpenter controller from the public registry to local ECR, deploys Karpenter via Helm and deploys a single default Karpenter Nodepool with EC2NodeClass. # CHANGELOG * 0.0.2 -- 2024-07-30 @@ -29,32 +29,31 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [aws](#requirement\_aws) | >= 5.14.0 | | [helm](#requirement\_helm) | >= 2.11.0 | | [kubectl](#requirement\_kubectl) | >= 1.14.0 | -| [kubernetes](#requirement\_kubernetes) | >= 2.23.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 5.14.0 | -| [helm](#provider\_helm) | >= 2.11.0 | -| [kubectl](#provider\_kubectl) | >= 1.14.0 | +| [aws](#provider\_aws) | 5.61.0 | +| [helm](#provider\_helm) | 2.14.0 | +| [kubectl](#provider\_kubectl) | 1.14.0 | ## Modules | Name | Source | Version | |------|--------|---------| -| [images](#module\_images) | git@github.e.it.census.gov:terraform-modules/aws-ecr-copy-images.git/ | 2.0.2 | -| [karpenter\_resources](#module\_karpenter\_resources) | git@github.e.it.census.gov:SCT-Engineering/terraform-aws-eks.git//modules/karpenter | v20.8.5 | +| [images](#module\_images) | git@github.e.it.census.gov:terraform-modules/aws-ecr-copy-images.git/ | tf-upgrade | +| [karpenter\_resources](#module\_karpenter\_resources) | git@github.e.it.census.gov:SCT-Engineering/terraform-aws-eks.git//modules/karpenter | v20.20.0 | ## Resources | Name | Type | |------|------| -| [aws_iam_instance_profile.KarpenterNodeInstanceProfile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | +| [aws_iam_instance_profile.karpenter_node_instance_profile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | | [aws_iam_service_linked_role.ec2_spot](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_service_linked_role) | resource | | [helm_release.karpenter](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | -| [kubectl_manifest.karpenter_EC2NodeClass](https://registry.terraform.io/providers/gavinbunney/kubectl/latest/docs/resources/manifest) | resource | -| [kubectl_manifest.karpenter_NodePool](https://registry.terraform.io/providers/gavinbunney/kubectl/latest/docs/resources/manifest) | resource | +| [kubectl_manifest.karpenter_ec2_node_class](https://registry.terraform.io/providers/gavinbunney/kubectl/latest/docs/resources/manifest) | resource | +| [kubectl_manifest.karpenter_node_pool](https://registry.terraform.io/providers/gavinbunney/kubectl/latest/docs/resources/manifest) | resource | | [aws_ecr_image.karpenter_image](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecr_image) | data source | ## Inputs @@ -65,6 +64,7 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [cluster\_name](#input\_cluster\_name) | EKS cluster name name component used through out the EKS cluster describing its purpose (ex: dice-dev) | `string` | n/a | yes | | [karpenter\_helm\_chart](#input\_karpenter\_helm\_chart) | Which helm chart of karpenter | `string` | `"0.37.0"` | no | | [karpenter\_helm\_repo](#input\_karpenter\_helm\_repo) | Helm repo for official karpenter chart | `string` | `"oci://public.ecr.aws/karpenter"` | no | +| [karpenter\_node\_group\_name](#input\_karpenter\_node\_group\_name) | The cluster node group that will host karpenter, should not be a karpenter managed node group | `string` | n/a | yes | | [karpenter\_tag](#input\_karpenter\_tag) | Which tag of karpenter image | `string` | `"0.37.0"` | no | | [oidc\_provider\_arn](#input\_oidc\_provider\_arn) | The ARN of the OIDC Provider if `enable_irsa = true` | `string` | n/a | yes | | [profile](#input\_profile) | AWS config profile | `string` | `""` | no | @@ -73,5 +73,8 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the ## Outputs -No outputs. +| Name | Description | +|------|-------------| +| [module\_name](#output\_module\_name) | The name of this module. | +| [module\_version](#output\_module\_version) | The version of this module. | diff --git a/EC2NodeClass.yaml.tpl b/ec2_node_class.yaml.tpl similarity index 75% rename from EC2NodeClass.yaml.tpl rename to ec2_node_class.yaml.tpl index 4ba530d..04bd06a 100644 --- a/EC2NodeClass.yaml.tpl +++ b/ec2_node_class.yaml.tpl @@ -1,9 +1,10 @@ +--- apiVersion: karpenter.k8s.aws/v1beta1 kind: EC2NodeClass metadata: - name: default + name: ${cluster_name}-karpenter-nodes spec: - amiFamily: AL2 + amiFamily: ${amd_ami_family} instanceProfile: "KarpenterNodeInstanceProfile-${cluster_name}" subnetSelectorTerms: - tags: @@ -11,4 +12,4 @@ spec: securityGroupSelectorTerms: - tags: Name: "${cluster_name}-node" - tags: ${tags} \ No newline at end of file + tags: ${tags} diff --git a/ec2_node_pool.yaml.tpl b/ec2_node_pool.yaml.tpl new file mode 100644 index 0000000..81b1cef --- /dev/null +++ b/ec2_node_pool.yaml.tpl @@ -0,0 +1,40 @@ +--- +# NodePool for regular EC2 instances +apiVersion: karpenter.sh/v1beta1 +kind: NodePool +metadata: + name: generalcompute +spec: + disruption: + consolidationPolicy: WhenUnderutilized + expireAfter: 4h + template: + spec: + nodeClassRef: + name: ${cluster_name}-karpenter-nodes + requirements: + - key: node.kubernetes.io/instance-type + operator: In + values: + - m5.large + - m5.xlarge + - m5.2xlarge + - c5.large + - c5.xlarge + - c5a.large + - c5a.xlarge + - r5.large + - r5.xlarge + - key: kubernetes.io/os + operator: In + values: + - linux + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - key: karpenter.sh/capacity-type + operator: In + values: + - on-demand + - spot diff --git a/examples/simple/README.md b/examples/simple/README.md index 0cc9a49..2263b21 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -1,6 +1,6 @@ # Karpenter Example -Configuration in this directory creates an AWS EKS cluster with Karpenter provisioned for managing compute resource scaling. In the example, Karpenter is provisioned on top of an EKS Managed Node Group following best practice recommendations. +Configuration in this directory creates an AWS EKS cluster with Karpenter provisioned for managing compute resource scaling. In the example, Karpenter is provisioned on top of an EKS Managed Node Group following best practice recommendations. ## Usage @@ -15,15 +15,15 @@ $ terraform apply Verifying Karpenter is deployed: ```bash -$ # Verify Karpenter controller pods +$ # Verify Karpenter controller pods $ kubectl get pods -n karpenter -$ +$ $ # Review controller logs with $ kubectl logs -f -n karpenter -l app.kubernetes.io/name=karpenter -c controller -$ +$ $ # Identify Karpenter managed nodes $ kubectl get nodes -L karpenter.sh/registered -``` +``` ### Tear Down & Clean-Up @@ -83,4 +83,4 @@ terraform destroy ## Outputs No outputs. - \ No newline at end of file + diff --git a/examples/simple/karpenter.tf b/examples/simple/karpenter.tf index ee22cd7..d11d114 100644 --- a/examples/simple/karpenter.tf +++ b/examples/simple/karpenter.tf @@ -9,4 +9,4 @@ module "karpenter" { karpenter_node_group_name = var.karpenter_node_group_name tags = var.tags -} \ No newline at end of file +} diff --git a/examples/simple/providers.tf b/examples/simple/providers.tf index 02b5460..f0663ae 100644 --- a/examples/simple/providers.tf +++ b/examples/simple/providers.tf @@ -1,8 +1,21 @@ terraform { required_version = ">= 1.5.0" required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.14.0" + } + helm = { + source = "hashicorp/helm" + version = ">= 2.11.0" + } kubectl = { - source = "gavinbunney/kubectl" + source = "gavinbunney/kubectl" + version = ">= 1.14.0" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = ">= 2.23.0" } } } @@ -41,4 +54,4 @@ provider "kubectl" { cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority[0].data) token = data.aws_eks_cluster_auth.cluster.token load_config_file = false -} \ No newline at end of file +} diff --git a/examples/simple/variables.tf b/examples/simple/variables.tf index e049b3f..c13a56c 100644 --- a/examples/simple/variables.tf +++ b/examples/simple/variables.tf @@ -33,4 +33,4 @@ variable "tags" { description = "AWS Tags to apply to appropriate resources" type = map(string) default = {} -} \ No newline at end of file +} diff --git a/main.tf b/main.tf index 94ff312..481eada 100644 --- a/main.tf +++ b/main.tf @@ -128,12 +128,12 @@ resource "helm_release" "karpenter" { } -resource "aws_iam_instance_profile" "KarpenterNodeInstanceProfile" { +resource "aws_iam_instance_profile" "karpenter_node_instance_profile" { name = "KarpenterNodeInstanceProfile-${var.cluster_name}" role = module.karpenter_resources.node_iam_role_name } -# Permission for spot +# Permission for spot resource "aws_iam_service_linked_role" "ec2_spot" { aws_service_name = "spot.amazonaws.com" } @@ -141,29 +141,33 @@ resource "aws_iam_service_linked_role" "ec2_spot" { # Lookup eks amis // didn't use this but would be path to get to mixed architectures/processors # data "aws_ssm_parameter" "arm_ami_id" { -# name = "/aws/service/eks/optimized-ami/1.30/amazon-linux-2-arm64/recommended/image_id" +# name = "/aws/service/eks/optimized-ami/1.30/bottlerocket-arm64/recommended/image_id" # } # data "aws_ssm_parameter" "amd_ami_id" { -# name = "/aws/service/eks/optimized-ami/1.30/amazon-linux-2/recommended/image_id" +# name = "/aws/service/eks/optimized-ami/1.30/bottlerocket-x86_64/recommended/image_id" # } # SHOULD PROBABLY PUT THESE OBJECTS INTO A HELM CHART -# Create karpenter default -resource "kubectl_manifest" "karpenter_EC2NodeClass" { +# Create karpenter default +resource "kubectl_manifest" "karpenter_ec2_node_class" { depends_on = [ helm_release.karpenter, ] - yaml_body = templatefile("${path.module}/EC2NodeClass.yaml.tpl", { - cluster_name = var.cluster_name - tags = jsonencode(var.tags) + yaml_body = templatefile("${path.module}/ec2_node_class.yaml.tpl", { + cluster_name = var.cluster_name + amd_ami_family = "BOTTLEROCKET_x86_64" + + tags = jsonencode(var.tags) }) } -# Create karpenter default NodePool -resource "kubectl_manifest" "karpenter_NodePool" { +# Create karpenter default NodePool +resource "kubectl_manifest" "karpenter_node_pool" { depends_on = [ - kubectl_manifest.karpenter_EC2NodeClass, + kubectl_manifest.karpenter_ec2_node_class, ] - yaml_body = templatefile("${path.module}/EC2NodePool.yaml.tpl", {}) + yaml_body = templatefile("${path.module}/ec2_node_pool.yaml.tpl", { + cluster_name = var.cluster_name + }) } diff --git a/outputs.tf b/outputs.tf index 0349496..b999ac9 100644 --- a/outputs.tf +++ b/outputs.tf @@ -4,10 +4,10 @@ output "module_name" { description = "The name of this module." - value = local._module_name + value = local.module_name } output "module_version" { description = "The version of this module." - value = local._module_version + value = local.module_version } diff --git a/requirements.tf b/requirements.tf index 8c1f05b..4eab89e 100644 --- a/requirements.tf +++ b/requirements.tf @@ -14,10 +14,5 @@ terraform { source = "gavinbunney/kubectl" version = ">= 1.14.0" } - kubernetes = { - source = "hashicorp/kubernetes" - version = ">= 2.23.0" - } - } } diff --git a/terragrunt.hcl b/terragrunt.hcl new file mode 100644 index 0000000..d904b65 --- /dev/null +++ b/terragrunt.hcl @@ -0,0 +1,24 @@ +# include "root" { +# path = find_in_parent_folders() +# } + +terraform { + source = "../tfmod-karpenter" + extra_arguments "retry_lock" { + commands = get_terraform_commands_that_need_locking() + arguments = ["-lock-timeout=20m"] + } +} + +dependency "eks" { + config_path = "../tfmod-eks" +} + +inputs = { + cluster_endpoint = dependency.eks.outputs.cluster_endpoint + cluster_name = dependency.eks.inputs.cluster_name + karpenter_node_group_name = dependency.eks.outputs.node_group_name + oidc_provider_arn = dependency.eks.outputs.oidc_provider_arn + profile = dependency.eks.inputs.profile + region = dependency.eks.inputs.region +} diff --git a/version.tf b/version.tf index 5970ee3..3ae0d94 100644 --- a/version.tf +++ b/version.tf @@ -1,4 +1,4 @@ locals { - _module_name = "tfmod-karpenter" - _module_version = "0.0.2" + module_name = "tfmod-karpenter" + module_version = "0.0.2" } From 2d7e3eacc14c093aced5061e339d45406e7cabeb Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Thu, 1 Aug 2024 23:59:39 -0400 Subject: [PATCH 03/40] add changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..39a1b93 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +## Unreleased + +### ci + +- **base**: add repo features From 4851a6854b4ea817536067c94dbbfc3041de1d1f Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Fri, 2 Aug 2024 17:31:16 -0400 Subject: [PATCH 04/40] fix(main.tf): correct the value for amd_ami_family --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 481eada..de74a74 100644 --- a/main.tf +++ b/main.tf @@ -156,7 +156,7 @@ resource "kubectl_manifest" "karpenter_ec2_node_class" { ] yaml_body = templatefile("${path.module}/ec2_node_class.yaml.tpl", { cluster_name = var.cluster_name - amd_ami_family = "BOTTLEROCKET_x86_64" + amd_ami_family = "Bottlerocket" tags = jsonencode(var.tags) }) From 65e7880e1dbd134b3a031113151c098d596e66d8 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Fri, 2 Aug 2024 18:12:16 -0400 Subject: [PATCH 05/40] use scm for ver --- .cz.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cz.yaml b/.cz.yaml index 35aa66f..b1981ec 100644 --- a/.cz.yaml +++ b/.cz.yaml @@ -4,5 +4,5 @@ commitizen: name: cz_gitmoji tag_format: $version update_changelog_on_bump: true - version: 0.0.1 + version_provider: scm version_scheme: semver2 From 088e7188e9faaa0ebaf059d9eab9eaf281432ee7 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Fri, 2 Aug 2024 18:13:33 -0400 Subject: [PATCH 06/40] add changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39a1b93..60bd7d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,3 +3,7 @@ ### ci - **base**: add repo features + +### fix + +- **main.tf**: correct the value for amd_ami_family From 2d0bd4490f63737035abe4559e9b11def78e3e98 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Fri, 2 Aug 2024 18:28:41 -0400 Subject: [PATCH 07/40] examples(terragrunt.hcl): mv terragrunt.hcl to examples/ folder --- terragrunt.hcl => examples/terragrunt.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename terragrunt.hcl => examples/terragrunt.hcl (95%) diff --git a/terragrunt.hcl b/examples/terragrunt.hcl similarity index 95% rename from terragrunt.hcl rename to examples/terragrunt.hcl index d904b65..b513eaf 100644 --- a/terragrunt.hcl +++ b/examples/terragrunt.hcl @@ -3,7 +3,7 @@ # } terraform { - source = "../tfmod-karpenter" + source = "../../tfmod-karpenter" extra_arguments "retry_lock" { commands = get_terraform_commands_that_need_locking() arguments = ["-lock-timeout=20m"] From 4b609e85346bfd5efd24e0fe1ca72ea39a2c4961 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Fri, 2 Aug 2024 18:30:27 -0400 Subject: [PATCH 08/40] move tg.hcl to examples folder --- examples/terragrunt.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/terragrunt.hcl b/examples/terragrunt.hcl index b513eaf..aa1a6b3 100644 --- a/examples/terragrunt.hcl +++ b/examples/terragrunt.hcl @@ -11,7 +11,7 @@ terraform { } dependency "eks" { - config_path = "../tfmod-eks" + config_path = "../../tfmod-eks" } inputs = { From e3ef9e1c6ae5a797a8e7b543d4bea728decfd133 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 5 Aug 2024 15:17:04 -0400 Subject: [PATCH 09/40] typo --- CHANGELOG.md | 8 ++++++++ README.md | 8 -------- ec2_node_class.yaml.tpl | 4 ++-- ec2_node_pool.yaml.tpl | 4 ++-- main.tf | 12 ++++++++---- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60bd7d1..c55b5f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,3 +7,11 @@ ### fix - **main.tf**: correct the value for amd_ami_family + + +* 0.0.2 -- 2024-07-30 + - update after removing cluster-autoscaler + - add second yaml template + - update images module +* 0.0.1 -- 2024-07-26 + - Genesis/Initial development diff --git a/README.md b/README.md index ee74d02..a072505 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,6 @@ NOTE: Deploying Karpenter after deploying Istio is not recommended because it di The module deploys Karpenter needed AWS resources, namely in IAM. It copies the Karpenter controller from the public registry to local ECR, deploys Karpenter via Helm and deploys a single default Karpenter Nodepool with EC2NodeClass. -# CHANGELOG -* 0.0.2 -- 2024-07-30 - - update after removing cluster-autoscaler - - add second yaml template - - update images module -* 0.0.1 -- 2024-07-26 - - Genesis/Initial development - ## Requirements diff --git a/ec2_node_class.yaml.tpl b/ec2_node_class.yaml.tpl index 04bd06a..668db58 100644 --- a/ec2_node_class.yaml.tpl +++ b/ec2_node_class.yaml.tpl @@ -2,10 +2,10 @@ apiVersion: karpenter.k8s.aws/v1beta1 kind: EC2NodeClass metadata: - name: ${cluster_name}-karpenter-nodes + name: ${cluster_name}-karpenter-node-class spec: amiFamily: ${amd_ami_family} - instanceProfile: "KarpenterNodeInstanceProfile-${cluster_name}" + instanceProfile: "${cluster_name}-karpenter-instance-profile" subnetSelectorTerms: - tags: Name: "*-container-*" diff --git a/ec2_node_pool.yaml.tpl b/ec2_node_pool.yaml.tpl index 81b1cef..fd4a448 100644 --- a/ec2_node_pool.yaml.tpl +++ b/ec2_node_pool.yaml.tpl @@ -3,7 +3,7 @@ apiVersion: karpenter.sh/v1beta1 kind: NodePool metadata: - name: generalcompute + name: ${cluster_name}-node-pool-general spec: disruption: consolidationPolicy: WhenUnderutilized @@ -11,7 +11,7 @@ spec: template: spec: nodeClassRef: - name: ${cluster_name}-karpenter-nodes + name: ${cluster_name}-karpenter-node-class requirements: - key: node.kubernetes.io/instance-type operator: In diff --git a/main.tf b/main.tf index de74a74..20a39ca 100644 --- a/main.tf +++ b/main.tf @@ -1,5 +1,6 @@ locals { namespace = "karpenter" + iam_arn = format("arn:%v:iam::%v:%%v", data.aws_arn.current.partition, data.aws_caller_identity.current.account_id) } # Replicating from here: https://github.e.it.census.gov/SCT-Engineering/terraform-aws-eks/tree/master/modules/karpenter @@ -13,7 +14,8 @@ module "karpenter_resources" { # Attach additional IAM policies to the Karpenter node IAM role node_iam_role_additional_policies = { - AmazonSSMManagedInstanceCore = "arn:aws-us-gov:iam::aws:policy/AmazonSSMManagedInstanceCore" + AmazonSSMManagedInstanceCore = format(local.iam_arn, "policy/AmazonSSMManagedInstanceCore") + # "arn:aws-us-gov:iam::aws:policy/AmazonSSMManagedInstanceCore" } tags = var.tags @@ -30,7 +32,7 @@ data "aws_ecr_image" "karpenter_image" { resource "helm_release" "karpenter" { depends_on = [ - module.images, + data.aws_ecr_image.karpenter_image ] name = "karpenter" chart = "karpenter" @@ -129,11 +131,13 @@ resource "helm_release" "karpenter" { resource "aws_iam_instance_profile" "karpenter_node_instance_profile" { - name = "KarpenterNodeInstanceProfile-${var.cluster_name}" + name = "${var.cluster_name}-karpenter-instance-profile" role = module.karpenter_resources.node_iam_role_name } -# Permission for spot + + +# # Permission for spot resource "aws_iam_service_linked_role" "ec2_spot" { aws_service_name = "spot.amazonaws.com" } From 6ac5e996b2ee9d6ec65fae0d635262af4736a0db Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 5 Aug 2024 19:52:00 -0400 Subject: [PATCH 10/40] use data item and count --- README.md | 1 + main.tf | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a072505..3174519 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [kubectl_manifest.karpenter_ec2_node_class](https://registry.terraform.io/providers/gavinbunney/kubectl/latest/docs/resources/manifest) | resource | | [kubectl_manifest.karpenter_node_pool](https://registry.terraform.io/providers/gavinbunney/kubectl/latest/docs/resources/manifest) | resource | | [aws_ecr_image.karpenter_image](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecr_image) | data source | +| [aws_iam_roles.roles](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_roles) | data source | ## Inputs diff --git a/main.tf b/main.tf index 20a39ca..d6b0498 100644 --- a/main.tf +++ b/main.tf @@ -135,10 +135,14 @@ resource "aws_iam_instance_profile" "karpenter_node_instance_profile" { role = module.karpenter_resources.node_iam_role_name } - +data "aws_iam_roles" "roles" { + name_regex = "AWSServiceRoleForEC2Spot" + path_prefix = "/aws-reserved/spot.amazonaws.com/" +} # # Permission for spot resource "aws_iam_service_linked_role" "ec2_spot" { + count = data.aws_iam_roles.roles == 1 ? 0 : 1 aws_service_name = "spot.amazonaws.com" } From 56812955e75c7c295bb4dc895a2bcb86400dc6da Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 5 Aug 2024 20:12:04 -0400 Subject: [PATCH 11/40] add logic for service-linked role --- README.md | 2 ++ aws_data.tf | 5 +++++ main.tf | 4 ++-- 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 aws_data.tf diff --git a/README.md b/README.md index 3174519..0f7c6cc 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,8 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [helm_release.karpenter](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [kubectl_manifest.karpenter_ec2_node_class](https://registry.terraform.io/providers/gavinbunney/kubectl/latest/docs/resources/manifest) | resource | | [kubectl_manifest.karpenter_node_pool](https://registry.terraform.io/providers/gavinbunney/kubectl/latest/docs/resources/manifest) | resource | +| [aws_arn.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | | [aws_ecr_image.karpenter_image](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecr_image) | data source | | [aws_iam_roles.roles](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_roles) | data source | diff --git a/aws_data.tf b/aws_data.tf new file mode 100644 index 0000000..2c6aade --- /dev/null +++ b/aws_data.tf @@ -0,0 +1,5 @@ +data "aws_caller_identity" "current" {} + +data "aws_arn" "current" { + arn = data.aws_caller_identity.current.arn +} diff --git a/main.tf b/main.tf index d6b0498..78897be 100644 --- a/main.tf +++ b/main.tf @@ -136,13 +136,13 @@ resource "aws_iam_instance_profile" "karpenter_node_instance_profile" { } data "aws_iam_roles" "roles" { - name_regex = "AWSServiceRoleForEC2Spot" + # name_regex = "AWSServiceRoleForEC2Spot" path_prefix = "/aws-reserved/spot.amazonaws.com/" } # # Permission for spot resource "aws_iam_service_linked_role" "ec2_spot" { - count = data.aws_iam_roles.roles == 1 ? 0 : 1 + count = data.aws_iam_roles.roles == null ? 1 : 0 aws_service_name = "spot.amazonaws.com" } From d5e8126b8fafae5899f766f4c1c7b3f1c07ad0ee Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 5 Aug 2024 20:17:14 -0400 Subject: [PATCH 12/40] fix format on policy --- main.tf | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/main.tf b/main.tf index 78897be..aeaec13 100644 --- a/main.tf +++ b/main.tf @@ -1,6 +1,5 @@ locals { namespace = "karpenter" - iam_arn = format("arn:%v:iam::%v:%%v", data.aws_arn.current.partition, data.aws_caller_identity.current.account_id) } # Replicating from here: https://github.e.it.census.gov/SCT-Engineering/terraform-aws-eks/tree/master/modules/karpenter @@ -14,7 +13,7 @@ module "karpenter_resources" { # Attach additional IAM policies to the Karpenter node IAM role node_iam_role_additional_policies = { - AmazonSSMManagedInstanceCore = format(local.iam_arn, "policy/AmazonSSMManagedInstanceCore") + AmazonSSMManagedInstanceCore = format("arn:%v:iam::%v:%%v", data.aws_arn.current.partition, "aws", "policy/AmazonSSMManagedInstanceCore") # "arn:aws-us-gov:iam::aws:policy/AmazonSSMManagedInstanceCore" } @@ -135,12 +134,12 @@ resource "aws_iam_instance_profile" "karpenter_node_instance_profile" { role = module.karpenter_resources.node_iam_role_name } +# Query to see if service-linked role exists data "aws_iam_roles" "roles" { - # name_regex = "AWSServiceRoleForEC2Spot" path_prefix = "/aws-reserved/spot.amazonaws.com/" } -# # Permission for spot +# Permission for spot resource "aws_iam_service_linked_role" "ec2_spot" { count = data.aws_iam_roles.roles == null ? 1 : 0 aws_service_name = "spot.amazonaws.com" From b5b34440efe9083902435d77132d325633ee32ee Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 5 Aug 2024 20:18:25 -0400 Subject: [PATCH 13/40] dupe --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index aeaec13..0a9ba4c 100644 --- a/main.tf +++ b/main.tf @@ -13,7 +13,7 @@ module "karpenter_resources" { # Attach additional IAM policies to the Karpenter node IAM role node_iam_role_additional_policies = { - AmazonSSMManagedInstanceCore = format("arn:%v:iam::%v:%%v", data.aws_arn.current.partition, "aws", "policy/AmazonSSMManagedInstanceCore") + AmazonSSMManagedInstanceCore = format("arn:%v:iam::%v:%v", data.aws_arn.current.partition, "aws", "policy/AmazonSSMManagedInstanceCore") # "arn:aws-us-gov:iam::aws:policy/AmazonSSMManagedInstanceCore" } From e04825a05a7fb64756188f13ed7937afb813fcbb Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Tue, 6 Aug 2024 22:57:12 -0400 Subject: [PATCH 14/40] =?UTF-8?q?=E2=9C=A8=20feat(prometheus):=20enables?= =?UTF-8?q?=20serviceMonitor=20to=20captures=20karpenter=20metrics=20in=20?= =?UTF-8?q?prometheus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.tf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main.tf b/main.tf index 0a9ba4c..985adc0 100644 --- a/main.tf +++ b/main.tf @@ -120,6 +120,10 @@ resource "helm_release" "karpenter" { name = "resources.limits.memory" value = "1Gi" } + set { + name = "serviceMonitor.enabled" + value = true + } set { name = "serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn" value = module.karpenter_resources.iam_role_arn From 38582ff52254244018f91598c73edc4abeecc5da Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Tue, 6 Aug 2024 23:34:08 -0400 Subject: [PATCH 15/40] =?UTF-8?q?=E2=9C=A8=20feat(many):=20subnet=20taggin?= =?UTF-8?q?g=20updated=20nodepoolandnodeclass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +++ ec2_node_class.yaml.tpl | 46 ++++++++++++++++++++++++++++++++++++++++- ec2_node_pool.yaml.tpl | 6 ++++-- main.tf | 35 ++++++++++++++++++++++++------- variables.tf | 6 ++++++ 5 files changed, 85 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 0f7c6cc..d2ba762 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | Name | Type | |------|------| +| [aws_ec2_tag.container_subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_tag) | resource | | [aws_iam_instance_profile.karpenter_node_instance_profile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | | [aws_iam_service_linked_role.ec2_spot](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_service_linked_role) | resource | | [helm_release.karpenter](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | @@ -50,6 +51,7 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | | [aws_ecr_image.karpenter_image](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecr_image) | data source | | [aws_iam_roles.roles](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_roles) | data source | +| [aws_subnets.container_subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | ## Inputs @@ -65,6 +67,7 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [profile](#input\_profile) | AWS config profile | `string` | `""` | no | | [region](#input\_region) | AWS region | `string` | n/a | yes | | [tags](#input\_tags) | AWS Tags to apply to appropriate resources | `map(string)` | `{}` | no | +| [vpc\_id](#input\_vpc\_id) | vpc to use for subnet tags | `string` | `""` | no | ## Outputs diff --git a/ec2_node_class.yaml.tpl b/ec2_node_class.yaml.tpl index 668db58..7b73f99 100644 --- a/ec2_node_class.yaml.tpl +++ b/ec2_node_class.yaml.tpl @@ -1,15 +1,59 @@ --- +# apiVersion: karpenter.k8s.aws/v1beta1 +# kind: EC2NodeClass +# metadata: +# name: ${cluster_name}-karpenter-node-class +# spec: +# amiFamily: ${amd_ami_family} +# instanceProfile: "${cluster_name}-karpenter-instance-profile" +# subnetSelectorTerms: +# - tags: +# Name: "*-container-*" +# securityGroupSelectorTerms: +# - tags: +# Name: "${cluster_name}-node" +# tags: ${tags} + apiVersion: karpenter.k8s.aws/v1beta1 kind: EC2NodeClass metadata: name: ${cluster_name}-karpenter-node-class spec: + # Required, resolves a default ami and userdata amiFamily: ${amd_ami_family} - instanceProfile: "${cluster_name}-karpenter-instance-profile" + + # Required, discovers subnets to attach to instances + # Each term in the array of subnetSelectorTerms is ORed together + # Within a single term, all conditions are ANDed subnetSelectorTerms: - tags: + karpenter.sh/discovery: "${CLUSTER_NAME}" Name: "*-container-*" + + # Required, discovers security groups to attach to instances + # Each term in the array of securityGroupSelectorTerms is ORed together + # Within a single term, all conditions are ANDed securityGroupSelectorTerms: - tags: + karpenter.sh/discovery: "${CLUSTER_NAME}" Name: "${cluster_name}-node" + + # Optional, IAM instance profile to use for the node identity. + # Must specify one of "role" or "instanceProfile" for Karpenter to launch nodes + instanceProfile: "${cluster_name}-karpenter_node_instance_profile" + + # Optional, use instance-store volumes for node ephemeral-storage + instanceStorePolicy: RAID0 + + # Optional, propagates tags to underlying EC2 resources tags: ${tags} + + # Optional, configures IMDS for the instance + metadataOptions: + httpEndpoint: enabled + httpProtocolIPv6: disabled + httpPutResponseHopLimit: 2 + httpTokens: required + + # Optional, configures detailed monitoring for the instance + detailedMonitoring: true diff --git a/ec2_node_pool.yaml.tpl b/ec2_node_pool.yaml.tpl index fd4a448..cd10da2 100644 --- a/ec2_node_pool.yaml.tpl +++ b/ec2_node_pool.yaml.tpl @@ -1,5 +1,4 @@ --- -# NodePool for regular EC2 instances apiVersion: karpenter.sh/v1beta1 kind: NodePool metadata: @@ -7,7 +6,7 @@ metadata: spec: disruption: consolidationPolicy: WhenUnderutilized - expireAfter: 4h + expireAfter: 1h template: spec: nodeClassRef: @@ -25,6 +24,9 @@ spec: - c5a.xlarge - r5.large - r5.xlarge + - t3.xlarge + - t3a.xlarge + - t4a.xlarge - key: kubernetes.io/os operator: In values: diff --git a/main.tf b/main.tf index 985adc0..7292c63 100644 --- a/main.tf +++ b/main.tf @@ -2,24 +2,43 @@ locals { namespace = "karpenter" } +data "aws_subnets" "container_subnets" { + filter { + name = "tag:Name" + values = [local.container_subnets_name] + } + filter { + name = "vpc-id" + values = [var.vpc_id] + } +} + # Replicating from here: https://github.e.it.census.gov/SCT-Engineering/terraform-aws-eks/tree/master/modules/karpenter # Karpenter IRSA roles and policies module "karpenter_resources" { source = "git@github.e.it.census.gov:SCT-Engineering/terraform-aws-eks.git//modules/karpenter?ref=v20.20.0" - cluster_name = var.cluster_name - enable_irsa = true - irsa_oidc_provider_arn = var.oidc_provider_arn + cluster_name = var.cluster_name + enable_irsa = true + irsa_oidc_provider_arn = var.oidc_provider_arn + create_pod_identity_association = true # Attach additional IAM policies to the Karpenter node IAM role node_iam_role_additional_policies = { AmazonSSMManagedInstanceCore = format("arn:%v:iam::%v:%v", data.aws_arn.current.partition, "aws", "policy/AmazonSSMManagedInstanceCore") - # "arn:aws-us-gov:iam::aws:policy/AmazonSSMManagedInstanceCore" } tags = var.tags } +# Tag subnets for Karpenter Discovery +resource "aws_ec2_tag" "container_subnets" { + for_each = toset(data.aws_subnets.container_subnets.ids) + resource_id = each.value + key = "karpenter.sh/discovery" + value = var.cluster_name +} + # Install Karpenter data "aws_ecr_image" "karpenter_image" { depends_on = [ @@ -120,10 +139,10 @@ resource "helm_release" "karpenter" { name = "resources.limits.memory" value = "1Gi" } - set { - name = "serviceMonitor.enabled" - value = true - } + # set { + # name = "serviceMonitor.enabled" + # value = true + # } set { name = "serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn" value = module.karpenter_resources.iam_role_arn diff --git a/variables.tf b/variables.tf index 1150802..bce4005 100644 --- a/variables.tf +++ b/variables.tf @@ -53,3 +53,9 @@ variable "tags" { type = map(string) default = {} } + +variable "vpc_id" { + description = "vpc to use for subnet tags" + type = string + default = "" +} From 61b13de470142c60ef584e14a87e5231fcd17b7e Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Tue, 6 Aug 2024 23:42:01 -0400 Subject: [PATCH 16/40] subnets ref --- README.md | 1 + main.tf | 6 ++++-- variables.tf | 6 ++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d2ba762..fc2e7c6 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [oidc\_provider\_arn](#input\_oidc\_provider\_arn) | The ARN of the OIDC Provider if `enable_irsa = true` | `string` | n/a | yes | | [profile](#input\_profile) | AWS config profile | `string` | `""` | no | | [region](#input\_region) | AWS region | `string` | n/a | yes | +| [subnets\_name](#input\_subnets\_name) | Define the name of the subnets to be used by this cluster | `string` | `"*-container-*"` | no | | [tags](#input\_tags) | AWS Tags to apply to appropriate resources | `map(string)` | `{}` | no | | [vpc\_id](#input\_vpc\_id) | vpc to use for subnet tags | `string` | `""` | no | diff --git a/main.tf b/main.tf index 7292c63..d755b7b 100644 --- a/main.tf +++ b/main.tf @@ -1,5 +1,7 @@ locals { - namespace = "karpenter" + namespace = "karpenter" + container_subnets_name = var.subnets_name + vpc_id = var.vpc_id } data "aws_subnets" "container_subnets" { @@ -9,7 +11,7 @@ data "aws_subnets" "container_subnets" { } filter { name = "vpc-id" - values = [var.vpc_id] + values = [local.vpc_id] } } diff --git a/variables.tf b/variables.tf index bce4005..0ce194f 100644 --- a/variables.tf +++ b/variables.tf @@ -48,6 +48,12 @@ variable "karpenter_tag" { default = "0.37.0" } +variable "subnets_name" { + description = "Define the name of the subnets to be used by this cluster" + type = string + default = "*-container-*" +} + variable "tags" { description = "AWS Tags to apply to appropriate resources" type = map(string) From 6ad7b3f573cfa1c161b886c84c63618ff1d2fa3c Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Tue, 6 Aug 2024 23:43:28 -0400 Subject: [PATCH 17/40] cleanup --- ec2_node_class.yaml.tpl | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/ec2_node_class.yaml.tpl b/ec2_node_class.yaml.tpl index 7b73f99..617d8f4 100644 --- a/ec2_node_class.yaml.tpl +++ b/ec2_node_class.yaml.tpl @@ -1,19 +1,4 @@ --- -# apiVersion: karpenter.k8s.aws/v1beta1 -# kind: EC2NodeClass -# metadata: -# name: ${cluster_name}-karpenter-node-class -# spec: -# amiFamily: ${amd_ami_family} -# instanceProfile: "${cluster_name}-karpenter-instance-profile" -# subnetSelectorTerms: -# - tags: -# Name: "*-container-*" -# securityGroupSelectorTerms: -# - tags: -# Name: "${cluster_name}-node" -# tags: ${tags} - apiVersion: karpenter.k8s.aws/v1beta1 kind: EC2NodeClass metadata: @@ -27,7 +12,7 @@ spec: # Within a single term, all conditions are ANDed subnetSelectorTerms: - tags: - karpenter.sh/discovery: "${CLUSTER_NAME}" + karpenter.sh/discovery: "${cluster_name}" Name: "*-container-*" # Required, discovers security groups to attach to instances @@ -35,7 +20,7 @@ spec: # Within a single term, all conditions are ANDed securityGroupSelectorTerms: - tags: - karpenter.sh/discovery: "${CLUSTER_NAME}" + karpenter.sh/discovery: "${cluster_name}" Name: "${cluster_name}-node" # Optional, IAM instance profile to use for the node identity. From 324c45f382b8876f1578bfc1c276d23afc95c65f Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Tue, 6 Aug 2024 23:48:42 -0400 Subject: [PATCH 18/40] simpler securitygroup selector --- ec2_node_class.yaml.tpl | 1 - 1 file changed, 1 deletion(-) diff --git a/ec2_node_class.yaml.tpl b/ec2_node_class.yaml.tpl index 617d8f4..c6c1112 100644 --- a/ec2_node_class.yaml.tpl +++ b/ec2_node_class.yaml.tpl @@ -20,7 +20,6 @@ spec: # Within a single term, all conditions are ANDed securityGroupSelectorTerms: - tags: - karpenter.sh/discovery: "${cluster_name}" Name: "${cluster_name}-node" # Optional, IAM instance profile to use for the node identity. From 9fca10c847f9c9d1bb43154e4a58cb69237475be Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Tue, 6 Aug 2024 23:53:26 -0400 Subject: [PATCH 19/40] fix profilename --- ec2_node_class.yaml.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ec2_node_class.yaml.tpl b/ec2_node_class.yaml.tpl index c6c1112..73fbfc3 100644 --- a/ec2_node_class.yaml.tpl +++ b/ec2_node_class.yaml.tpl @@ -24,7 +24,7 @@ spec: # Optional, IAM instance profile to use for the node identity. # Must specify one of "role" or "instanceProfile" for Karpenter to launch nodes - instanceProfile: "${cluster_name}-karpenter_node_instance_profile" + instanceProfile: "${cluster_name}-karpenter-instance-profile" # Optional, use instance-store volumes for node ephemeral-storage instanceStorePolicy: RAID0 From 99783919af121d69d943bbab14b15a4f7b6a72f3 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 7 Aug 2024 13:13:49 -0400 Subject: [PATCH 20/40] add custom suffix to service-linked-role --- main.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/main.tf b/main.tf index d755b7b..89b6c79 100644 --- a/main.tf +++ b/main.tf @@ -168,6 +168,7 @@ data "aws_iam_roles" "roles" { resource "aws_iam_service_linked_role" "ec2_spot" { count = data.aws_iam_roles.roles == null ? 1 : 0 aws_service_name = "spot.amazonaws.com" + custom_suffix = var.cluster_name } From 2df93b7503985d187571573dbe7d65566159c731 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 7 Aug 2024 13:23:33 -0400 Subject: [PATCH 21/40] update data item query --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 89b6c79..9225f9f 100644 --- a/main.tf +++ b/main.tf @@ -161,7 +161,7 @@ resource "aws_iam_instance_profile" "karpenter_node_instance_profile" { # Query to see if service-linked role exists data "aws_iam_roles" "roles" { - path_prefix = "/aws-reserved/spot.amazonaws.com/" + path_prefix = "/aws-reserved/spot.amazonaws.com/${var.cluster_name}" } # Permission for spot From 5000b679a9dcca70505f905307a373a09fc8708c Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 7 Aug 2024 15:45:03 -0400 Subject: [PATCH 22/40] no tag filtering in subet --- ec2_node_class.yaml.tpl | 2 +- main.tf | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/ec2_node_class.yaml.tpl b/ec2_node_class.yaml.tpl index 73fbfc3..2c4d271 100644 --- a/ec2_node_class.yaml.tpl +++ b/ec2_node_class.yaml.tpl @@ -12,8 +12,8 @@ spec: # Within a single term, all conditions are ANDed subnetSelectorTerms: - tags: - karpenter.sh/discovery: "${cluster_name}" Name: "*-container-*" + # karpenter.sh/discovery: "${cluster_name}" # Required, discovers security groups to attach to instances # Each term in the array of securityGroupSelectorTerms is ORed together diff --git a/main.tf b/main.tf index 9225f9f..8d80356 100644 --- a/main.tf +++ b/main.tf @@ -141,10 +141,6 @@ resource "helm_release" "karpenter" { name = "resources.limits.memory" value = "1Gi" } - # set { - # name = "serviceMonitor.enabled" - # value = true - # } set { name = "serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn" value = module.karpenter_resources.iam_role_arn @@ -153,7 +149,6 @@ resource "helm_release" "karpenter" { timeout = 300 } - resource "aws_iam_instance_profile" "karpenter_node_instance_profile" { name = "${var.cluster_name}-karpenter-instance-profile" role = module.karpenter_resources.node_iam_role_name @@ -172,15 +167,6 @@ resource "aws_iam_service_linked_role" "ec2_spot" { } -# Lookup eks amis // didn't use this but would be path to get to mixed architectures/processors -# data "aws_ssm_parameter" "arm_ami_id" { -# name = "/aws/service/eks/optimized-ami/1.30/bottlerocket-arm64/recommended/image_id" -# } - -# data "aws_ssm_parameter" "amd_ami_id" { -# name = "/aws/service/eks/optimized-ami/1.30/bottlerocket-x86_64/recommended/image_id" -# } - # SHOULD PROBABLY PUT THESE OBJECTS INTO A HELM CHART # Create karpenter default resource "kubectl_manifest" "karpenter_ec2_node_class" { From 48ecaabdd00a9ed53a0e10c46c85baff9a8b72c4 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 7 Aug 2024 16:11:41 -0400 Subject: [PATCH 23/40] yamlencode --- ec2_node_class.yaml.tpl | 4 ++-- main.tf | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/ec2_node_class.yaml.tpl b/ec2_node_class.yaml.tpl index 2c4d271..a8f6b1e 100644 --- a/ec2_node_class.yaml.tpl +++ b/ec2_node_class.yaml.tpl @@ -30,12 +30,12 @@ spec: instanceStorePolicy: RAID0 # Optional, propagates tags to underlying EC2 resources - tags: ${tags} + tags: "${tags}" # Optional, configures IMDS for the instance metadataOptions: httpEndpoint: enabled - httpProtocolIPv6: disabled + httpProtocolIPv6: enabled httpPutResponseHopLimit: 2 httpTokens: required diff --git a/main.tf b/main.tf index 8d80356..60bec2d 100644 --- a/main.tf +++ b/main.tf @@ -176,8 +176,7 @@ resource "kubectl_manifest" "karpenter_ec2_node_class" { yaml_body = templatefile("${path.module}/ec2_node_class.yaml.tpl", { cluster_name = var.cluster_name amd_ami_family = "Bottlerocket" - - tags = jsonencode(var.tags) + tags = yamlencode(var.tags) }) } From d5a84adfc962995de2fa94b3d45fea1ba2292c52 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 7 Aug 2024 16:17:05 -0400 Subject: [PATCH 24/40] jsonencode --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 60bec2d..c0aa0e4 100644 --- a/main.tf +++ b/main.tf @@ -176,7 +176,7 @@ resource "kubectl_manifest" "karpenter_ec2_node_class" { yaml_body = templatefile("${path.module}/ec2_node_class.yaml.tpl", { cluster_name = var.cluster_name amd_ami_family = "Bottlerocket" - tags = yamlencode(var.tags) + tags = jsonencode(var.tags) }) } From 6c4ee2c7bdc465a70b816d5e55b2c078be1e3ae1 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 7 Aug 2024 17:52:29 -0400 Subject: [PATCH 25/40] drop tags from node_class template --- ec2_node_class.yaml.tpl | 2 +- main.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ec2_node_class.yaml.tpl b/ec2_node_class.yaml.tpl index a8f6b1e..01c6597 100644 --- a/ec2_node_class.yaml.tpl +++ b/ec2_node_class.yaml.tpl @@ -30,7 +30,7 @@ spec: instanceStorePolicy: RAID0 # Optional, propagates tags to underlying EC2 resources - tags: "${tags}" + # tags: "${tags}" # Optional, configures IMDS for the instance metadataOptions: diff --git a/main.tf b/main.tf index c0aa0e4..11fb507 100644 --- a/main.tf +++ b/main.tf @@ -176,7 +176,7 @@ resource "kubectl_manifest" "karpenter_ec2_node_class" { yaml_body = templatefile("${path.module}/ec2_node_class.yaml.tpl", { cluster_name = var.cluster_name amd_ami_family = "Bottlerocket" - tags = jsonencode(var.tags) + # tags = jsonencode(var.tags) }) } From 0a4118be59b2c94a3a83093149a0be0e123481b3 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Wed, 7 Aug 2024 17:54:44 -0400 Subject: [PATCH 26/40] remove i said --- ec2_node_class.yaml.tpl | 3 --- main.tf | 1 - 2 files changed, 4 deletions(-) diff --git a/ec2_node_class.yaml.tpl b/ec2_node_class.yaml.tpl index 01c6597..28d052e 100644 --- a/ec2_node_class.yaml.tpl +++ b/ec2_node_class.yaml.tpl @@ -29,9 +29,6 @@ spec: # Optional, use instance-store volumes for node ephemeral-storage instanceStorePolicy: RAID0 - # Optional, propagates tags to underlying EC2 resources - # tags: "${tags}" - # Optional, configures IMDS for the instance metadataOptions: httpEndpoint: enabled diff --git a/main.tf b/main.tf index 11fb507..c81ff74 100644 --- a/main.tf +++ b/main.tf @@ -176,7 +176,6 @@ resource "kubectl_manifest" "karpenter_ec2_node_class" { yaml_body = templatefile("${path.module}/ec2_node_class.yaml.tpl", { cluster_name = var.cluster_name amd_ami_family = "Bottlerocket" - # tags = jsonencode(var.tags) }) } From bc7ad84f885ab611413632b478475f1883e887e6 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 19 Aug 2024 14:07:00 -0400 Subject: [PATCH 27/40] bump for 1.0 release --- README.md | 8 ++++---- main.tf | 2 +- variables.tf | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index fc2e7c6..54c05d6 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | Name | Source | Version | |------|--------|---------| | [images](#module\_images) | git@github.e.it.census.gov:terraform-modules/aws-ecr-copy-images.git/ | tf-upgrade | -| [karpenter\_resources](#module\_karpenter\_resources) | git@github.e.it.census.gov:SCT-Engineering/terraform-aws-eks.git//modules/karpenter | v20.20.0 | +| [karpenter\_resources](#module\_karpenter\_resources) | git@github.e.it.census.gov:SCT-Engineering/terraform-aws-eks.git//modules/karpenter | v20.23.0 | ## Resources @@ -59,10 +59,10 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the |------|-------------|------|---------|:--------:| | [cluster\_endpoint](#input\_cluster\_endpoint) | Endpoint for your Kubernetes API server | `string` | n/a | yes | | [cluster\_name](#input\_cluster\_name) | EKS cluster name name component used through out the EKS cluster describing its purpose (ex: dice-dev) | `string` | n/a | yes | -| [karpenter\_helm\_chart](#input\_karpenter\_helm\_chart) | Which helm chart of karpenter | `string` | `"0.37.0"` | no | -| [karpenter\_helm\_repo](#input\_karpenter\_helm\_repo) | Helm repo for official karpenter chart | `string` | `"oci://public.ecr.aws/karpenter"` | no | +| [karpenter\_helm\_chart](#input\_karpenter\_helm\_chart) | Which helm chart of karpenter | `string` | `"1.0.0"` | no | +| [karpenter\_helm\_repo](#input\_karpenter\_helm\_repo) | Helm repo for official karpenter chart | `string` | `"oci://public.ecr.aws/karpenter/karpenter"` | no | | [karpenter\_node\_group\_name](#input\_karpenter\_node\_group\_name) | The cluster node group that will host karpenter, should not be a karpenter managed node group | `string` | n/a | yes | -| [karpenter\_tag](#input\_karpenter\_tag) | Which tag of karpenter image | `string` | `"0.37.0"` | no | +| [karpenter\_tag](#input\_karpenter\_tag) | Which tag of karpenter image | `string` | `"1.0.0"` | no | | [oidc\_provider\_arn](#input\_oidc\_provider\_arn) | The ARN of the OIDC Provider if `enable_irsa = true` | `string` | n/a | yes | | [profile](#input\_profile) | AWS config profile | `string` | `""` | no | | [region](#input\_region) | AWS region | `string` | n/a | yes | diff --git a/main.tf b/main.tf index c81ff74..46df2e9 100644 --- a/main.tf +++ b/main.tf @@ -18,7 +18,7 @@ data "aws_subnets" "container_subnets" { # Replicating from here: https://github.e.it.census.gov/SCT-Engineering/terraform-aws-eks/tree/master/modules/karpenter # Karpenter IRSA roles and policies module "karpenter_resources" { - source = "git@github.e.it.census.gov:SCT-Engineering/terraform-aws-eks.git//modules/karpenter?ref=v20.20.0" + source = "git@github.e.it.census.gov:SCT-Engineering/terraform-aws-eks.git//modules/karpenter?ref=v20.23.0" cluster_name = var.cluster_name enable_irsa = true diff --git a/variables.tf b/variables.tf index 0ce194f..3643bd5 100644 --- a/variables.tf +++ b/variables.tf @@ -32,20 +32,20 @@ variable "karpenter_node_group_name" { variable "karpenter_helm_repo" { description = "Helm repo for official karpenter chart" type = string - default = "oci://public.ecr.aws/karpenter" + default = "oci://public.ecr.aws/karpenter/karpenter" # default = "https://charts.karpenter.sh/" public.ecr.aws/karpenter/karpenter:0.37.0 } variable "karpenter_helm_chart" { description = "Which helm chart of karpenter" type = string - default = "0.37.0" + default = "1.0.0" } variable "karpenter_tag" { description = "Which tag of karpenter image" type = string - default = "0.37.0" + default = "1.0.0" } variable "subnets_name" { From e89cd548e121807376e3c7cdf8d9691f5134673d Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 19 Aug 2024 14:11:47 -0400 Subject: [PATCH 28/40] revert change to chart repo --- README.md | 2 +- variables.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 54c05d6..cec0dd5 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [cluster\_endpoint](#input\_cluster\_endpoint) | Endpoint for your Kubernetes API server | `string` | n/a | yes | | [cluster\_name](#input\_cluster\_name) | EKS cluster name name component used through out the EKS cluster describing its purpose (ex: dice-dev) | `string` | n/a | yes | | [karpenter\_helm\_chart](#input\_karpenter\_helm\_chart) | Which helm chart of karpenter | `string` | `"1.0.0"` | no | -| [karpenter\_helm\_repo](#input\_karpenter\_helm\_repo) | Helm repo for official karpenter chart | `string` | `"oci://public.ecr.aws/karpenter/karpenter"` | no | +| [karpenter\_helm\_repo](#input\_karpenter\_helm\_repo) | Helm repo for official karpenter chart | `string` | `"oci://public.ecr.aws/karpenter"` | no | | [karpenter\_node\_group\_name](#input\_karpenter\_node\_group\_name) | The cluster node group that will host karpenter, should not be a karpenter managed node group | `string` | n/a | yes | | [karpenter\_tag](#input\_karpenter\_tag) | Which tag of karpenter image | `string` | `"1.0.0"` | no | | [oidc\_provider\_arn](#input\_oidc\_provider\_arn) | The ARN of the OIDC Provider if `enable_irsa = true` | `string` | n/a | yes | diff --git a/variables.tf b/variables.tf index 3643bd5..b4a2031 100644 --- a/variables.tf +++ b/variables.tf @@ -32,7 +32,7 @@ variable "karpenter_node_group_name" { variable "karpenter_helm_repo" { description = "Helm repo for official karpenter chart" type = string - default = "oci://public.ecr.aws/karpenter/karpenter" + default = "oci://public.ecr.aws/karpenter" # default = "https://charts.karpenter.sh/" public.ecr.aws/karpenter/karpenter:0.37.0 } From 10a9afc866382b6fe692377cdd2e1d80fe534a60 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 19 Aug 2024 18:39:16 -0400 Subject: [PATCH 29/40] =?UTF-8?q?=E2=9C=A8=20feat(karpenter):=20update=20m?= =?UTF-8?q?odule=20upstream=20to=201.0.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + copy_images.tf | 10 ++++++++++ ec2_node_class.yaml.tpl | 2 +- ec2_node_pool.yaml.tpl | 2 +- variables.tf | 6 ++++++ 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cec0dd5..ca9b10a 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [karpenter\_helm\_repo](#input\_karpenter\_helm\_repo) | Helm repo for official karpenter chart | `string` | `"oci://public.ecr.aws/karpenter"` | no | | [karpenter\_node\_group\_name](#input\_karpenter\_node\_group\_name) | The cluster node group that will host karpenter, should not be a karpenter managed node group | `string` | n/a | yes | | [karpenter\_tag](#input\_karpenter\_tag) | Which tag of karpenter image | `string` | `"1.0.0"` | no | +| [kubectl\_tag](#input\_kubectl\_tag) | Which tag of kubectl image | `string` | `"1.3.0"` | no | | [oidc\_provider\_arn](#input\_oidc\_provider\_arn) | The ARN of the OIDC Provider if `enable_irsa = true` | `string` | n/a | yes | | [profile](#input\_profile) | AWS config profile | `string` | `""` | no | | [region](#input\_region) | AWS region | `string` | n/a | yes | diff --git a/copy_images.tf b/copy_images.tf index 4c05c03..810e87b 100644 --- a/copy_images.tf +++ b/copy_images.tf @@ -1,5 +1,6 @@ locals { karpenter_key = format("%v#%v", "karpenter/controller", var.karpenter_tag) + # kubectl_key = format("%v#%v", "bitnami/kubectl", var.kubectl_tag) image_config = [ { @@ -11,6 +12,15 @@ locals { source_tag = var.karpenter_tag tag = var.karpenter_tag }, + { + enabled = true + dest_path = null + name = "bitnami/kubectl" + source_image = "bitnami/kubectl" + source_registry = "public.ecr.aws" + source_tag = var.kubectl_tag + tag = var.kubectl_tag + }, ] } diff --git a/ec2_node_class.yaml.tpl b/ec2_node_class.yaml.tpl index 28d052e..ce854a5 100644 --- a/ec2_node_class.yaml.tpl +++ b/ec2_node_class.yaml.tpl @@ -1,5 +1,5 @@ --- -apiVersion: karpenter.k8s.aws/v1beta1 +apiVersion: karpenter.k8s.aws/v1 kind: EC2NodeClass metadata: name: ${cluster_name}-karpenter-node-class diff --git a/ec2_node_pool.yaml.tpl b/ec2_node_pool.yaml.tpl index cd10da2..88285f4 100644 --- a/ec2_node_pool.yaml.tpl +++ b/ec2_node_pool.yaml.tpl @@ -1,5 +1,5 @@ --- -apiVersion: karpenter.sh/v1beta1 +apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: ${cluster_name}-node-pool-general diff --git a/variables.tf b/variables.tf index b4a2031..5b2ee35 100644 --- a/variables.tf +++ b/variables.tf @@ -48,6 +48,12 @@ variable "karpenter_tag" { default = "1.0.0" } +variable "kubectl_tag" { + description = "Which tag of kubectl image" + type = string + default = "1.3.0" +} + variable "subnets_name" { description = "Define the name of the subnets to be used by this cluster" type = string From 3d5d881f855b23d474eb43cb7dae82d834d56263 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 19 Aug 2024 18:48:19 -0400 Subject: [PATCH 30/40] update to pull image from docker.io for kubectl --- copy_images.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copy_images.tf b/copy_images.tf index 810e87b..33d6b6c 100644 --- a/copy_images.tf +++ b/copy_images.tf @@ -17,7 +17,7 @@ locals { dest_path = null name = "bitnami/kubectl" source_image = "bitnami/kubectl" - source_registry = "public.ecr.aws" + source_registry = "docker.io" source_tag = var.kubectl_tag tag = var.kubectl_tag }, From 3ee4974261b3813c31b637b4227a638b5cb67809 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 19 Aug 2024 19:01:19 -0400 Subject: [PATCH 31/40] =?UTF-8?q?=F0=9F=90=9B=20fix(kubectl):=20fixes=20fo?= =?UTF-8?q?r=20kubectl=20image?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- copy_images.tf | 2 +- variables.tf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ca9b10a..618a2a6 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [karpenter\_helm\_repo](#input\_karpenter\_helm\_repo) | Helm repo for official karpenter chart | `string` | `"oci://public.ecr.aws/karpenter"` | no | | [karpenter\_node\_group\_name](#input\_karpenter\_node\_group\_name) | The cluster node group that will host karpenter, should not be a karpenter managed node group | `string` | n/a | yes | | [karpenter\_tag](#input\_karpenter\_tag) | Which tag of karpenter image | `string` | `"1.0.0"` | no | -| [kubectl\_tag](#input\_kubectl\_tag) | Which tag of kubectl image | `string` | `"1.3.0"` | no | +| [kubectl\_tag](#input\_kubectl\_tag) | Which tag of kubectl image | `string` | `"v1.3.0"` | no | | [oidc\_provider\_arn](#input\_oidc\_provider\_arn) | The ARN of the OIDC Provider if `enable_irsa = true` | `string` | n/a | yes | | [profile](#input\_profile) | AWS config profile | `string` | `""` | no | | [region](#input\_region) | AWS region | `string` | n/a | yes | diff --git a/copy_images.tf b/copy_images.tf index 33d6b6c..3aa623c 100644 --- a/copy_images.tf +++ b/copy_images.tf @@ -15,7 +15,7 @@ locals { { enabled = true dest_path = null - name = "bitnami/kubectl" + name = "kubectl" source_image = "bitnami/kubectl" source_registry = "docker.io" source_tag = var.kubectl_tag diff --git a/variables.tf b/variables.tf index 5b2ee35..785ff05 100644 --- a/variables.tf +++ b/variables.tf @@ -51,7 +51,7 @@ variable "karpenter_tag" { variable "kubectl_tag" { description = "Which tag of kubectl image" type = string - default = "1.3.0" + default = "v1.3.0" } variable "subnets_name" { From 33a703af928d4abbfcca362a6d1df52419246a4b Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 19 Aug 2024 19:05:49 -0400 Subject: [PATCH 32/40] minus v --- README.md | 2 +- variables.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 618a2a6..ca9b10a 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [karpenter\_helm\_repo](#input\_karpenter\_helm\_repo) | Helm repo for official karpenter chart | `string` | `"oci://public.ecr.aws/karpenter"` | no | | [karpenter\_node\_group\_name](#input\_karpenter\_node\_group\_name) | The cluster node group that will host karpenter, should not be a karpenter managed node group | `string` | n/a | yes | | [karpenter\_tag](#input\_karpenter\_tag) | Which tag of karpenter image | `string` | `"1.0.0"` | no | -| [kubectl\_tag](#input\_kubectl\_tag) | Which tag of kubectl image | `string` | `"v1.3.0"` | no | +| [kubectl\_tag](#input\_kubectl\_tag) | Which tag of kubectl image | `string` | `"1.3.0"` | no | | [oidc\_provider\_arn](#input\_oidc\_provider\_arn) | The ARN of the OIDC Provider if `enable_irsa = true` | `string` | n/a | yes | | [profile](#input\_profile) | AWS config profile | `string` | `""` | no | | [region](#input\_region) | AWS region | `string` | n/a | yes | diff --git a/variables.tf b/variables.tf index 785ff05..5b2ee35 100644 --- a/variables.tf +++ b/variables.tf @@ -51,7 +51,7 @@ variable "karpenter_tag" { variable "kubectl_tag" { description = "Which tag of kubectl image" type = string - default = "v1.3.0" + default = "1.3.0" } variable "subnets_name" { From 2b3875fdf867899fa45282b20f2c86cf3d0823ed Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 19 Aug 2024 19:39:55 -0400 Subject: [PATCH 33/40] add images to helm --- README.md | 5 ++++- copy_images.tf | 12 +++++++++++- main.tf | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ variables.tf | 8 +++++++- 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ca9b10a..ea1f33e 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,8 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [aws_arn.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source | | [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | | [aws_ecr_image.karpenter_image](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecr_image) | data source | +| [aws_ecr_image.kubectl_image](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecr_image) | data source | +| [aws_ecr_image.webhook_image](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecr_image) | data source | | [aws_iam_roles.roles](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_roles) | data source | | [aws_subnets.container_subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | @@ -63,13 +65,14 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [karpenter\_helm\_repo](#input\_karpenter\_helm\_repo) | Helm repo for official karpenter chart | `string` | `"oci://public.ecr.aws/karpenter"` | no | | [karpenter\_node\_group\_name](#input\_karpenter\_node\_group\_name) | The cluster node group that will host karpenter, should not be a karpenter managed node group | `string` | n/a | yes | | [karpenter\_tag](#input\_karpenter\_tag) | Which tag of karpenter image | `string` | `"1.0.0"` | no | -| [kubectl\_tag](#input\_kubectl\_tag) | Which tag of kubectl image | `string` | `"1.3.0"` | no | +| [kubectl\_tag](#input\_kubectl\_tag) | Which tag of kubectl image | `string` | `"1.27.14"` | no | | [oidc\_provider\_arn](#input\_oidc\_provider\_arn) | The ARN of the OIDC Provider if `enable_irsa = true` | `string` | n/a | yes | | [profile](#input\_profile) | AWS config profile | `string` | `""` | no | | [region](#input\_region) | AWS region | `string` | n/a | yes | | [subnets\_name](#input\_subnets\_name) | Define the name of the subnets to be used by this cluster | `string` | `"*-container-*"` | no | | [tags](#input\_tags) | AWS Tags to apply to appropriate resources | `map(string)` | `{}` | no | | [vpc\_id](#input\_vpc\_id) | vpc to use for subnet tags | `string` | `""` | no | +| [webhook\_tag](#input\_webhook\_tag) | Which tag of karpenter/webhook image | `string` | `"1.0.0"` | no | ## Outputs diff --git a/copy_images.tf b/copy_images.tf index 3aa623c..2d6d151 100644 --- a/copy_images.tf +++ b/copy_images.tf @@ -1,6 +1,7 @@ locals { karpenter_key = format("%v#%v", "karpenter/controller", var.karpenter_tag) - # kubectl_key = format("%v#%v", "bitnami/kubectl", var.kubectl_tag) + kubectl_key = format("%v#%v", "bitnami/kubectl", var.kubectl_tag) + webhook_key = format("%v#%v", "karpenter/webhook", var.webhook_tag) image_config = [ { @@ -12,6 +13,15 @@ locals { source_tag = var.karpenter_tag tag = var.karpenter_tag }, + { + enabled = true + dest_path = null + name = "karpenter/webhook" + source_image = "karpenter/webhook" + source_registry = "public.ecr.aws" + source_tag = var.webhook_tag + tag = var.webhook_tag + }, { enabled = true dest_path = null diff --git a/main.tf b/main.tf index 46df2e9..f77b079 100644 --- a/main.tf +++ b/main.tf @@ -50,6 +50,22 @@ data "aws_ecr_image" "karpenter_image" { image_tag = module.images.images[local.karpenter_key].tag } +data "aws_ecr_image" "kubectl_image" { + depends_on = [ + module.images, + ] + repository_name = module.images.images[local.kubectl_key].dest_repository + image_tag = module.images.images[local.kubectl_key].tag +} + +data "aws_ecr_image" "webhook_image" { + depends_on = [ + module.images, + ] + repository_name = module.images.images[local.webhook_key].dest_repository + image_tag = module.images.images[local.webhook_key].tag +} + resource "helm_release" "karpenter" { depends_on = [ data.aws_ecr_image.karpenter_image @@ -94,6 +110,10 @@ resource "helm_release" "karpenter" { name = "settings.clusterEndpoint" value = var.cluster_endpoint } + set { + name = "settings.featureGates.spotToSpotConsolidation" + value = "true" + } set { name = "settings.interruptionQueue" value = module.karpenter_resources.queue_name @@ -117,6 +137,36 @@ resource "helm_release" "karpenter" { name = "controller.image.digest" value = data.aws_ecr_image.karpenter_image.id } + set { + name = "postInstallHook.image.repository" + value = format("%v/%v", + module.images.images[local.kubectl_key].dest_registry, + module.images.images[local.kubectl_key].dest_repository + ) + } + set { + name = "postInstallHook.image.tag" + value = module.images.images[local.kubectl_key].tag + } + set { + name = "postInstallHook.image.digest" + value = data.aws_ecr_image.kubectl_image.id + } + set { + name = "webhook.image.repository" + value = format("%v/%v", + module.images.images[local.webhook_key].dest_registry, + module.images.images[local.webhook_key].dest_repository + ) + } + set { + name = "webhook.image.tag" + value = module.images.images[local.webhook_key].tag + } + set { + name = "webhook.image.digest" + value = data.aws_ecr_image.webhook_image.id + } set { name = "controller.env[0].name" value = "AWS_REGION" diff --git a/variables.tf b/variables.tf index 5b2ee35..a956725 100644 --- a/variables.tf +++ b/variables.tf @@ -48,10 +48,16 @@ variable "karpenter_tag" { default = "1.0.0" } +variable "webhook_tag" { + description = "Which tag of karpenter/webhook image" + type = string + default = "1.0.0" +} + variable "kubectl_tag" { description = "Which tag of kubectl image" type = string - default = "1.3.0" + default = "1.27.14" } variable "subnets_name" { From d247ce68e5335157b41c72f27270cc0c4e78cb42 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 19 Aug 2024 19:41:46 -0400 Subject: [PATCH 34/40] update version for kubectl --- README.md | 2 +- variables.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ea1f33e..e81d304 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [karpenter\_helm\_repo](#input\_karpenter\_helm\_repo) | Helm repo for official karpenter chart | `string` | `"oci://public.ecr.aws/karpenter"` | no | | [karpenter\_node\_group\_name](#input\_karpenter\_node\_group\_name) | The cluster node group that will host karpenter, should not be a karpenter managed node group | `string` | n/a | yes | | [karpenter\_tag](#input\_karpenter\_tag) | Which tag of karpenter image | `string` | `"1.0.0"` | no | -| [kubectl\_tag](#input\_kubectl\_tag) | Which tag of kubectl image | `string` | `"1.27.14"` | no | +| [kubectl\_tag](#input\_kubectl\_tag) | Which tag of kubectl image | `string` | `"1.30.4"` | no | | [oidc\_provider\_arn](#input\_oidc\_provider\_arn) | The ARN of the OIDC Provider if `enable_irsa = true` | `string` | n/a | yes | | [profile](#input\_profile) | AWS config profile | `string` | `""` | no | | [region](#input\_region) | AWS region | `string` | n/a | yes | diff --git a/variables.tf b/variables.tf index a956725..087f7c5 100644 --- a/variables.tf +++ b/variables.tf @@ -57,7 +57,7 @@ variable "webhook_tag" { variable "kubectl_tag" { description = "Which tag of kubectl image" type = string - default = "1.27.14" + default = "1.30.4" } variable "subnets_name" { From a471e0a0780b58210c04ec00d3a6025c23e65654 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 19 Aug 2024 19:44:05 -0400 Subject: [PATCH 35/40] yep --- copy_images.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copy_images.tf b/copy_images.tf index 2d6d151..1973ed6 100644 --- a/copy_images.tf +++ b/copy_images.tf @@ -1,6 +1,6 @@ locals { karpenter_key = format("%v#%v", "karpenter/controller", var.karpenter_tag) - kubectl_key = format("%v#%v", "bitnami/kubectl", var.kubectl_tag) + kubectl_key = format("%v#%v", "kubectl", var.kubectl_tag) webhook_key = format("%v#%v", "karpenter/webhook", var.webhook_tag) image_config = [ From d76f3ea1b5773804759e635aa46a1212d1a97336 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 19 Aug 2024 19:49:43 -0400 Subject: [PATCH 36/40] wtfwasithinking --- README.md | 2 -- copy_images.tf | 10 ---------- main.tf | 23 ----------------------- variables.tf | 6 ------ 4 files changed, 41 deletions(-) diff --git a/README.md b/README.md index e81d304..5fc006a 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,6 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | | [aws_ecr_image.karpenter_image](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecr_image) | data source | | [aws_ecr_image.kubectl_image](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecr_image) | data source | -| [aws_ecr_image.webhook_image](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecr_image) | data source | | [aws_iam_roles.roles](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_roles) | data source | | [aws_subnets.container_subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | @@ -72,7 +71,6 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [subnets\_name](#input\_subnets\_name) | Define the name of the subnets to be used by this cluster | `string` | `"*-container-*"` | no | | [tags](#input\_tags) | AWS Tags to apply to appropriate resources | `map(string)` | `{}` | no | | [vpc\_id](#input\_vpc\_id) | vpc to use for subnet tags | `string` | `""` | no | -| [webhook\_tag](#input\_webhook\_tag) | Which tag of karpenter/webhook image | `string` | `"1.0.0"` | no | ## Outputs diff --git a/copy_images.tf b/copy_images.tf index 1973ed6..f6dd157 100644 --- a/copy_images.tf +++ b/copy_images.tf @@ -1,7 +1,6 @@ locals { karpenter_key = format("%v#%v", "karpenter/controller", var.karpenter_tag) kubectl_key = format("%v#%v", "kubectl", var.kubectl_tag) - webhook_key = format("%v#%v", "karpenter/webhook", var.webhook_tag) image_config = [ { @@ -13,15 +12,6 @@ locals { source_tag = var.karpenter_tag tag = var.karpenter_tag }, - { - enabled = true - dest_path = null - name = "karpenter/webhook" - source_image = "karpenter/webhook" - source_registry = "public.ecr.aws" - source_tag = var.webhook_tag - tag = var.webhook_tag - }, { enabled = true dest_path = null diff --git a/main.tf b/main.tf index f77b079..4d2d1ab 100644 --- a/main.tf +++ b/main.tf @@ -58,14 +58,6 @@ data "aws_ecr_image" "kubectl_image" { image_tag = module.images.images[local.kubectl_key].tag } -data "aws_ecr_image" "webhook_image" { - depends_on = [ - module.images, - ] - repository_name = module.images.images[local.webhook_key].dest_repository - image_tag = module.images.images[local.webhook_key].tag -} - resource "helm_release" "karpenter" { depends_on = [ data.aws_ecr_image.karpenter_image @@ -152,21 +144,6 @@ resource "helm_release" "karpenter" { name = "postInstallHook.image.digest" value = data.aws_ecr_image.kubectl_image.id } - set { - name = "webhook.image.repository" - value = format("%v/%v", - module.images.images[local.webhook_key].dest_registry, - module.images.images[local.webhook_key].dest_repository - ) - } - set { - name = "webhook.image.tag" - value = module.images.images[local.webhook_key].tag - } - set { - name = "webhook.image.digest" - value = data.aws_ecr_image.webhook_image.id - } set { name = "controller.env[0].name" value = "AWS_REGION" diff --git a/variables.tf b/variables.tf index 087f7c5..03fe6f9 100644 --- a/variables.tf +++ b/variables.tf @@ -48,12 +48,6 @@ variable "karpenter_tag" { default = "1.0.0" } -variable "webhook_tag" { - description = "Which tag of karpenter/webhook image" - type = string - default = "1.0.0" -} - variable "kubectl_tag" { description = "Which tag of kubectl image" type = string From 2e838496bc8171db3acaba575bf7ad5432c90178 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 19 Aug 2024 19:59:45 -0400 Subject: [PATCH 37/40] update ec2nodeClass --- ec2_node_class.yaml.tpl | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/ec2_node_class.yaml.tpl b/ec2_node_class.yaml.tpl index ce854a5..facebf0 100644 --- a/ec2_node_class.yaml.tpl +++ b/ec2_node_class.yaml.tpl @@ -4,9 +4,38 @@ kind: EC2NodeClass metadata: name: ${cluster_name}-karpenter-node-class spec: + kubelet: + podsPerCore: 2 + maxPods: 20 + systemReserved: + cpu: 100m + memory: 100Mi + ephemeral-storage: 1Gi + kubeReserved: + cpu: 200m + memory: 100Mi + ephemeral-storage: 3Gi + evictionHard: + memory.available: 5% + nodefs.available: 10% + nodefs.inodesFree: 10% + evictionSoft: + memory.available: 500Mi + nodefs.available: 15% + nodefs.inodesFree: 15% + evictionSoftGracePeriod: + memory.available: 1m + nodefs.available: 1m30s + nodefs.inodesFree: 2m + evictionMaxPodGracePeriod: 60 + imageGCHighThresholdPercent: 85 + imageGCLowThresholdPercent: 80 + cpuCFSQuota: true + # Required, resolves a default ami and userdata amiFamily: ${amd_ami_family} - + amiSelectorTerms: + - alias: bottlerocket@latest # Required, discovers subnets to attach to instances # Each term in the array of subnetSelectorTerms is ORed together # Within a single term, all conditions are ANDed From 3e572d6e2bdcc738dc51d1b86928bb1c2b20653a Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 19 Aug 2024 20:13:33 -0400 Subject: [PATCH 38/40] updates from docs --- ec2_node_class.yaml.tpl | 4 ++- ec2_node_pool.yaml.tpl | 56 ++++++++++++++++++----------------------- 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/ec2_node_class.yaml.tpl b/ec2_node_class.yaml.tpl index facebf0..4251292 100644 --- a/ec2_node_class.yaml.tpl +++ b/ec2_node_class.yaml.tpl @@ -3,6 +3,8 @@ apiVersion: karpenter.k8s.aws/v1 kind: EC2NodeClass metadata: name: ${cluster_name}-karpenter-node-class + annotations: + kubernetes.io/description: "EC2NodeClass for running Bottlerocket nodes" spec: kubelet: podsPerCore: 2 @@ -35,7 +37,7 @@ spec: # Required, resolves a default ami and userdata amiFamily: ${amd_ami_family} amiSelectorTerms: - - alias: bottlerocket@latest + - alias: bottlerocket@latest # Bottlerocket # Required, discovers subnets to attach to instances # Each term in the array of subnetSelectorTerms is ORed together # Within a single term, all conditions are ANDed diff --git a/ec2_node_pool.yaml.tpl b/ec2_node_pool.yaml.tpl index 88285f4..0da0ee8 100644 --- a/ec2_node_pool.yaml.tpl +++ b/ec2_node_pool.yaml.tpl @@ -3,40 +3,32 @@ apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: ${cluster_name}-node-pool-general + annotations: + kubernetes.io/description: "General purpose NodePool for generic workloads" spec: - disruption: - consolidationPolicy: WhenUnderutilized - expireAfter: 1h template: spec: + requirements: + - key: kubernetes.io/arch + operator: In + values: ["amd64"] + - key: kubernetes.io/os + operator: In + values: ["linux"] + - key: karpenter.sh/capacity-type + operator: In + values: ["on-demand", "spot"] + - key: karpenter.k8s.aws/instance-category + operator: In + values: ["c", "m", "r", "t"] + - key: karpenter.k8s.aws/instance-generation + operator: Gt + values: ["2"] nodeClassRef: + group: karpenter.k8s.aws + kind: EC2NodeClass name: ${cluster_name}-karpenter-node-class - requirements: - - key: node.kubernetes.io/instance-type - operator: In - values: - - m5.large - - m5.xlarge - - m5.2xlarge - - c5.large - - c5.xlarge - - c5a.large - - c5a.xlarge - - r5.large - - r5.xlarge - - t3.xlarge - - t3a.xlarge - - t4a.xlarge - - key: kubernetes.io/os - operator: In - values: - - linux - - key: kubernetes.io/arch - operator: In - values: - - amd64 - - key: karpenter.sh/capacity-type - operator: In - values: - - on-demand - - spot + disruption: + consolidationPolicy: WhenEmptyOrUnderutilized + consolidateAfter: 1h + expireAfter: 1h From 77b3115e5afae11bfe3e89911d275a8e08958905 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 19 Aug 2024 20:19:13 -0400 Subject: [PATCH 39/40] =?UTF-8?q?bump:=20version=200.0.0=20=E2=86=92=200.1?= =?UTF-8?q?.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c55b5f5..ada5fcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,14 @@ -## Unreleased +## 0.1.0 (2024-08-19) + +### ✨ Features + +- **karpenter**: update module upstream to 1.0.0 +- **many**: subnet tagging updated nodepoolandnodeclass +- **prometheus**: enables serviceMonitor to captures karpenter metrics in prometheus + +### 🐛🚑️ Fixes + +- **kubectl**: fixes for kubectl image ### ci @@ -7,11 +17,3 @@ ### fix - **main.tf**: correct the value for amd_ami_family - - -* 0.0.2 -- 2024-07-30 - - update after removing cluster-autoscaler - - add second yaml template - - update images module -* 0.0.1 -- 2024-07-26 - - Genesis/Initial development From 87ce2cea72b2e26bcff0ad95b810b05900147831 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Mon, 19 Aug 2024 22:01:29 -0400 Subject: [PATCH 40/40] rename --- copy_images.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/copy_images.tf b/copy_images.tf index f6dd157..c98c243 100644 --- a/copy_images.tf +++ b/copy_images.tf @@ -1,6 +1,6 @@ locals { karpenter_key = format("%v#%v", "karpenter/controller", var.karpenter_tag) - kubectl_key = format("%v#%v", "kubectl", var.kubectl_tag) + kubectl_key = format("%v#%v", "bitnami/kubectl", var.kubectl_tag) image_config = [ { @@ -15,7 +15,7 @@ locals { { enabled = true dest_path = null - name = "kubectl" + name = "bitnami/kubectl" source_image = "bitnami/kubectl" source_registry = "docker.io" source_tag = var.kubectl_tag