【问题标题】:How to import EKS secrets from AWS Secrets Manager using aws-cdk?如何使用 aws-cdk 从 AWS Secrets Manager 导入 EKS 密钥?
【发布时间】:2020-07-23 22:19:20
【问题描述】:

我有:

  • EKS 由 aws-cdk 脚本部署,启用 kubectl,应用由 eks.Cluster.addResource() 部署
  • AWS Secrets Manager 包含一组我希望可用于 EKS 应用程序的密钥

我尝试以这种方式部署 Secret:

  import * as sm from "@aws-cdk/aws-secretsmanager";

  getSecret(secretKey: string): string {
    let secretTokens = sm.Secret.fromSecretArn(scope, "ImportedSecrets", awsSecretStorageArn);
    return secretTokens.secretValueFromJson(secretKey).toString();
  }

  createKubernetesImagePullSecrets(k8s: eks.Cluster): void {
    let eksSecretStorageName = this.env.awsResourcesConfig.k8sImagePullSecretStorageName;
    k8s.addResource(eksSecretStorageName, {
      apiVersion: "v1",
      kind: "Secret",
      metadata: {
        name: eksSecretStorageName,
      },
      data: {
        ".dockerconfigjson": this.getSecret('hub-secret'),
      },
      type: "kubernetes.io/dockerconfigjson",
    });
  }

我收到来自 CloudFormation 的错误:

版本“v1”中的秘密不能作为秘密处理:v1.Secret.ObjectMeta:v1.ObjectMeta.TypeMeta:种类:数据:解码base64:输入字节0处的非法base64数据

发生这种情况是因为秘密令牌没有展开并且“.dockerconfigjson”字段值在这种情况下看起来像${Token[TOKEN.417]}

有没有办法在部署过程中部署 EKS Secret 资源并正确扩展秘密令牌?

【问题讨论】:

    标签: aws-cdk amazon-eks aws-secrets-manager kubernetes-secrets


    【解决方案1】:

    我为此创建了一个临时解决方法,通过使用aws-cli 下载纯文本版本的机密。不是一种安全的方式,但有效。 如果您有更安全的解决方案,请不要使用它。

    import { execSync } from "child_process";
    
      extractSecretValues(awsSecretStorageArn: string) : Map<string, string> {
        let map = new Map<string, string>();
        let secretsContent = execSync(`aws secretsmanager get-secret-value --secret-id ${awsSecretStorageArn}`).toString();
        let secrets = JSON.parse(secretsContent);
        if (!secrets)
          throw new Error(`Secret values could not be extracted from ${awsSecretStorageArn}`);
        if (secrets.SecretString) {
          let secretValuesObj = JSON.parse(secrets.SecretString);
          for (let [secretKey, secretValue] of Object.entries<string>(secretValuesObj)) {
            map.set(secretKey, secretValue);
          }
        }
        return map;
      }
    
      let secretValueMap = extractSecretValues();
    
      createKubernetesImagePullSecrets(k8s: eks.Cluster): void {
        let eksSecretStorageName = this.env.awsResourcesConfig.k8sImagePullSecretStorageName;
        k8s.addResource(eksSecretStorageName, {
          apiVersion: "v1",
          kind: "Secret",
          metadata: {
            name: eksSecretStorageName,
          },
          data: {
            ".dockerconfigjson": secretValueMap.get('hub-secret'),
          },
          type: "kubernetes.io/dockerconfigjson",
        });
      }
    

    【讨论】:

    • 是的,太糟糕了,秘密以这种方式保存在模板中。在我看来,唯一的办法似乎是在 CDK 之外创建秘密,例如aws cli、eksctl 或 kubectl。这需要在第一个 CDK 脚本中创建集群,为该集群设置密钥,然后在另一个 CDK 脚本中引用使用该密钥的 pod。相当复杂。 CDK 使用SecretValue 的常规解决方案似乎也不支持(至少对于系统管理器 SecureStrings:“SSM 安全参考不受支持:[Custom::AWSCDK-EKS-KubernetesResource/Properties/Manifest]”)
    猜你喜欢
    • 2020-10-26
    • 2022-01-19
    • 2019-02-15
    • 2019-12-01
    • 2020-09-29
    • 2021-10-29
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    相关资源
    最近更新 更多