简体   繁体   English

AWS Cloudformation 模板 EC2 角色/策略循环依赖

[英]AWS Cloudformation template EC2 Role/Policy circular dependency

I am writing a Cloudformation template with a single EC2 instance and an EBS volume.我正在编写一个带有单个 EC2 实例和一个 EBS 卷的 Cloudformation 模板。 I attach the volume later on at some point when the machine is created using Powershell script.我稍后会在使用 Powershell 脚本创建机器时附加卷。 It works when I put wildcard '*' in policy statement resource however I want to limit the access to one instance and one ebs volume.当我在策略声明资源中放置通配符 '*' 时它起作用,但是我想限制对一个实例和一个 ebs 卷的访问。 With EBS volume it's easy I can just refer it in the template and it is created before the role but with instance the problem is that instance requires the role to be created first but also to be able to create the instance we need to create the role first.使用 EBS 卷很容易,我可以在模板中引用它,它是在角色之前创建的,但对于实例,问题是实例需要首先创建角色,但也需要能够创建我们需要创建角色的实例首先。 What's a good way of resolving this kind of circular dependency?解决这种循环依赖的好方法是什么?

Here is my template:这是我的模板:

Resources:
  InstanceRole:
    Type: 'AWS::IAM::Role'
    Properties:
      RoleName: InstanceRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      Policies:
        - PolicyName: AttachVolume
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - 'ec2:AttachVolume'
                Resource:
                  - !Join 
                    - ''
                    - - 'arn:aws:ec2:'
                      - !Ref 'AWS::Region'
                      - ':'
                      - !Ref 'AWS::AccountId'
                      - ':instance/*'
                  - !Join 
                    - ''
                    - - 'arn:aws:ec2:'
                      - !Ref 'AWS::Region'
                      - ':'
                      - !Ref 'AWS::AccountId'
                      - ':volume/'
                      - !Ref DataVolume             
  InstanceProfile:
    Type: 'AWS::IAM::InstanceProfile'
    Properties:
      Roles:
        - !Ref InstanceRole
      InstanceProfileName: InstanceProfile
  Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      ImageId: !Ref AMI
      InstanceType: !Ref InstanceType
      IamInstanceProfile: !Ref InstanceProfile
      KeyName: ec2key
      BlockDeviceMappings:
        - DeviceName: /dev/sda1
          Ebs:
            VolumeType: gp2
            DeleteOnTermination: 'true'
            VolumeSize: '30'
      Tags:
        - Key: Name
          Value: MyInstance
      SubnetId: !Ref SubnetId
      SecurityGroupIds:
        - !Ref SGId
      UserData: !Base64 
        'Fn::Join':
          - ''
          - - |
              <script>
            - 'cfn-init.exe -v -c config -s '
            - !Ref 'AWS::StackId'
            - ' -r Instance'
            - ' --region '
            - !Ref 'AWS::Region'
            - |+

            - |
              </script>
  DataVolume:
    Type: "AWS::EC2::Volume"
    Properties:  
      AvailabilityZone: !GetAtt 
        - Instance
        - AvailabilityZone
      Size: "100"
      Tags:
        - Key: Name
          Value: InstanceExtraVolume

In your particular example, you have the following dependency chain: InstanceRole -> DataVolume -> Instance -> InstanceProfile -> InstanceRole在您的特定示例中,您具有以下依赖项链: InstanceRole -> DataVolume -> Instance -> InstanceProfile -> InstanceRole

In general, when your Role depends on your Resources and your Resources depend on your Role , this is where the AWS::IAM::Policy resource type is useful.通常,当您的Role依赖于您的Resources而您的Resources依赖于您的Role 时,这就是AWS::IAM::Policy资源类型的用处。 This basically decouples the particular policy on the IAM Role from being resolved at the same time as the IAM Policy itself.这基本上将IAM 角色上的特定策略与IAM 策略本身解耦。

To do this, you would take your InstanceRole and split it into an InstanceRole and an InstanceRolePolicy为此,您需要将InstanceRole拆分为一个InstanceRole和一个InstanceRolePolicy

Resources:
  InstanceRole:
    Type: 'AWS::IAM::Role'
    Properties:
      RoleName: InstanceRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
  InstanceRolePolicy:
    Type: 'AWS::IAM::Policy'
    Properties:
      Roles:
        - !Ref InstanceRole
      PolicyName: AttachVolume
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Action:
              - 'ec2:AttachVolume'
            Resource:
              - !Join 
                - ''
                - - 'arn:aws:ec2:'
                  - !Ref 'AWS::Region'
                  - ':'
                  - !Ref 'AWS::AccountId'
                  - ':instance/*'
              - !Join 
                - ''
                - - 'arn:aws:ec2:'
                  - !Ref 'AWS::Region'
                  - ':'
                  - !Ref 'AWS::AccountId'
                  - ':volume/'
                  - !Ref DataVolume

With that, the InstanceRolePolicy depends on the InstanceRole and DataVolume , but the InstanceRole doesn't depend on anything, so the DataVolume -> Instance -> InstanceProfile -> InstanceRole chain can resolve.这样, InstanceRolePolicy取决于InstanceRoleDataVolume ,但InstanceRole不依赖任何东西,因此DataVolume -> Instance -> InstanceProfile -> InstanceRole链可以解析。

One common solution to circular dependencies is to do this is multiple steps: create the stack with minimal resources, then modify the template and update the stack.循环依赖的一种常见解决方案是执行多个步骤:使用最少的资源创建堆栈,然后修改模板并更新堆栈。

So, v1 of your template creates just the basic dependent resource and in v2, you modify the template to add the depending resource and modify the original dependent resource at the same time.因此,模板的 v1 仅创建基本依赖资源,而在 v2 中,您修改模板以添加依赖资源并同时修改原始依赖资源。 Then do a stack update.然后进行堆栈更新。

Also, see more ideas .另外,请参阅更多想法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM