title: iam:PutRolePolicy User: xxx is not authorized to perform: iam:PutRolePolicy on resource: role yyy
body: <p>I have a cloudformation stack to create my codepipeline/codebuild resources etc. When I try to run it, I get:</p>
  
  <blockquote>
    <p>iam:PutRolePolicy User: arn:aws:sts::0000000000:assumed-role/aaaaaaaaaa/AWSCloudFormation is not authorized to perform: iam:PutRolePolicy on resource: role bbbbbbbbbb</p>
  </blockquote>
  
  <p>Whats wrong? I already have a policy like: </p>
  
  <pre><code>- Effect: Allow
    Resource: !Sub 'arn:aws:iam::${AWS::AccountId}:role/*'
    Action:
    - 'iam:GetRole'
    - 'iam:CreateRole'
    - 'iam:DeleteRole'
    - 'iam:PassRole'
    - 'iam:AttachRolePolicy'
    - 'iam:DetachRolePolicy'
    - 'iam:DeleteRolePolicy'
    - 'iam:PutRolePolicy'
  </code></pre>
  
  <p>My stack YAML</p>
  
  <pre><code>AWSTemplateFormatVersion : '2010-09-09'
  Description: 'Skynet stack for CodePipeline'
  
  Parameters:
    PipelineName:
      Type: String
      Description: Pipeline Name (Lower case only, since S3 bucket names can only have lowercase)
      Default: skynet-pipeline
    GitHubOwner:
      Type: String
      Description: GitHub Owner
      Default: 2359media
    GitHubRepo:
      Type: String
      Description: GitHub Repo
      Default: 'skynet'
    GitHubBranch:
      Type: String
      Description: GitHub Branch
      Default: master
    GitHubToken:
      Type: String
      Description: GitHub Token
      NoEcho: true
  
  Resources:
    Pipeline:
      Type: AWS::CodePipeline::Pipeline
      Properties:
        Name: !Ref PipelineName
        RoleArn: !GetAtt [PipelineRole, Arn]
        ArtifactStore:
          Location: !Ref PipelineArtifactStore
          Type: S3
        DisableInboundStageTransitions: []
        Stages:
          - Name: GitHubSource
            Actions:
            - Name: Source
              ActionTypeId:
                Category: Source
                Owner: ThirdParty
                Version: 1
                Provider: GitHub
              Configuration:
                Owner: !Ref GitHubOwner
                Repo: !Ref GitHubRepo
                Branch: !Ref GitHubBranch
                OAuthToken: !Ref GitHubToken
              OutputArtifacts:
                - Name: SourceCode
          - Name: Build
            Actions:
            - Name: Lambda
              InputArtifacts:
                - Name: SourceCode
              OutputArtifacts:
                - Name: LambdaPackage
              ActionTypeId:
                Category: Build
                Owner: AWS
                Version: 1
                Provider: CodeBuild
              Configuration:
                ProjectName: !Ref CodeBuildLambda
          - Name: CreateChangeSet
            Actions:
            - Name: Lambda
              InputArtifacts:
                - Name: LambdaPackage
              OutputArtifacts:
                - Name: LambdaDeployment
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Version: 1
                Provider: CloudFormation
              Configuration:
                ActionMode: CHANGE_SET_REPLACE
                ChangeSetName: !Sub
                  - '${PipelineName}-lambda'
                  - {PipelineName: !Ref PipelineName}
                RoleArn: !GetAtt [CloudFormationRole, Arn]
                StackName: !Sub
                  - '${PipelineName}-lambda'
                  - {PipelineName: !Ref PipelineName}
                TemplatePath: 'LambdaPackage::SkynetLambdaPackaged.yml'
          - Name: ExecuteChangeSet
            Actions:
            - Name: Lambda
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Version: 1
                Provider: CloudFormation
              Configuration:
                ActionMode: CHANGE_SET_EXECUTE
                ChangeSetName: !Sub
                  - '${PipelineName}-lambda'
                  - {PipelineName: !Ref PipelineName}
                StackName: !Sub
                  - '${PipelineName}-lambda'
                  - {PipelineName: !Ref PipelineName}
  
    CodeBuildLambda:
      Type: AWS::CodeBuild::Project
      Properties:
        Name: !Sub '${PipelineName}-lambda'
        Artifacts:
          Type: CODEPIPELINE
        Environment:
          ComputeType: BUILD_GENERAL1_SMALL
          Image: aws/codebuild/nodejs:7.0.0
          Type: LINUX_CONTAINER
          EnvironmentVariables:
            - Name: S3_BUCKET
              Value: !Ref PipelineArtifactStore
        ServiceRole: !Ref CodeBuildRole
        Source:
          BuildSpec: 'lambda/buildspec.yml'
          Type: CODEPIPELINE
  
    PipelineArtifactStore:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: !Sub '${PipelineName}-artifacts'
        VersioningConfiguration:
          Status: Enabled
  
    CodeBuildRole:
      Type: AWS::IAM::Role
      Properties:
        RoleName: !Sub '${PipelineName}-codebuild'
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            Effect: Allow
            Principal:
              Service: codebuild.amazonaws.com
            Action: sts:AssumeRole
        Policies:
          - PolicyName: !Sub '${PipelineName}-codebuild'
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Effect: Allow
                  Resource: 'arn:aws:logs:*:*:*'
                  Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                - Effect: Allow
                  Resource:
                    - !Sub 'arn:aws:s3:::codepipeline-${AWS::Region}-*/*'
                    - !Sub
                      - '${PipelineArtifactStoreArn}/*'
                      - {PipelineArtifactStoreArn: !GetAtt [PipelineArtifactStore, Arn]}
                  Action:
                    - 's3:GetObject'
                    - 's3:GetObjectVersion'
                    - 's3:PutObject'
  
    CloudFormationRole:
      Type: AWS::IAM::Role
      Properties:
        RoleName: !Sub '${PipelineName}-cloudformation'
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Principal:
              Service: cloudformation.amazonaws.com
            Action:
            - sts:AssumeRole
        ManagedPolicyArns:
          - 'arn:aws:iam::aws:policy/AWSLambdaExecute'
        Policies:
          - PolicyName: !Sub '${PipelineName}-cloudformation'
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Effect: Allow
                  Resource: '*'
                  Action:
                  - 's3:GetObject'
                  - 's3:GetObjectVersion'
                  - 's3:GetBucketVersioning'
                - Effect: Allow
                  Resource: 'arn:aws:s3:::codepipeline*'
                  Action:
                  - 's3:PutObject'
                - Effect: Allow
                  Resource: !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:*'
                  Action:
                  - 'lambda:*'
                - Effect: Allow
                  Resource: !Sub 'arn:aws:apigateway:${AWS::Region}::*'
                  Action:
                  - 'apigateway:*'
                - Effect: Allow
                  Resource: '*'
                  Action:
                  - 'lambda:CreateEventSourceMapping'
                  - 'lambda:DeleteEventSourceMapping'
                  - 'lambda:GetEventSourceMapping'
                - Effect: Allow
                  Resource: !Sub 'arn:aws:iam::${AWS::AccountId}:role/*'
                  Action:
                  - 'iam:GetRole'
                  - 'iam:CreateRole'
                  - 'iam:DeleteRole'
                  - 'iam:PassRole'
                  - 'iam:AttachRolePolicy'
                  - 'iam:DetachRolePolicy'
                  - 'iam:DeleteRolePolicy'
                  - 'iam:PutRolePolicy'
                - Effect: Allow
                  Resource: '*'
                  Action:
                  - 'iam:PassRole'
                - Effect: Allow
                  Resource: !Sub 'arn:aws:cloudformation:${AWS::Region}:aws:transform/Serverless-2016-10-31'
                  Action:
                  - 'cloudformation:CreateChangeSet'
  
    PipelineRole:
      Type: AWS::IAM::Role
      Properties:
        RoleName: !Sub '${PipelineName}-pipeline'
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Action: ['sts:AssumeRole']
            Effect: Allow
            Principal:
              Service: [codepipeline.amazonaws.com]
        Path: /
        Policies:
          - PolicyName: SkynetPipeline
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Action:
                  - 's3:GetObject'
                  - 's3:GetObjectVersion'
                  - 's3:GetBucketVersioning'
                  Effect: 'Allow'
                  Resource: '*'
                - Action:
                  - 's3:PutObject'
                  Effect: 'Allow'
                  Resource:
                  - !GetAtt [PipelineArtifactStore, Arn]
                - Action:
                  - 'codecommit:CancelUploadArchive'
                  - 'codecommit:GetBranch'
                  - 'codecommit:GetCommit'
                  - 'codecommit:GetUploadArchiveStatus'
                  - 'codecommit:UploadArchive'
                  Effect: 'Allow'
                  Resource: '*'
                - Action:
                  - 'codedeploy:CreateDeployment'
                  - 'codedeploy:GetApplicationRevision'
                  - 'codedeploy:GetDeployment'
                  - 'codedeploy:GetDeploymentConfig'
                  - 'codedeploy:RegisterApplicationRevision'
                  Effect: 'Allow'
                  Resource: '*'
                - Action:
                  - 'elasticbeanstalk:*'
                  - 'ec2:*'
                  - 'elasticloadbalancing:*'
                  - 'autoscaling:*'
                  - 'cloudwatch:*'
                  - 's3:*'
                  - 'sns:*'
                  - 'cloudformation:*'
                  - 'rds:*'
                  - 'sqs:*'
                  - 'ecs:*'
                  - 'iam:PassRole'
                  Effect: 'Allow'
                  Resource: '*'
                - Action:
                  - 'lambda:InvokeFunction'
                  - 'lambda:ListFunctions'
                  Effect: 'Allow'
                  Resource: '*'
                - Action:
                  - 'opsworks:CreateDeployment'
                  - 'opsworks:DescribeApps'
                  - 'opsworks:DescribeCommands'
                  - 'opsworks:DescribeDeployments'
                  - 'opsworks:DescribeInstances'
                  - 'opsworks:DescribeStacks'
                  - 'opsworks:UpdateApp'
                  - 'opsworks:UpdateStack'
                  Effect: 'Allow'
                  Resource: '*'
                - Action:
                  - 'cloudformation:CreateStack'
                  - 'cloudformation:DeleteStack'
                  - 'cloudformation:DescribeStacks'
                  - 'cloudformation:UpdateStack'
                  - 'cloudformation:CreateChangeSet'
                  - 'cloudformation:DeleteChangeSet'
                  - 'cloudformation:DescribeChangeSet'
                  - 'cloudformation:ExecuteChangeSet'
                  - 'cloudformation:SetStackPolicy'
                  - 'cloudformation:ValidateTemplate'
                  - 'iam:PassRole'
                  Effect: 'Allow'
                  Resource: '*'
                - Action:
                  - 'codebuild:BatchGetBuilds'
                  - 'codebuild:StartBuild'
                  Effect: 'Allow'
                  Resource: '*'
  </code></pre>