When do I need to have CAPABILITY_NAMED_IAM
Solution 1
When are CAPABILITY_IAM
/CAPABILITY_NAMED_IAM
Required
According to CloudFormation CreateStack Parameters, one of these is required when your Template includes any of the following resource types:
AWS::IAM::AccessKey
AWS::IAM::Group
AWS::IAM::InstanceProfile
AWS::IAM::Policy
AWS::IAM::Role
AWS::IAM::User
AWS::IAM::UserToGroupAddition
When to use CAPABILITY_NAMED_IAM
instead of CAPABILITY_IAM
When any of your IAM resources have a custom name, such as a RoleName
then CAPABILITY_NAMED_IAM
is required.
Why are these required?
The Capabilities are there to ensure you realize that you're creating IAM resources, that these will modify the permissions on your account, and that you have reviewed these resources and their permissions as necessary.
Solution 2
You've added a resource of type AWS::IAM::Role to your resources section. This tells CloudFormation to create an IAM Role. In order to create IAM resources, you need to supply CAPABILITY_IAM or CAPABILITY_NAMED_IAM. It's an acknowledgement from you to CloudFormation that you understand that you are creating resources that can affect permissions in your AWS account.
Note on use of CAPABILITY_NAMED_IAM vs CAPABILITY_IAM:
- If you have IAM resources with custom names, you must specify CAPABILITY_NAMED_IAM.
- Otherwise, if you have IAM resources, you can specify either capability.
Jiew Meng
Web Developer & Computer Science Student Tools of Trade: PHP, Symfony MVC, Doctrine ORM, HTML, CSS, jQuery/JS Looking at Python/Google App Engine, C#/WPF/Entity Framework I hope to develop usable web applications like Wunderlist, SpringPad in the future
Updated on June 07, 2022Comments
-
Jiew Meng almost 2 years
I was editing my CloudFormation templates and suddenly AWS tells me I need
CAPABILITY_NAMED_IAM
. I am curious as to which change triggers this?What is a named IAM resource?
Before I already "name" my resources like
RoleName: !Sub '${PipelineName}-codebuild'
I am not asked to add this capability, I think until I add
Parameters: AppName: Type: String Description: Prefix for resources Resources: LambdaRole: Type: AWS::IAM::Role Properties: RoleName: !Ref AppName
To my SAM application template. But arent they the "same" except one uses
!Ref
? Or maybe some other change triggered this?For reference, my CodePipeline stack
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' Capabilities: CAPABILITY_NAMED_IAM ParameterOverrides: !Sub '{"AppName": "${PipelineName}-lambda"}' - 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: '*' 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: '*'
The part of SAM stack (
sam.yml
) changed recentlyAWSTemplateFormatVersion : '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: 'Skynet. AWS Management Assistant' Parameters: AppName: Type: String Description: Prefix for resources Resources: LambdaRole: Type: AWS::IAM::Role Properties: RoleName: !Ref AppName AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com - apigateway.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - 'arn:aws:iam::aws:policy/AmazonEC2FullAccess' - 'arn:aws:iam::aws:policy/AWSLambdaFullAccess' - 'arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess' - 'arn:aws:iam::aws:policy/AmazonAPIGatewayInvokeFullAccess' - 'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess'
-
Jiew Meng over 6 yearsAs long as I am naming my IAM resources I need the named IAM capability correct?
-
Jamie Starke over 6 yearsYes, as long as the CloudFormation Stack has an IAM Resource that is named.
-
PureW over 2 yearsThis doesn't answer the question of when to use which of
CAPABILITY_IAM
vsCAPABILITY_NAMED_IAM
-
jarmod over 2 years@PureW Good point, have added clarification.