问题描述
我正在使用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,});
接下来,我想将其作为环境变量传递。
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,它将在实例化taskRole
构造时自动为您创建taskDefinition
。您可以使用各种described here的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
要更详细地说明您的问题,
- 避免定制创建的IAM角色,并使用CDK生成的角色。它们是一致的,并使用最小特权原则。在我的博客文章中,不需要手动创建IAM角色。是的,我知道...我需要更新。 ;)
- 使用相应资源的
grant*
方法,例如taskDefinition
。 这将为生成的角色1)创建策略声明 - 请勿将环境变量用于机密。
网络上有很多资源,可以告诉您原因。
这里是一个:https://security.stackexchange.com/questions/197784/is-it-unsafe-to-use-environmental-variables-for-secret-data
特别是在使用ECS时,请在任务定义中使用
secrets
参数(请参阅博客文章)。 - 似乎您正在传递令牌,而不是实际的秘密值。
那不行令牌在
synth
/云形成生成期间被解析。 - 您将不需要
CfnOutput
。使用直接堆栈->字段的堆栈传递。CfnOutput
确实是……,当在一个CDK应用程序中控制所有堆栈时,应避免使用该命令。 仅当您要在CDK应用程序之间共享时才有意义,这些应用程序是分开的部署和存储库。
如果……。尚不清楚,请随时提出问题。