From 15284f017515bbcfac0d686ef2265a0344cfddcc Mon Sep 17 00:00:00 2001 From: Garland Kan Date: Wed, 22 Sep 2021 21:10:40 -0700 Subject: [PATCH] Kubernetes external secrets (#166) --- .../kubernetes-external-secrets/README.md | 17 +++++ .../helm_values.tpl.yaml | 9 +++ .../iam-policy.tpl.json | 20 ++++++ .../helm/kubernetes-external-secrets/main.tf | 68 +++++++++++++++++++ .../kubernetes-external-secrets/variables.tf | 53 +++++++++++++++ 5 files changed, 167 insertions(+) create mode 100644 terraform-modules/aws/helm/kubernetes-external-secrets/README.md create mode 100644 terraform-modules/aws/helm/kubernetes-external-secrets/helm_values.tpl.yaml create mode 100644 terraform-modules/aws/helm/kubernetes-external-secrets/iam-policy.tpl.json create mode 100644 terraform-modules/aws/helm/kubernetes-external-secrets/main.tf create mode 100644 terraform-modules/aws/helm/kubernetes-external-secrets/variables.tf diff --git a/terraform-modules/aws/helm/kubernetes-external-secrets/README.md b/terraform-modules/aws/helm/kubernetes-external-secrets/README.md new file mode 100644 index 000000000..4b2491839 --- /dev/null +++ b/terraform-modules/aws/helm/kubernetes-external-secrets/README.md @@ -0,0 +1,17 @@ +# kubernetes-external-secrets + +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 + +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/kubernetes-external-secrets/helm_values.tpl.yaml b/terraform-modules/aws/helm/kubernetes-external-secrets/helm_values.tpl.yaml new file mode 100644 index 000000000..940f943a7 --- /dev/null +++ b/terraform-modules/aws/helm/kubernetes-external-secrets/helm_values.tpl.yaml @@ -0,0 +1,9 @@ +--- +env: + AWS_REGION: us-east-1 + AWS_DEFAULT_REGION: us-east-1 + +serviceAccount: + name: ${resource_name} + annotations: + eks.amazonaws.com/role-arn: "arn:aws:iam::${awsAccountID}:role/${resource_name}" diff --git a/terraform-modules/aws/helm/kubernetes-external-secrets/iam-policy.tpl.json b/terraform-modules/aws/helm/kubernetes-external-secrets/iam-policy.tpl.json new file mode 100644 index 000000000..d56ddee99 --- /dev/null +++ b/terraform-modules/aws/helm/kubernetes-external-secrets/iam-policy.tpl.json @@ -0,0 +1,20 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "secretsmanager:GetResourcePolicy", + "secretsmanager:GetSecretValue", + "secretsmanager:DescribeSecret", + "secretsmanager:ListSecretVersionIds", + "sts:AssumeRole" + ], + "Resource": [ + "arn:aws:iam::016733450475:role/kubernetes-external-secrets-${envName}", + "arn:aws:secretsmanager:${awsRegion}:${awsAccountID}:secret:${secretsPrefix}*" + ] + } + ] +} + \ No newline at end of file diff --git a/terraform-modules/aws/helm/kubernetes-external-secrets/main.tf b/terraform-modules/aws/helm/kubernetes-external-secrets/main.tf new file mode 100644 index 000000000..9cf38face --- /dev/null +++ b/terraform-modules/aws/helm/kubernetes-external-secrets/main.tf @@ -0,0 +1,68 @@ +locals { + base_name = "kubernetes-external-secrets" + iam_policy_file = "iam-policy.tpl.json" + k8s_service_account_name = "kubernetes-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 = "kubernetes-external-secrets" + namespace = var.namespace + create_namespace = var.create_namespace + name = var.chart_name + version = var.helm_version + verify = var.verify + repository = "https://external-secrets.github.io/kubernetes-external-secrets/" + + values = [ + data.template_file.helm_values.rendered, + var.helm_values, + ] + + depends_on = [ + module.iam_assumable_role_admin + ] +} diff --git a/terraform-modules/aws/helm/kubernetes-external-secrets/variables.tf b/terraform-modules/aws/helm/kubernetes-external-secrets/variables.tf new file mode 100644 index 000000000..1863b2f06 --- /dev/null +++ b/terraform-modules/aws/helm/kubernetes-external-secrets/variables.tf @@ -0,0 +1,53 @@ +variable "helm_version" { + type = string + default = "8.3.0" + 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 = "kubernetes-external-secrets" + description = "Namespace to install in" +} + +variable "chart_name" { + type = string + default = "kubernetes-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" +}