首页 > 解决方案 > CDK 中的高级权限处理:passRole、创建实例和传递多个权限

问题描述

我对 CDK 有一个非常讨厌的 IAM / 权限问题。我已经让它在控制台上工作了。这是一个分为两部分的问题,第一部分处理我已经完成的工作,第二部分研究如何在 CDK 中复制它。

现有解决方案

我有一个可以从多个来源触发的 Lambda 函数。每个源都提供了一些控制执行的参数。lambda 的主要任务是创建一个 EC2 实例并向其发送用户数据脚本以执行。虚拟机排队一个点实例以节省一些钱,当它完成时,它就会终止。这是一个相当庞大的虚拟机,因为它需要进行一些非常繁重的数据处理,但很少发生,因此我为什么不让它一直活着。

虚拟机本身需要 priveldeges 才能触发 SES 电子邮件,并访问 s3 存储桶进行读写。

在此处输入图像描述

权限

Lambda 在其角色中有 3 个策略文档:

  1. 基本执行。
  2. EC2 完全访问 AWS 托管策略。
  3. 自定义 Pass-Role 策略,如下:
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "iam:PassRole",
                "Resource": "arn:aws:iam::xxxxxxxxxxxxxxxxxxxx:role/EC2Role-Machine"
            },
            {
                "Effect": "Allow",
                "Action": [
                    "iam:CreateInstanceProfile",
                    "iam:AddRoleToInstanceProfile"
                ],
                "Resource": "arn:aws:iam::xxxxxxxxxxxx:*"
            }
        ]
    }

pass-role 策略包含以下权限:

EC2 自定义角色

此 EC2 自定义角色包含 2 个策略

     {
       "Version":"2012-10-17",
       "Statement":[
          {
             "Sid":"VisualEditor0",
             "Effect":"Allow",
             "Action":[
                "s3:GetAccessPoint",
                "s3:PutAccountPublicAccessBlock",
                "s3:GetAccountPublicAccessBlock",
                "s3:ListAllMyBuckets",
                "s3:ListAccessPoints",
                "s3:ListJobs",
                "s3:CreateJob"
             ],
             "Resource":"*"
          },
          {
             "Sid":"VisualEditor1",
             "Effect":"Allow",
             "Action":[
                "s3:*",
                "s3:ListObjectsV2"
             ],
             "Resource":[
                "arn:aws:s3:::monkey.test.bucket/*",
                "arn:aws:s3:::reports.monkeytronics.co.nz/*",
                "arn:aws:s3:::analytics.monkeytronics.co.nz/*",
                "arn:aws:s3:::analytics.monkeytronics.co.nz"
             ]
          }
       ]
    }

问题 1

虽然这有效......对吗?是否应该进行任何安全性或最佳实践改进?

问题2

这如何在 CDK 中复制。我已经开始研究它,但很快就碰壁了。触发 lambda 时出现错误。Lambda 的主要内容如下。基本上,它只是启动一个新的 EC2 实例并输入用户数据。完成后,EC2 终止。安全组、角色和密钥都已准备好,我知道它们从以前开始就可以正常工作。

// my custom AMI
    var instanceParams = {
        ImageId: 'ami-0dfxxxxxxxxxxxe', 
        InstanceType: 't2.xlarge',
        KeyName: 'EC2-Test-Key-Pair',
        MinCount: 1,
        MaxCount: 1,
        SecurityGroups: ['launch-wizard-1'],
        UserData: userDataEncoded,
        InstanceInitiatedShutdownBehavior: "terminate",
        // InstanceMarketOptions: {
        //     "MarketType" : "spot",
        //     //"SpotOptions" : SpotOptions // max price / block period etc...
        // },
        IamInstanceProfile : { 
            "Arn" : "arn:aws:iam::xxxxxxxxxxx:instance-profile/EC2Role-R-Machine"
        }
    };
    
// Create a promise on an EC2 service object
    var instancePromise = new AWS.EC2({apiVersion: '2016-11-15'}).runInstances(instanceParams).promise();    
    
// Handle promise's fulfilled/rejected states
    await instancePromise.then(
        function(data) {
            console.log(data);
            var instanceId = data.Instances[0].InstanceId;
            console.log("Created instance", instanceId);
        }
    );  

这是来自 cloudwatch 的错误消息。恐怕不是很有帮助,但足以说明它在权限中。尽管已经在控制台中成功实现了这一点,但我不能说我真的牢牢掌握了这里使用 pass 角色和其他权限概念。

"errorType": "UnauthorizedOperation", "errorMessage": "您无权执行此操作。编码授权失败消息:OhVTfR8eBb7y.....

PS 感谢您整理出我乱七八糟的代码格式!

标签: amazon-web-servicesamazon-iamaws-cdk

解决方案


问题 2 的答案如下所示:

对于动态 EC2 对象:

// create ec2 role & add policies.
      const ec2RoleR = new iam.Role(this, 'ec2RoleR', {
            assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
            description: 'EC2 Role - SES & s3 access.',
            roleName: 'sn-v1-EC2-Role-R'
      });

      ec2RoleR.addToPolicy(new iam.PolicyStatement({
            resources: [
                  s3Reports.bucketArn,
                  s3Analytics.bucketArn
            ],
            actions: [
                   's3:GetAccessPoint',
                   's3:PutAccountPublicAccessBlock',
                   's3:GetAccountPublicAccessBlock',
                   's3:ListAllMyBuckets',
                   's3:ListAccessPoints',
                   's3:ListJobs',
                   's3:CreateJob'
            ],
      }));

  ec2RoleR.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSESFullAccess'));

对于 Lambda:

// Add necessary policies to Lambda
      lambdaReportPutR.addToRolePolicy(new iam.PolicyStatement({ // needs SES & iotPublish permissions!
            effect: Effect.ALLOW,
            resources: [
                  "arn:aws:iam::xxxxxxxxx:role/EC2Role-R-Machine", // console role.
                  ec2RoleR.roleArn // cdk role above
            ],
            actions: ['iam:PassRole'],
      })); 
      
      // create & add role to * instance
      lambdaReportPutR.addToRolePolicy(new iam.PolicyStatement({
            effect: iam.Effect.ALLOW,
            resources: ['arn:aws:iam::xxxxxxxxx:*'],
            actions: [
                  "iam:CreateInstanceProfile",
                  "iam:AddRoleToInstanceProfile"
            ]
      }));

      // ec2 full access by lambda.
      lambdaReportPutR.role?.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonEC2FullAccess'));

推荐阅读