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

时间:2017-10-24 12:30:37

标签: amazon-web-services amazon-ec2 amazon-cloudformation

我正在编写一个包含单个EC2实例和EBS卷的Cloudformation模板。我稍后在使用Powershell脚本创建计算机时附加卷。当我把通配符' *'但是在策略语句资源中我想限制对一个实例和一个ebs卷的访问。使用EBS卷很容易我可以在模板中引用它并在角色之前创建但实例问题是实例需要首先创建角色,但也能够创建我们需要的实例首先创建角色。什么是解决这种循环依赖的好方法?

这是我的模板:

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

2 个答案:

答案 0 :(得分:0)

循环依赖的一个常见解决方案是执行此操作是多个步骤:使用最少的资源创建堆栈,然后修改模板并更新堆栈。

因此,模板的v1只创建基本的依赖资源,而在v2中,您修改模板以添加依赖资源并同时修改原始依赖资源。然后进行堆栈更新。

另请参阅more ideas

答案 1 :(得分:0)

在您的特定示例中,您具有以下依赖关系链:InstanceRole -> DataVolume -> Instance -> InstanceProfile -> InstanceRole

通常,当角色取决于您的资源资源取决于您的角色时,是AWS::IAM::Policy资源类型有用的地方。这基本上解除了 IAM角色上的特定政策与 IAM政策本身同时解决的问题。

为此,您需要使用 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::Role'
    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

有了这个, InstanceRolePolicy 取决于 InstanceRole DataVolume ,但 InstanceRole 不依赖于在任何事情上,DataVolume -> Instance -> InstanceProfile -> InstanceRole链都可以解决。