AWS CDK-如何将访问密钥秘密和秘密密钥ID作为Env参数传递给容器

时间:2020-11-07 15:43:03

标签: amazon-iam amazon-ecs aws-cdk cdk

我正在使用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

您知道我如何实现这一目标吗?

2 个答案:

答案 0 :(得分:2)

通常来说,创建IAM用户并不是走这条路-最好使用IAM角色。使用CDK,它将在实例化taskRole构造时自动为您创建taskDefinition。您可以使用各种described heregrant*方法将权限分配给堆栈中的其他构造:

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);

答案 1 :(得分:0)

简而言之,请在我的博客文章中找到答案: 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。使用直接堆栈->字段的堆栈传递。 CfnOutput确实是……,当在一个CDK应用程序中控制所有堆栈时,应避免使用该命令。 仅当您要在CDK应用程序之间共享时才有意义,这些应用程序是分开的部署和存储库。

如果……。尚不清楚,请随时提出问题。