AWS CDK-如何将访问密钥密钥和密钥Id作为环境参数传递给容器



我正在使用CDK在AWS上构建我们的基础设施。我为我的微服务创建IAM用户,以便根据定义的策略与AWS服务对话。我的问题是,我无法获得aws密钥和id,然后作为Env变量传递到我的容器。见下文:

首先,我创建了我的IAM用户,该用户将被我的微服务使用。

const user = new User(this, "user", {
userName: `${myAppEnv}-api-iam-user`,
});

其次,我正在尝试创建访问密钥。

const accessKey = new CfnAccessKey(this, "ApiUserAccessKey", {
userName: user.userName,
});
const accessKeyId = new CfnOutput(this, "AccessKeyId", {
value: accessKey.ref,
});
const accessKeySecret = new CfnOutput(this, "SecretAccessKeyId", {
value: accessKey.attrSecretAccessKey,
});

接下来,我想将其作为env变量传递。

const apiContainer = apiTaskDefinition.addContainer(containerId, {
image: apiImage,
environment: {
APP_ENV: myAppEnv,
AWS_ACCESS_KEY_ID: awsAccessKeyId.value || ":(",
AWS_SECRET_ACCESS_KEY: awsSecretAccessKey.value || ":(",
NOTIFICATIONS_TABLE_ARN: notificationsTableDynamoDBArn,
NOTIFICATIONS_QUEUE_URL: notificationsQueueUrl,
},
cpu: 256,
memoryLimitMiB: 512,
logging: new AwsLogDriver({ streamPrefix: `${myAppEnv}-ec-api` }),
});

当我的CDK部署成功完成时,我会看到打印出来的以下内容:/

Outputs:
staging-ecstack.AccessKeyId = SOMETHING
staging-ecstack.SecretAccessKeyId = SOMETHINGsy12X21xSSOMETHING2X2

你知道我怎样才能做到这一点吗?

一般来说,创建IAM用户不是解决问题的方法,最好使用IAM角色。使用CDK,当您实例化taskDefinition构造时,它将自动为您创建一个taskRole。您可以使用各种grant*方法将权限分配给堆栈中的其他构造,如下所述:

const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef');
const container = taskDefinition.addContainer('web', {
image: ecs.ContainerImage.fromRegistry("apps/myapp"),
memoryLimitMiB: 256,
});
// Grant this task role access to use other resources
myDynamodbTable.grantReadWriteData(taskDefinition.taskRole);
mySnsTopic.grantPublish(taskDefinition.taskRole);

简而言之,在我的博客文章中找到答案:https://blog.michaelfecher.com/i-tell-you-a-secret-provide-database-credentials-to-an-ecs-fargate-task-in-aws-cdk

为了更详细地解释您的问题:

  1. 避免自定义创建的IAM角色,并使用CDK生成的角色。他们是一致的,并使用最小特权原则。在我的博客文章中,没有必要手动创建IAM角色。是的,我知道。。。我需要更新。(
  2. 使用相应资源的grant*方法,例如taskDefinition。这将为生成的角色1(创建一个策略声明
  3. 不要使用环境变量作为机密。网上有很多资源,告诉你为什么。其中一个是:https://security.stackexchange.com/questions/197784/is-it-unsafe-to-use-environmental-variables-for-secret-data特别是在使用ECS时,请使用任务定义中的secrets参数(请参阅博客文章(
  4. 看起来,您传递的是令牌,而不是实际的秘密值。这行不通。令牌在synth/云形成生成期间解析
  5. 你不需要CfnOutput。使用直接堆栈->字段的堆栈传递。当在一个CDK应用程序中控制所有Stack时,CfnOutput实际上是应该避免的。只有当您想在CDK应用程序之间共享时,这才有意义,CDK应用是分离的部署和存储库

如果有什么不清楚的地方,不要犹豫,提出问题。

最新更新