我正在编写一个包含单个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
答案 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
链都可以解决。