Amazon web services CDK中的高级任务处理:passRole、创建实例&;传递多个权限

Amazon web services CDK中的高级任务处理:passRole、创建实例&;传递多个权限,amazon-web-services,amazon-iam,aws-cdk,Amazon Web Services,Amazon Iam,Aws Cdk,我对CDK有一个非常棘手的IAM/权限问题。我已经在控制台上用过了。这是一个分为两部分的问题,第一部分是关于我已经做过的事情,第二部分是关于如何在CDK中复制它 现有解决方案 我有一个Lambda函数,它可以从多个源触发。每个源都提供一些控制执行的参数。lambda的主要任务是创建一个EC2实例,并向其发送一个要执行的用户数据脚本。虚拟机将spot实例排队以节省一些资金,当它完成时,它将终止。这是一个相当庞大的虚拟机,因为它需要执行一些相当繁重的数据处理,但很少,因此我不让它一直保持活动状态 虚

我对CDK有一个非常棘手的IAM/权限问题。我已经在控制台上用过了。这是一个分为两部分的问题,第一部分是关于我已经做过的事情,第二部分是关于如何在CDK中复制它

现有解决方案 我有一个Lambda函数,它可以从多个源触发。每个源都提供一些控制执行的参数。lambda的主要任务是创建一个EC2实例,并向其发送一个要执行的用户数据脚本。虚拟机将spot实例排队以节省一些资金,当它完成时,它将终止。这是一个相当庞大的虚拟机,因为它需要执行一些相当繁重的数据处理,但很少,因此我不让它一直保持活动状态

虚拟机本身需要特权来发送SES电子邮件,并访问s3存储桶进行读写

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

  • 基本执行
  • EC2完全访问AWS管理策略
  • 自定义通行证角色策略,如下所示:
  • 通行证角色策略包含以下权限:

    • 在我的帐户中创建“*”实例
    • 将角色添加到我的帐户中的“*”实例
    • 传递角色(EC2自定义角色)
    EC2自定义角色 此EC2自定义角色包含2个策略

    • SES完全访问权限
    • s3访问大约8个不同的操作“s3:xxxxx”,用于4个独立的bucket资源。见下文。注:“s3:*”是在事情不顺利的时候悄悄出现的,这需要一些挠头来解释为什么这是必要的
    问题1 虽然这有效。。。是这样吗?是否应该对安全性或最佳实践进行改进

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

    // 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的错误消息。恐怕没有多大帮助,但足以说明它在许可证中。尽管已经在控制台中成功地实现了这一点,但我不能说我真正掌握了passrole和其他权限概念的使用

    “错误类型”:“未经授权的操作”, “errorMessage”:“您无权执行此操作。编码的授权失败消息:OhVTfR8eBb7y

    PS感谢您整理我混乱的代码格式!

    关于Q1

    您写了“大约8个不同的操作‘s3:xxxxx’”,但您的策略允许所有可能的s3操作,而不仅仅是8个,因为
    s3:
    在:

                 "Action":[
                    "s3:*",
                    "s3:ListObjectsV2"
                 ],
    

    这包括删除对象和存储桶。

    问题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'));
    

    “开始着手研究,但很快就撞到了墙上“这并不具体。我想你可以用你的CDK代码,确切的错误消息(如果有的话),或者解释为什么这个代码不能像预期的那样工作。在lambda和错误消息上发布了额外的细节。这是一个正在进行的工作,有测试资源!但这一点很重要。我需要对确切的权限更严格。@monkey我还想知道,既然您有多个bucket,也许通过bucket策略从您的角色控制对它们的访问会更容易。这将简化您的角色,并将bucket访问权限管理委托给相应的bucket,而不是将所有内容放在一个角色下。True。使用桶策略是一个好主意。减少混乱。一个缺点是它们必须非常通用,因为ec2资源是动态创建和销毁的,所以它需要类似于ec2:*。我将给出第2个问题的答案,看看在我提出的问题上是否有任何进展。
    // 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'));
    
    // 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'));