diff --git a/terraform-modules/aws/helm/external-secrets/README.md b/terraform-modules/aws/helm/external-secrets/README.md new file mode 100644 index 000000000..5235f685d --- /dev/null +++ b/terraform-modules/aws/helm/external-secrets/README.md @@ -0,0 +1,18 @@ +# kubernetes-external-secrets + +Source project: https://github.com/external-secrets/external-secrets +Source chart: https://github.com/external-secrets/external-secrets/tree/main/deploy/charts/external-secrets +Usage Docs: https://external-secrets.io/v0.4.4/ + +EKS Kubernetes v1.19+ + +## Useful guides +Getting the IAM policies and trust relationships to all align up is tricky. If something is not set correctly like +the name is off in one of the place, the entire sequence of chained identity fails and it is hard to figure out where +exactly. You can guess and see if it is something obvious but if it is not, then you should just follow each of the +resources through to make sure everything is setup correctly. + +Here is the doc on how to setup IAM for ServiceAccounts: https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html + +At the bottom of this doc it will link to how to create each of the items. Following each one through to make sure these +items exist and the names all match up is critical for this entire setup. diff --git a/terraform-modules/aws/helm/external-secrets/install/helm_values.tpl.yaml b/terraform-modules/aws/helm/external-secrets/install/helm_values.tpl.yaml new file mode 100644 index 000000000..93fdce7b5 --- /dev/null +++ b/terraform-modules/aws/helm/external-secrets/install/helm_values.tpl.yaml @@ -0,0 +1,11 @@ +--- +extraEnv: +- name: AWS_REGION + value: ${awsRegion} +- name: AWS_DEFAULT_REGION + value: ${awsRegion} + +serviceAccount: + name: ${resource_name} + annotations: + eks.amazonaws.com/role-arn: "arn:aws:iam::${awsAccountID}:role/${resource_name}" diff --git a/terraform-modules/aws/helm/external-secrets/install/iam-policy.tpl.json b/terraform-modules/aws/helm/external-secrets/install/iam-policy.tpl.json new file mode 100644 index 000000000..9aca6ee23 --- /dev/null +++ b/terraform-modules/aws/helm/external-secrets/install/iam-policy.tpl.json @@ -0,0 +1,19 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "secretsmanager:GetResourcePolicy", + "secretsmanager:GetSecretValue", + "secretsmanager:DescribeSecret", + "secretsmanager:ListSecretVersionIds", + "sts:AssumeRole" + ], + "Resource": [ + "arn:aws:secretsmanager:${awsRegion}:${awsAccountID}:secret:${secretsPrefix}*" + ] + } + ] +} + \ No newline at end of file diff --git a/terraform-modules/aws/helm/external-secrets/install/main.tf b/terraform-modules/aws/helm/external-secrets/install/main.tf new file mode 100644 index 000000000..00adca4f3 --- /dev/null +++ b/terraform-modules/aws/helm/external-secrets/install/main.tf @@ -0,0 +1,68 @@ +locals { + base_name = "external-secrets" + iam_policy_file = "iam-policy.tpl.json" + k8s_service_account_name = "external-secrets" +} + +data "aws_caller_identity" "current" {} +data "aws_region" "current" {} + +module "iam_assumable_role_admin" { + source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc" + version = "3.6.0" + create_role = true + role_name = "${local.base_name}-${var.environment_name}" + # role_path = "/token-file-web-identity/" + provider_url = replace(var.eks_cluster_oidc_issuer_url, "https://", "") + role_policy_arns = [aws_iam_policy.cluster_autoscaler.arn] + oidc_fully_qualified_subjects = ["system:serviceaccount:${var.namespace}:${local.k8s_service_account_name}-${var.environment_name}"] +} + +data "template_file" "iam_policy" { + template = file("${path.module}/iam-policy.tpl.json") + vars = { + awsAccountID = data.aws_caller_identity.current.account_id + awsRegion = data.aws_region.current.name + secretsPrefix = var.secrets_prefix + envName = var.environment_name + } +} + +# Policy doc: https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/docs/iam-policy-example.json +resource "aws_iam_policy" "cluster_autoscaler" { + name_prefix = "${local.base_name}-${var.environment_name}" + description = "${local.base_name} for ${var.environment_name}" + policy = data.template_file.iam_policy.rendered +} + +# +# Helm templating +# +data "template_file" "helm_values" { + template = file("${path.module}/helm_values.tpl.yaml") + vars = { + awsAccountID = data.aws_caller_identity.current.account_id + awsRegion = data.aws_region.current.name + # serviceAccountName = local.k8s_service_account_name + resource_name = "${local.base_name}-${var.environment_name}" + } +} + +resource "helm_release" "helm_chart" { + chart = "external-secrets" + namespace = var.namespace + create_namespace = var.create_namespace + name = var.chart_name + version = var.helm_version + verify = var.verify + repository = "https://charts.external-secrets.io" + + values = [ + data.template_file.helm_values.rendered, + var.helm_values, + ] + + depends_on = [ + module.iam_assumable_role_admin + ] +} diff --git a/terraform-modules/aws/helm/external-secrets/install/variables.tf b/terraform-modules/aws/helm/external-secrets/install/variables.tf new file mode 100644 index 000000000..850efcdf2 --- /dev/null +++ b/terraform-modules/aws/helm/external-secrets/install/variables.tf @@ -0,0 +1,53 @@ +variable "helm_version" { + type = string + default = "0.4.4" + description = "Helm chart version" +} + +variable "verify" { + type = bool + default = false + description = "Verify the helm download" +} + +variable "create_namespace" { + type = bool + default = true + description = "Create namespace if it does not exist" +} + +variable "namespace" { + type = string + default = "external-secrets" + description = "Namespace to install in" +} + +variable "chart_name" { + type = string + default = "external-secrets" + description = "Name to set the helm deployment to" +} + +variable "helm_values" { + type = string + default = "" + description = "Additional helm values to pass in. These values would override the default in this module." +} + +variable "environment_name" { + type = string + default = "env" + description = "An environment name to attach to some resources. Optional only needed if you are going to create more than one of these items in an AWS account" +} + +variable "eks_cluster_oidc_issuer_url" { + type = string + default = "" + description = "EKS cluster oidc issuer url" +} + +variable "secrets_prefix" { + type = string + default = "" + description = "The prefix to your AWS Secrets. This allows this module to craft a more tightly controlled set of IAM policies to only allow it to get certain secrets" +} diff --git a/terraform-modules/aws/helm/external-secrets/secret_store/main.tf b/terraform-modules/aws/helm/external-secrets/secret_store/main.tf new file mode 100644 index 000000000..07d41651a --- /dev/null +++ b/terraform-modules/aws/helm/external-secrets/secret_store/main.tf @@ -0,0 +1,63 @@ +locals { + base_name = "external-secrets" +} + +data "aws_region" "current" {} + +resource "kubernetes_manifest" "secret_store" { + manifest = { + "apiVersion" = "external-secrets.io/v1alpha1" + "kind" = "SecretStore" + "metadata" = { + "name" = var.secret_store_name + "namespace" = var.namespace + "labels" = { + "managed/by": "terraform" + } + } + "spec" = { + "provider" = { + "aws": { + "service": "SecretsManager" + "region": data.aws_region.current.name + "auth": { + "jwt": { + "serviceAccountRef": { + "name": "${local.base_name}-${var.environment_name}" + } + } + } + } + } + } + } +} + +resource "kubernetes_manifest" "cluster_secret_store" { + manifest = { + "apiVersion" = "external-secrets.io/v1alpha1" + "kind" = "ClusterSecretStore" + "metadata" = { + "name" = var.secret_store_name + "labels" = { + "managed/by": "terraform" + } + } + "spec" = { + "provider" = { + "aws": { + "service": "SecretsManager" + "region": data.aws_region.current.name + "auth": { + "jwt": { + "serviceAccountRef": { + "name": "${local.base_name}-${var.environment_name}" + "namespace": var.namespace + } + } + } + } + } + } + } +} diff --git a/terraform-modules/aws/helm/external-secrets/secret_store/variables.tf b/terraform-modules/aws/helm/external-secrets/secret_store/variables.tf new file mode 100644 index 000000000..9430d5b0c --- /dev/null +++ b/terraform-modules/aws/helm/external-secrets/secret_store/variables.tf @@ -0,0 +1,17 @@ +variable "namespace" { + type = string + default = "external-secrets" + description = "Namespace to install in" +} + +variable "secret_store_name" { + type = string + default = "secretstore-main" + description = "The secret stores name" +} + +variable "environment_name" { + type = string + default = "env" + description = "An environment name to attach to some resources. Optional only needed if you are going to create more than one of these items in an AWS account" +} diff --git a/terraform-modules/aws/helm/external-secrets/secrets/main.tf b/terraform-modules/aws/helm/external-secrets/secrets/main.tf new file mode 100644 index 000000000..03939ca18 --- /dev/null +++ b/terraform-modules/aws/helm/external-secrets/secrets/main.tf @@ -0,0 +1,9 @@ +locals { + base_name = "external-secrets" +} + +data "aws_region" "current" {} + +resource "kubernetes_manifest" "external_secret" { + manifest = yamldecode(var.yaml) +} diff --git a/terraform-modules/aws/helm/external-secrets/secrets/variables.tf b/terraform-modules/aws/helm/external-secrets/secrets/variables.tf new file mode 100644 index 000000000..77ea6bd5c --- /dev/null +++ b/terraform-modules/aws/helm/external-secrets/secrets/variables.tf @@ -0,0 +1,5 @@ +variable "yaml" { + type = string + description = "A yaml of the kind: ExternalSecret" + default = "---" +} diff --git a/terraform-modules/aws/helm/kubernetes-external-secrets/README.md b/terraform-modules/aws/helm/kubernetes-external-secrets/README.md index 4b2491839..938b0c00c 100644 --- a/terraform-modules/aws/helm/kubernetes-external-secrets/README.md +++ b/terraform-modules/aws/helm/kubernetes-external-secrets/README.md @@ -1,5 +1,8 @@ # kubernetes-external-secrets +# Deprecated +This helm chart has been deprecated in favor of the `external-secrets` helm chart + Source project: https://github.com/external-secrets/kubernetes-external-secrets Source chart: https://github.com/external-secrets/kubernetes-external-secrets/tree/master/charts/kubernetes-external-secrets