diff --git a/.github/RELEASE_DRAFTER.yml b/.github/RELEASE_DRAFTER.yml index 1ae725f..c6af0a0 100644 --- a/.github/RELEASE_DRAFTER.yml +++ b/.github/RELEASE_DRAFTER.yml @@ -7,11 +7,25 @@ categories: - 'enhancement' - title: 'Bug Fixes' labels: - - 'fix' - - 'bugfix' - 'bug' - title: 'Documentation' label: 'documentation' + - title: 'CI' + label: 'ci' +version-resolver: + major: + labels: + - 'major' + minor: + labels: + - 'feature' + - 'enhancement' + patch: + labels: + - 'ci' + - 'bug' + - 'documentation' + default: patch change-template: '- $TITLE, by @$AUTHOR (#$NUMBER)' template: | # What's changed diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 7c0b1ec..cb202ac 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -1,5 +1,8 @@ name: pre-commit +permissions: + contents: read + on: workflow_dispatch: pull_request: @@ -8,36 +11,42 @@ on: - master env: + PYTHON_VERSION: "3.10" TERRAFORM_DOCS_VERSION: "v0.16.0" - TFLINT_VERSION: "v0.36.2" + TFLINT_VERSION: "v0.48.0" jobs: pre-commit: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - - - name: Install additional pre-commit hooks - shell: bash - run: | - echo "########### Install Checkov ####################" - pip install checkov - - echo "########### Install Terraform-docs #############" - wget https://github.com/terraform-docs/terraform-docs/releases/download/${{ env.TERRAFORM_DOCS_VERSION }}/terraform-docs-${{ env.TERRAFORM_DOCS_VERSION }}-linux-amd64.tar.gz - tar xvzf terraform-docs-${{ env.TERRAFORM_DOCS_VERSION }}-linux-amd64.tar.gz - mkdir -p ~/terraform-docs/bin/ - install terraform-docs ~/terraform-docs/bin/ - echo '~/terraform-docs/bin/' >> $GITHUB_PATH - - echo "########### Install Terraform-linters ##########" - wget https://github.com/terraform-linters/tflint/releases/download/${{ env.TFLINT_VERSION }}/tflint_linux_amd64.zip - unzip tflint_linux_amd64.zip - mkdir -p ~/tflint/bin/ - echo '~/tflint/bin/' >> $GITHUB_PATH - install tflint ~/tflint/bin/ - ~/tflint/bin/tflint --init - - - name: Run pre-commit - uses: pre-commit/action@v2.0.3 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: ${{ env.PYTHON_VERSION }} + cache: pip + + - name: Install Python dependencies + run: pip install -r requirements.txt + + - name: Install terraform-docs + uses: jaxxstorm/action-install-gh-release@v1.9.0 + with: + repo: terraform-docs/terraform-docs + tag: ${{ env.TERRAFORM_DOCS_VERSION }} + cache: enable + + - name: TFLint cache + uses: actions/cache@v3 + with: + path: ~/.tflint.d/plugins + key: ${{ runner.os }}-tflint-${{ hashFiles('.tflint.hcl') }} + + - name: Install TFLint + uses: terraform-linters/setup-tflint@v2 + with: + tflint_version: ${{ env.TFLINT_VERSION }} + + - name: Run pre-commit + uses: pre-commit/action@v3.0.0 diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 7cae11f..9528a7a 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -15,7 +15,7 @@ on: jobs: update_release_draft: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: release-drafter/release-drafter@v5 with: diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 2d3f60e..2b9e3e7 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -1,5 +1,8 @@ name: Terraform validate +permissions: + contents: read + on: workflow_dispatch: pull_request: @@ -10,11 +13,11 @@ on: jobs: versionExtract: name: Extract min/max Terraform versions - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Extract Terraform min/max versions id: minMax @@ -26,7 +29,7 @@ jobs: maxVersion: ${{ steps.minMax.outputs.maxVersion }} terraform-validate: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: versionExtract strategy: matrix: @@ -35,7 +38,7 @@ jobs: - ${{ needs.versionExtract.outputs.maxVersion }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: hashicorp/setup-terraform@v2 with: terraform_version: ${{ matrix.tf_ver }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4b7f891..e5e4dc7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.2.0 + rev: v4.4.0 hooks: - id: trailing-whitespace - id: check-merge-conflict @@ -10,23 +10,22 @@ repos: - id: end-of-file-fixer - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.71.0 + rev: v1.83.1 hooks: - id: terraform_fmt - id: terraform_tflint + args: + - --args=--config=__GIT_WORKING_DIR__/.tflint.hcl - id: terraform_validate - id: terraform_checkov + args: + - '--args=--quiet --skip-check CKV_TF_1' #CKV_TF_1: "Ensure Terraform module sources use a commit hash" - id: terraform_docs args: - - '--args=--hide providers --sort-by required' - - - repo: https://github.com/pecigonzalo/pre-commit-terraform-vars - rev: v1.0.0 - hooks: - - id: terraform-vars + - '--args=--config=.terraform-docs.yml' - repo: https://github.com/Yelp/detect-secrets - rev: v1.3.0 + rev: v1.4.0 hooks: - id: detect-secrets args: ['--baseline', '.secrets.baseline'] diff --git a/.secrets.baseline b/.secrets.baseline index eaf7047..68642d2 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -109,5 +109,5 @@ } ], "results": {}, - "generated_at": "2022-07-28T10:50:47Z" + "generated_at": "2022-10-10T14:52:48Z" } diff --git a/.terraform-docs.yml b/.terraform-docs.yml new file mode 100644 index 0000000..cb998c2 --- /dev/null +++ b/.terraform-docs.yml @@ -0,0 +1,15 @@ +formatter: markdown table + +output: + mode: inject + template: |- + + {{ .Content }} + + +sections: + hide: + - providers + +sort: + by: required diff --git a/.tflint.hcl b/.tflint.hcl new file mode 100644 index 0000000..543ca2b --- /dev/null +++ b/.tflint.hcl @@ -0,0 +1,12 @@ +plugin "terraform" { + enabled = true + version = "0.4.0" + source = "github.com/terraform-linters/tflint-ruleset-terraform" + preset = "recommended" +} + +plugin "aws" { + enabled = true + version = "0.26.0" + source = "github.com/terraform-linters/tflint-ruleset-aws" +} diff --git a/README.md b/README.md index b6b4164..c65d235 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # AWS EKS EBS CSI driver Terraform module -[![labyrinth labs logo](ll-logo.png)](https://lablabs.io/) +[](https://lablabs.io/) We help companies build, run, deploy and scale software and infrastructure by embracing the right technologies and principles. Check out our website at --- [![Terraform validate](https://github.com/lablabs/terraform-aws-eks-ebs-csi-driver/actions/workflows/validate.yaml/badge.svg)](https://github.com/lablabs/terraform-aws-eks-ebs-csi-driver/actions/workflows/validate.yaml) -[![pre-commit](https://github.com/lablabs/terraform-aws-ebs-csi-driver/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/lablabs/terraform-aws-eks-ebs-csi-driver/actions/workflows/pre-commit.yml) +[![pre-commit](https://github.com/lablabs/terraform-aws-eks-ebs-csi-driver/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/lablabs/terraform-aws-eks-ebs-csi-driver/actions/workflows/pre-commit.yml) ## Description @@ -80,9 +80,9 @@ See [Basic example](examples/basic/README.md) for further information. | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 4.19.0 | +| [aws](#requirement\_aws) | >= 4.35.0 | | [helm](#requirement\_helm) | >= 2.6.0 | -| [kubernetes](#requirement\_kubernetes) | >= 2.11.0 | +| [kubernetes](#requirement\_kubernetes) | >= 2.20.0 | | [utils](#requirement\_utils) | >= 0.17.0 | ## Modules @@ -116,16 +116,16 @@ No modules. | [argo\_enabled](#input\_argo\_enabled) | If set to true, the module will be deployed as ArgoCD application, otherwise it will be deployed as a Helm release | `bool` | `false` | no | | [argo\_helm\_enabled](#input\_argo\_helm\_enabled) | If set to true, the ArgoCD Application manifest will be deployed using Kubernetes provider as a Helm release. Otherwise it'll be deployed as a Kubernetes manifest. See Readme for more info | `bool` | `false` | no | | [argo\_helm\_values](#input\_argo\_helm\_values) | Value overrides to use when deploying argo application object with helm | `string` | `""` | no | -| [argo\_info](#input\_argo\_info) | ArgoCD info manifest parameter | `list` |
[
{
"name": "terraform",
"value": "true"
}
]
| no | +| [argo\_info](#input\_argo\_info) | ArgoCD info manifest parameter |
list(object({
name = string
value = string
}))
|
[
{
"name": "terraform",
"value": "true"
}
]
| no | | [argo\_kubernetes\_manifest\_computed\_fields](#input\_argo\_kubernetes\_manifest\_computed\_fields) | List of paths of fields to be handled as "computed". The user-configured value for the field will be overridden by any different value returned by the API after apply. | `list(string)` |
[
"metadata.labels",
"metadata.annotations"
]
| no | | [argo\_kubernetes\_manifest\_field\_manager\_force\_conflicts](#input\_argo\_kubernetes\_manifest\_field\_manager\_force\_conflicts) | Forcibly override any field manager conflicts when applying the kubernetes manifest resource | `bool` | `false` | no | | [argo\_kubernetes\_manifest\_field\_manager\_name](#input\_argo\_kubernetes\_manifest\_field\_manager\_name) | The name of the field manager to use when applying the kubernetes manifest resource. Defaults to Terraform | `string` | `"Terraform"` | no | | [argo\_kubernetes\_manifest\_wait\_fields](#input\_argo\_kubernetes\_manifest\_wait\_fields) | A map of fields and a corresponding regular expression with a pattern to wait for. The provider will wait until the field matches the regular expression. Use * for any value. | `map(string)` | `{}` | no | -| [argo\_metadata](#input\_argo\_metadata) | ArgoCD Application metadata configuration. Override or create additional metadata parameters | `map` |
{
"finalizers": [
"resources-finalizer.argocd.argoproj.io"
]
}
| no | +| [argo\_metadata](#input\_argo\_metadata) | ArgoCD Application metadata configuration. Override or create additional metadata parameters | `any` |
{
"finalizers": [
"resources-finalizer.argocd.argoproj.io"
]
}
| no | | [argo\_namespace](#input\_argo\_namespace) | Namespace to deploy ArgoCD application CRD to | `string` | `"argo"` | no | | [argo\_project](#input\_argo\_project) | ArgoCD Application project | `string` | `"default"` | no | -| [argo\_spec](#input\_argo\_spec) | ArgoCD Application spec configuration. Override or create additional spec parameters | `map` | `{}` | no | -| [argo\_sync\_policy](#input\_argo\_sync\_policy) | ArgoCD syncPolicy manifest parameter | `map` | `{}` | no | +| [argo\_spec](#input\_argo\_spec) | ArgoCD Application spec configuration. Override or create additional spec parameters | `any` | `{}` | no | +| [argo\_sync\_policy](#input\_argo\_sync\_policy) | ArgoCD syncPolicy manifest parameter | `any` | `{}` | no | | [enabled](#input\_enabled) | Variable indicating whether deployment is enabled | `bool` | `true` | no | | [helm\_atomic](#input\_helm\_atomic) | If set, installation process purges chart on fail. The wait flag will be set automatically if atomic is used | `bool` | `false` | no | | [helm\_chart\_name](#input\_helm\_chart\_name) | Helm chart name to be installed | `string` | `"aws-ebs-csi-driver"` | no | @@ -169,7 +169,7 @@ No modules. | [service\_account\_create](#input\_service\_account\_create) | Whether to create Service Account | `bool` | `true` | no | | [service\_account\_name](#input\_service\_account\_name) | The k8s EBS CSI driver service account name | `string` | `"aws-ebs-csi-driver"` | no | | [settings](#input\_settings) | Additional helm sets which will be passed to the Helm chart values, see https://github.com/kubernetes-sigs/aws-ebs-csi-driver/tree/master/charts/aws-ebs-csi-driver | `map(any)` | `{}` | no | -| [storage\_classes](#input\_storage\_classes) | List of the custom Storage Classes definitions | `list` |
[
{
"allowVolumeExpansion": true,
"annotations": {
"storageclass.kubernetes.io/is-default-class": "true"
},
"name": "ebs-csi-gp3",
"parameters": {
"encrypted": "true",
"type": "gp3"
},
"reclaimPolicy": "Delete",
"volumeBindingMode": "WaitForFirstConsumer"
}
]
| no | +| [storage\_classes](#input\_storage\_classes) | List of the custom Storage Classes definitions | `list(any)` |
[
{
"allowVolumeExpansion": true,
"annotations": {
"storageclass.kubernetes.io/is-default-class": "true"
},
"name": "ebs-csi-gp3",
"parameters": {
"encrypted": "true",
"type": "gp3"
},
"reclaimPolicy": "Delete",
"volumeBindingMode": "WaitForFirstConsumer"
}
]
| no | | [storage\_classes\_create](#input\_storage\_classes\_create) | Whether to create Storage Classes | `bool` | `true` | no | | [values](#input\_values) | Additional yaml encoded values which will be passed to the Helm chart, see https://github.com/kubernetes-sigs/aws-ebs-csi-driver/tree/master/charts/aws-ebs-csi-driver | `string` | `""` | no | diff --git a/argo.tf b/argo.tf index a952837..1aa62c7 100644 --- a/argo.tf +++ b/argo.tf @@ -10,11 +10,15 @@ locals { "repoURL" : var.helm_repo_url "chart" : var.helm_chart_name "targetRevision" : var.helm_chart_version - "helm" : { - "releaseName" : var.helm_release_name - "parameters" : [for k, v in var.settings : tomap({ "forceString" : true, "name" : k, "value" : v })] - "values" : var.enabled ? data.utils_deep_merge_yaml.values[0].output : "" - } + "helm" : merge( + { + "releaseName" : var.helm_release_name + "values" : var.enabled ? data.utils_deep_merge_yaml.values[0].output : "" + }, + length(var.settings) > 0 ? { + "parameters" : [for k, v in var.settings : tomap({ "forceString" : true, "name" : k, "value" : v })] + } : {} + ) } "destination" : { "server" : var.argo_destination_server @@ -43,7 +47,6 @@ data "utils_deep_merge_yaml" "argo_helm_values" { ]) } - resource "helm_release" "argo_application" { count = var.enabled && var.argo_enabled && var.argo_helm_enabled ? 1 : 0 @@ -57,9 +60,9 @@ resource "helm_release" "argo_application" { ] } - resource "kubernetes_manifest" "this" { count = var.enabled && var.argo_enabled && !var.argo_helm_enabled ? 1 : 0 + manifest = { "apiVersion" = var.argo_apiversion "kind" = "Application" diff --git a/examples/basic/README.md b/examples/basic/README.md index 9a7c801..15106e9 100644 --- a/examples/basic/README.md +++ b/examples/basic/README.md @@ -5,7 +5,12 @@ The code in this example shows how to use the module with basic configuration an ## Requirements -No requirements. +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.35.0 | +| [helm](#requirement\_helm) | >= 2.6.0 | +| [kubernetes](#requirement\_kubernetes) | >= 2.20.0 | ## Modules @@ -19,7 +24,7 @@ No requirements. | [ebs\_without\_irsa\_role](#module\_ebs\_without\_irsa\_role) | ../../ | n/a | | [eks\_cluster](#module\_eks\_cluster) | cloudposse/eks-cluster/aws | 2.3.0 | | [eks\_node\_group](#module\_eks\_node\_group) | cloudposse/eks-node-group/aws | 2.4.0 | -| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | 3.14.2 | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | 4.0.0 | ## Resources diff --git a/examples/basic/base.tf b/examples/basic/base.tf index ab6e026..cb626a2 100644 --- a/examples/basic/base.tf +++ b/examples/basic/base.tf @@ -1,8 +1,8 @@ module "vpc" { source = "terraform-aws-modules/vpc/aws" - version = "3.14.2" + version = "4.0.0" - name = "cluster-autoscaler-vpc" + name = "aws-ebs-csi-driver-vpc" cidr = "10.0.0.0/16" azs = ["eu-central-1a", "eu-central-1b"] public_subnets = ["10.0.101.0/24", "10.0.102.0/24"] diff --git a/examples/basic/providers.tf b/examples/basic/providers.tf index e8369d1..f18aaaa 100644 --- a/examples/basic/providers.tf +++ b/examples/basic/providers.tf @@ -10,10 +10,16 @@ data "aws_eks_cluster_auth" "this" { name = module.eks_cluster.eks_cluster_id } +provider "kubernetes" { + host = data.aws_eks_cluster.this.endpoint + token = data.aws_eks_cluster_auth.this.token + cluster_ca_certificate = base64decode(data.aws_eks_cluster.this.certificate_authority[0].data) +} + provider "helm" { kubernetes { host = data.aws_eks_cluster.this.endpoint token = data.aws_eks_cluster_auth.this.token - cluster_ca_certificate = base64decode(data.aws_eks_cluster.this.certificate_authority.0.data) + cluster_ca_certificate = base64decode(data.aws_eks_cluster.this.certificate_authority[0].data) } } diff --git a/examples/basic/versions.tf b/examples/basic/versions.tf new file mode 100644 index 0000000..7ec57e1 --- /dev/null +++ b/examples/basic/versions.tf @@ -0,0 +1,18 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.35.0" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = ">= 2.20.0" + } + helm = { + source = "hashicorp/helm" + version = ">= 2.6.0" + } + } +} diff --git a/iam.tf b/iam.tf index 7aaea41..d56d79f 100644 --- a/iam.tf +++ b/iam.tf @@ -6,6 +6,7 @@ data "aws_iam_policy_document" "this" { count = local.irsa_role_create && var.irsa_policy_enabled ? 1 : 0 #checkov:skip=CKV_AWS_111 there is correct condition for existing Tags + #checkov:skip=CKV_AWS_356 # Official documentation https://raw.githubusercontent.com/kubernetes-sigs/aws-ebs-csi-driver/helm-chart-aws-ebs-csi-driver-2.10.1/docs/example-iam-policy.json statement { @@ -82,18 +83,6 @@ data "aws_iam_policy_document" "this" { } } - statement { - effect = "Allow" - resources = ["*"] - actions = ["ec2:CreateVolume"] - - condition { - test = "StringLike" - variable = "aws:RequestTag/kubernetes.io/cluster/*" - values = ["owned"] - } - } - statement { effect = "Allow" resources = ["*"] @@ -125,8 +114,8 @@ data "aws_iam_policy_document" "this" { condition { test = "StringLike" - variable = "ec2:ResourceTag/kubernetes.io/cluster/*" - values = ["owned"] + variable = "ec2:ResourceTag/kubernetes.io/created-for/pvc/name" + values = ["*"] } } diff --git a/ll-logo.png b/ll-logo.png deleted file mode 100644 index 8aa2c6a..0000000 Binary files a/ll-logo.png and /dev/null differ diff --git a/outputs.tf b/outputs.tf index 3f48ea4..c9b4d3f 100644 --- a/outputs.tf +++ b/outputs.tf @@ -10,7 +10,7 @@ output "helm_release_application_metadata" { output "kubernetes_application_attributes" { description = "Argo kubernetes manifest attributes" - value = try(kubernetes_manifest.this, {}) + value = try(kubernetes_manifest.this[0], {}) } output "iam_role_attributes" { diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..cde6311 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +checkov==2.4.25 diff --git a/variables.tf b/variables.tf index a230ff2..52c3249 100644 --- a/variables.tf +++ b/variables.tf @@ -68,6 +68,7 @@ variable "service_account_create" { } variable "service_account_name" { + type = string default = "aws-ebs-csi-driver" description = "The k8s EBS CSI driver service account name" } @@ -109,6 +110,7 @@ variable "storage_classes_create" { } variable "storage_classes" { + type = list(any) default = [ { "name" : "ebs-csi-gp3" @@ -158,6 +160,10 @@ variable "argo_project" { } variable "argo_info" { + type = list(object({ + name = string + value = string + })) default = [{ "name" = "terraform" "value" = "true" @@ -166,11 +172,13 @@ variable "argo_info" { } variable "argo_sync_policy" { + type = any description = "ArgoCD syncPolicy manifest parameter" default = {} } variable "argo_metadata" { + type = any default = { "finalizers" : [ "resources-finalizer.argocd.argoproj.io" @@ -180,11 +188,13 @@ variable "argo_metadata" { } variable "argo_apiversion" { + type = string default = "argoproj.io/v1alpha1" description = "ArgoCD Appliction apiVersion" } variable "argo_spec" { + type = any default = {} description = "ArgoCD Application spec configuration. Override or create additional spec parameters" } @@ -202,6 +212,7 @@ variable "argo_kubernetes_manifest_computed_fields" { } variable "argo_kubernetes_manifest_field_manager_name" { + type = string default = "Terraform" description = "The name of the field manager to use when applying the kubernetes manifest resource. Defaults to Terraform" } diff --git a/versions.tf b/versions.tf index ea8c3a1..5255895 100644 --- a/versions.tf +++ b/versions.tf @@ -4,11 +4,11 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 4.19.0" + version = ">= 4.35.0" } kubernetes = { source = "hashicorp/kubernetes" - version = ">= 2.11.0" + version = ">= 2.20.0" } helm = { source = "hashicorp/helm"