如何使用 aws-cdk 从 AWS Secrets Manager 导入 EKS 密钥?
Posted
技术标签:
【中文标题】如何使用 aws-cdk 从 AWS Secrets Manager 导入 EKS 密钥?【英文标题】:How to import EKS secrets from AWS Secrets Manager using aws-cdk? 【发布时间】: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 资源并正确扩展秘密令牌?
【问题讨论】:
【参考方案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]”)以上是关于如何使用 aws-cdk 从 AWS Secrets Manager 导入 EKS 密钥?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 TypeScript 中使用 aws-cdk 在每次部署时不重建 DockerImageAsset?
在 aws-cdk 上的 aws-rds 上,使数据库可公开访问的设置在哪里?