我啥时候需要 CAPABILITY_NAMED_IAM

Posted

技术标签:

【中文标题】我啥时候需要 CAPABILITY_NAMED_IAM【英文标题】:When do I need to have CAPABILITY_NAMED_IAM我什么时候需要 CAPABILITY_NAMED_IAM 【发布时间】:2018-02-25 08:31:06 【问题描述】:

我正在编辑我的 CloudFormation 模板,突然 AWS 告诉我我需要 CAPABILITY_NAMED_IAM。我很好奇哪个变化触发了这个?

什么是命名的 IAM 资源?

在我已经“命名”我的资源之前

RoleName: !Sub '$PipelineName-codebuild'

我没有被要求添加此功能,我认为在我添加之前

Parameters:
  AppName:
    Type: String
    Description: Prefix for resources

Resources:
  LambdaRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Ref AppName

到我的 SAM 应用程序模板。但是除了一个使用!Ref之外,它们不是“相同的”吗?或者也许其他一些变化触发了这个?

作为参考,我的 CodePipeline 堆栈

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: '*'

SAM 堆栈 (sam.yml) 的部分最近发生了变化

AWSTemplateFormatVersion : '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'

【问题讨论】:

【参考方案1】:

什么时候需要CAPABILITY_IAM/CAPABILITY_NAMED_IAM

根据CloudFormation CreateStack Parameters,当您的模板包含以下任何资源类型时,需要其中之一:

AWS::IAM::AccessKey
AWS::IAM::Group
AWS::IAM::InstanceProfile
AWS::IAM::Policy
AWS::IAM::Role
AWS::IAM::User
AWS::IAM::UserToGroupAddition 

何时使用CAPABILITY_NAMED_IAM 而不是CAPABILITY_IAM

如果您的任何 IAM 资源具有自定义名称,例如 RoleName,则需要 CAPABILITY_NAMED_IAM

为什么需要这些?

这些功能可确保您意识到您正在创建 IAM 资源,这些资源将修改您账户的权限,并且您已根据需要查看了这些资源及其权限。

【讨论】:

只要我命名我的 IAM 资源,我需要正确命名的 IAM 功能吗? 可以,只要 CloudFormation 堆栈有一个已命名的 IAM 资源。【参考方案2】:

您已将AWS::IAM::Role 类型的资源添加到您的资源部分。这告诉 CloudFormation 创建一个 IAM 角色。为了创建 IAM 资源,您需要提供 CAPABILITY_IAM 或 CAPABILITY_NAMED_IAM。这是您对 CloudFormation 的确认,您了解您正在创建可能影响您 AWS 账户中权限的资源。

关于使用 CAPABILITY_NAMED_IAM 与 CAPABILITY_IAM 的注意事项:

    如果您的 IAM 资源具有自定义名称,则必须指定 CAPABILITY_NAMED_IAM。 否则,如果您有 IAM 资源,则可以指定任一功能。

【讨论】:

这并没有回答何时使用 CAPABILITY_IAMCAPABILITY_NAMED_IAM 中的哪一个的问题 @PureW 好点,已添加说明。

以上是关于我啥时候需要 CAPABILITY_NAMED_IAM的主要内容,如果未能解决你的问题,请参考以下文章

我啥时候需要使用四元数?

贝宝订阅 API 集成。我啥时候需要创建产品?

我啥时候需要 CAPABILITY_NAMED_IAM

我啥时候需要处理(服务器-客户端)对象?

我啥时候需要在 Heroku 中使用工作进程

我啥时候需要在 Gradle 依赖项中使用 Kapt?