[ CloudFormation ] WaitCondition for race conditions in IAM templates

0

Hi,
I'm working on a template that allows to create a user, add it to any groups if need, tag it, add managed policies and in-line policies:

## =================== VERSION ===================  
AWSTemplateFormatVersion: '2010-09-09'  
  
## =================== DESCRIPTION ===================  
Description: >-  
  Creates an IAM User if none is present, optionally manage to which IAM group(s) the user belongs to  
  Optionally embed AWS managed policies, customer managed policies and inline policies in the user  
  
## =================== METADATA ===================  
Metadata:   
  AWS::CloudFormation::Interface:   
    ParameterGroups:   
      -  
        Label:  
          default: Set a one-time password   
        Parameters:  
          - paramOneTimePassword  
    ParameterLabels:  
      paramOneTimePassword:  
        default: ' '  
  
## =================== PARAMETERS ===================  
Parameters:  
  paramOneTimePassword:  
    Description: The user will have to pick a new password upon first sign in  
    Type: String      
    NoEcho: 'true' # mask the parameter value as asterisks (*****) to prevent it from being displayed in the console, CLI, or API  
    ConstraintDescription: Password must be between 8 and 32 characters, start with lowercase or uppercase letter, and can be alphanumeric with the following special characters !@#$%&  
  
## =================== MAPPINGS ===================  
Mappings:  
  mapUserData:  
    UserName:  
      AWS: testuser  
      Real: 'Test User'  
    Groups:  
      Group: BackendDev  
    Tags:  
      product: testProduct  
  mapManagedPolicies:  
    CustomerManagedPolicies:   
      ARN: None  
  
## =================== CONDITIONS ===================  
Conditions:  
  hasManagedPolicy:  
    !Not \[!Equals \[!FindInMap \[mapManagedPolicies, CustomerManagedPolicies, ARN], 'None'] ]  
   
## =================== RESOURCES ===================  
Resources:  
  myInlinePolicyForChangeOwnPassword:  
    Type: 'AWS::IAM::Policy'  
    Properties:  
      PolicyName: IAM-ChangeOwnPassword  
      PolicyDocument:  
        Version: '2012-10-17'  
        Statement:  
          - Effect: Allow  
            Sid: ViewAccountPasswordRequirements  
            Action: 'iam:GetAccountPasswordPolicy'  
            Resource: "*"  
          - Effect: Allow  
            Sid: ChangeOwnPassword  
            Action:  
              - 'iam:GetUser'  
              - 'iam:ChangePassword'  
            Resource: !Join \['', \[arn:aws:iam::*:user/,!FindInMap \[mapUserData, UserName, AWS]]]  
      Users:  
        - !FindInMap \[mapUserData, UserName, AWS]  
  myUser:  
    Type: 'AWS::IAM::User'  
    Properties:  
      UserName: !FindInMap \[mapUserData, UserName, AWS]  
      LoginProfile:  
        Password: !Ref paramOneTimePassword   
        PasswordResetRequired: true   
      Groups:  
        - !FindInMap \[mapUserData, Groups, Group]  
      ManagedPolicyArns: # list of ARNs of IAM managed policies that you want to attach to the user  
        - !If \[ hasManagedPolicy, !FindInMap \[mapManagedPolicies, CustomerManagedPolicies, ARN], !Ref "AWS::NoValue" ]  
      Tags:  
        - Key: name  
          Value: !FindInMap \[mapUserData, UserName, Real]  
        - Key: product  
          Value: !FindInMap \[mapUserData, Tags, product]  
  WaitCondition:  
    Type: AWS::CloudFormation::WaitCondition  
    DependsOn: myUser  
    Properties:  
      # Handle: !Ref WaitHandle  
      Timeout: 120  
      Count: 1  
  
## =================== OUTPUT ===================  
Outputs:  
  outputArn:  
    Description: User ARN  
    Value: !GetAtt myUser.Arn  
  outputName:  
    Description: User name  
    Value: !Ref myUser  

The problem tho is that there's a race condition when sometimes the user is quickly created, so the in-line policy can be correctly attached, but other times it pops.
I've read about the WaitCondition resource (and WaitConditionHandle), but I can't really find a way to make CF wait and evaluate the AWS::IAM::User resource before going ahead and trying to attach the inline policy.

I'm running out of ideas here, thoughts?

cig0
質問済み 3年前537ビュー
1回答
0

Solved! Please check here the answer if you're interested in learning how to add both managed and inline policies to a user at the moment of user creation (I'm pointing to an external resource since these forums don't do well with code formatting): https://devops.stackexchange.com/questions/14344/how-to-add-a-wait-condition-when-creating-iam-entities/14345#14345

cig0
回答済み 3年前

ログインしていません。 ログイン 回答を投稿する。

優れた回答とは、質問に明確に答え、建設的なフィードバックを提供し、質問者の専門分野におけるスキルの向上を促すものです。

質問に答えるためのガイドライン

関連するコンテンツ