在CloudFormation中创建自假设IAM角色时的竞态条件问题
解决CloudFormation中IAM角色自假设的竞态条件问题
方案1:分离角色创建与信任策略配置(推荐)
把角色创建和信任策略拆成两个独立资源,利用CloudFormation的依赖关系,确保信任策略在角色完全创建后再应用,从根源避免竞态条件。
模板示例:
AWSTemplateFormatVersion: '2010-09-09' Resources: # 先创建带临时信任策略的角色(用账户根用户作为临时主体,保证角色能正常创建) MyNewRole: Type: AWS::IAM::Role Properties: RoleName: my-new-role AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: AWS: !Sub "arn:aws:iam::${AWS::AccountId}:root" Action: sts:AssumeRole # 再更新角色的信任策略,允许自身假设 MyNewRoleAssumePolicy: Type: AWS::IAM::AssumeRolePolicy Properties: RoleName: !Ref MyNewRole PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: AWS: !GetAtt MyNewRole.Arn Action: sts:AssumeRole
- 临时信任策略只是过渡用,后续会被
MyNewRoleAssumePolicy完全覆盖。 !GetAtt MyNewRole.Arn会在角色创建完成后解析出有效ARN,此时IAM能正常识别这个主体。
方案2:分两次部署模板(备选)
如果不想拆分资源,可以分两次部署模板:
第一次部署(创建角色)
用临时信任策略先把角色创建出来:
AWSTemplateFormatVersion: '2010-09-09' Resources: MyNewRole: Type: AWS::IAM::Role Properties: RoleName: my-new-role AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: AWS: !Sub "arn:aws:iam::${AWS::AccountId}:root" Action: sts:AssumeRole
第二次部署(更新信任策略)
替换信任策略为允许自身假设,此时角色已存在,!GetAtt能正确解析ARN:
AWSTemplateFormatVersion: '2010-09-09' Resources: MyNewRole: Type: AWS::IAM::Role Properties: RoleName: my-new-role AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: AWS: !GetAtt MyNewRole.Arn Action: sts:AssumeRole UpdateReplacePolicy: Retain DeletionPolicy: Retain
- 设置
UpdateReplacePolicy和DeletionPolicy为Retain,防止更新时角色被删除重建。
为什么之前的Fn::Sub无效?
创建角色时,CloudFormation会提前解析AssumeRolePolicyDocument里的所有引用,此时角色还未生成,IAM服务无法识别这个不存在的ARN作为主体,所以报错。而拆分资源或分两次部署,都是确保角色存在后再配置引用自身ARN的信任策略,自然解决了竞态问题。
内容的提问来源于stack exchange,提问作者Yonatan Adir
相关产品推荐
相关产品推荐

