aws-cloudformation-iam

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AWS CloudFormation IAM Security

AWS CloudFormation IAM 安全配置

Create production-ready IAM infrastructure using AWS CloudFormation templates. This skill covers users, roles, policies, managed policies, permission boundaries, and best practices for implementing least privilege access.
使用AWS CloudFormation模板创建可用于生产环境的IAM基础设施。本内容涵盖用户、角色、策略、托管策略、权限边界,以及实现最小权限访问的最佳实践。

When to Use

适用场景

Use this skill when:
  • Creating new IAM users with CloudFormation
  • Configuring IAM roles for AWS services
  • Defining inline policies and managed policies
  • Implementing cross-account access with STS
  • Creating permission boundaries
  • Organizing templates with Parameters, Outputs, Mappings, Conditions
  • Implementing cross-stack references for IAM resources
  • Configuring IAM Identity Center (SSO)
  • Managing service control policies (SCP)
在以下场景中使用本内容:
  • 使用CloudFormation创建新的IAM用户
  • 为AWS服务配置IAM角色
  • 定义内联策略和托管策略
  • 通过STS实现跨账户访问
  • 创建权限边界
  • 使用Parameters、Outputs、Mappings、Conditions组织模板
  • 为IAM资源实现跨栈引用
  • 配置IAM Identity Center(SSO)
  • 管理服务控制策略(SCP)

CloudFormation Template Structure

CloudFormation模板结构

Standard Format Base Template

标准格式基础模板

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM infrastructure with users, roles, and policies

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: User Configuration
        Parameters:
          - UserName
          - UserPermissionsBoundary
      - Label:
          default: Role Configuration
        Parameters:
          - RoleName
          - AssumeRolePolicyService

Parameters:
  UserName:
    Type: String
    Default: app-user
    Description: Name of the IAM user
    MinLength: 1
    MaxLength: 64

  UserPermissionsBoundary:
    Type: String
    Description: IAM policy ARN for permissions boundary
    Default: ""

  RoleName:
    Type: String
    Default: app-execution-role
    Description: Name of the IAM role

  AssumeRolePolicyService:
    Type: String
    Default: lambda.amazonaws.com
    Description: Service that can assume the role
    AllowedValues:
      - lambda.amazonaws.com
      - ec2.amazonaws.com
      - ecs-tasks.amazonaws.com
      - eks.amazonaws.com
      - states.amazonaws.com

Mappings:
  EnvironmentConfig:
    dev:
      MaxSessionDuration: 3600
      PolicyArns: []
    staging:
      MaxSessionDuration: 7200
      PolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
    production:
      MaxSessionDuration: 43200
      PolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
        - arn:aws:iam::aws:policy/SecurityAudit

Conditions:
  HasPermissionsBoundary: !Not [!Equals [!Ref UserPermissionsBoundary, ""]]
  IsProduction: !Equals [!Ref Environment, production]

Transform:
  - AWS::Serverless-2016-10-31

Resources:
  # IAM User
  AppUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Ref UserName
      PermissionsBoundary: !If
        - HasPermissionsBoundary
        - !Ref UserPermissionsBoundary
        - !Ref AWS::NoValue
      Tags:
        - Key: Environment
          Value: !Ref Environment
        - Key: Project
          Value: !Ref ProjectName

Outputs:
  UserArn:
    Description: ARN of the IAM user
    Value: !GetAtt AppUser.Arn
    Export:
      Name: !Sub "${AWS::StackName}-UserArn"
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM infrastructure with users, roles, and policies

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: User Configuration
        Parameters:
          - UserName
          - UserPermissionsBoundary
      - Label:
          default: Role Configuration
        Parameters:
          - RoleName
          - AssumeRolePolicyService

Parameters:
  UserName:
    Type: String
    Default: app-user
    Description: Name of the IAM user
    MinLength: 1
    MaxLength: 64

  UserPermissionsBoundary:
    Type: String
    Description: IAM policy ARN for permissions boundary
    Default: ""

  RoleName:
    Type: String
    Default: app-execution-role
    Description: Name of the IAM role

  AssumeRolePolicyService:
    Type: String
    Default: lambda.amazonaws.com
    Description: Service that can assume the role
    AllowedValues:
      - lambda.amazonaws.com
      - ec2.amazonaws.com
      - ecs-tasks.amazonaws.com
      - eks.amazonaws.com
      - states.amazonaws.com

Mappings:
  EnvironmentConfig:
    dev:
      MaxSessionDuration: 3600
      PolicyArns: []
    staging:
      MaxSessionDuration: 7200
      PolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
    production:
      MaxSessionDuration: 43200
      PolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
        - arn:aws:iam::aws:policy/SecurityAudit

Conditions:
  HasPermissionsBoundary: !Not [!Equals [!Ref UserPermissionsBoundary, ""]]
  IsProduction: !Equals [!Ref Environment, production]

Transform:
  - AWS::Serverless-2016-10-31

Resources:
  # IAM User
  AppUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Ref UserName
      PermissionsBoundary: !If
        - HasPermissionsBoundary
        - !Ref UserPermissionsBoundary
        - !Ref AWS::NoValue
      Tags:
        - Key: Environment
          Value: !Ref Environment
        - Key: Project
          Value: !Ref ProjectName

Outputs:
  UserArn:
    Description: ARN of the IAM user
    Value: !GetAtt AppUser.Arn
    Export:
      Name: !Sub "${AWS::StackName}-UserArn"

Parameters Best Practices

参数最佳实践

AWS-Specific Parameter Types

AWS特定参数类型

yaml
Parameters:
  # AWS-specific types for validation
  UserArn:
    Type: AWS::IAM::User::Arn
    Description: IAM user ARN for reference

  RoleArn:
    Type: AWS::IAM::Role::Arn
    Description: IAM role ARN for reference

  PolicyArn:
    Type: AWS::IAM::Policy::Arn
    Description: IAM policy ARN

  ManagedPolicyArn:
    Type: AWS::IAM::ManagedPolicy::Arn
    Description: AWS managed policy ARN

  InstanceProfileArn:
    Type: AWS::IAM::InstanceProfile::Arn
    Description: IAM instance profile ARN

  S3BucketPolicy:
    Type: AWS::S3::BucketPolicy::Resource
    Description: S3 bucket policy reference
yaml
Parameters:
  # AWS-specific types for validation
  UserArn:
    Type: AWS::IAM::User::Arn
    Description: IAM user ARN for reference

  RoleArn:
    Type: AWS::IAM::Role::Arn
    Description: IAM role ARN for reference

  PolicyArn:
    Type: AWS::IAM::Policy::Arn
    Description: IAM policy ARN

  ManagedPolicyArn:
    Type: AWS::IAM::ManagedPolicy::Arn
    Description: AWS managed policy ARN

  InstanceProfileArn:
    Type: AWS::IAM::InstanceProfile::Arn
    Description: IAM instance profile ARN

  S3BucketPolicy:
    Type: AWS::S3::BucketPolicy::Resource
    Description: S3 bucket policy reference

Parameter Constraints

参数约束

yaml
Parameters:
  UserName:
    Type: String
    Default: app-user
    Description: IAM username
    MinLength: 1
    MaxLength: 64
    ConstraintDescription: Must be 1-64 characters
    AllowedPattern: "[a-zA-Z0-9+=,.@_-]+"

  RoleName:
    Type: String
    Default: execution-role
    Description: IAM role name
    MinLength: 1
    MaxLength: 64
    ConstraintDescription: Must be 1-64 characters
    AllowedPattern: "[a-zA-Z0-9+=,.@_-]+"

  MaxSessionDuration:
    Type: Number
    Default: 3600
    Description: Maximum session duration in seconds
    MinValue: 900
    MaxValue: 43200
    ConstraintDescription: Must be between 900 and 43200 seconds

  AccessKeyRotationFrequency:
    Type: Number
    Default: 90
    Description: Days between access key rotations
    MinValue: 1
    MaxValue: 365
    ConstraintDescription: Must be between 1 and 365 days
yaml
Parameters:
  UserName:
    Type: String
    Default: app-user
    Description: IAM username
    MinLength: 1
    MaxLength: 64
    ConstraintDescription: Must be 1-64 characters
    AllowedPattern: "[a-zA-Z0-9+=,.@_-]+"

  RoleName:
    Type: String
    Default: execution-role
    Description: IAM role name
    MinLength: 1
    MaxLength: 64
    ConstraintDescription: Must be 1-64 characters
    AllowedPattern: "[a-zA-Z0-9+=,.@_-]+"

  MaxSessionDuration:
    Type: Number
    Default: 3600
    Description: Maximum session duration in seconds
    MinValue: 900
    MaxValue: 43200
    ConstraintDescription: Must be between 900 and 43200 seconds

  AccessKeyRotationFrequency:
    Type: Number
    Default: 90
    Description: Days between access key rotations
    MinValue: 1
    MaxValue: 365
    ConstraintDescription: Must be between 1 and 365 days

SSM Parameter References per Policy ARNs

基于SSM参数存储的策略ARN引用

yaml
Parameters:
  ReadOnlyPolicyArn:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /iam/policies/read-only-arn
    Description: ARN of the read-only policy from SSM

  CustomPolicyDocument:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /iam/policies/custom-policy-json
    Description: Policy document from SSM Parameter Store
yaml
Parameters:
  ReadOnlyPolicyArn:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /iam/policies/read-only-arn
    Description: ARN of the read-only policy from SSM

  CustomPolicyDocument:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /iam/policies/custom-policy-json
    Description: Policy document from SSM Parameter Store

Outputs and Cross-Stack References

输出与跨栈引用

Export/Import Patterns for IAM

IAM资源的导出/导入模式

yaml
undefined
yaml
undefined

Stack A - IAM Core Stack

Stack A - IAM核心栈

AWSTemplateFormatVersion: 2010-09-09 Description: Core IAM infrastructure stack
Resources:

Execution Role for applications

ApplicationExecutionRole: Type: AWS::IAM::Role Properties: RoleName: !Sub "${AWS::StackName}-execution-role" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole MaxSessionDuration: 3600

Role for Cross-Account Access

CrossAccountReadRole: Type: AWS::IAM::Role Properties: RoleName: !Sub "${AWS::StackName}-crossaccount-read" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: AWS: !Sub "arn:aws:iam::${TargetAccountId}:root" Action: sts:AssumeRole Condition: StringEquals: sts:Externalid: !Ref ExternalId Policies: - PolicyName: ReadOnlyAccess PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - s3:GetObject - s3:GetObjectVersion Resource: !Ref SourceBucketArn - Effect: Allow Action: - dynamodb:Query - dynamodb:Scan - dynamodb:GetItem Resource: !Ref SourceTableArn
Outputs: ApplicationExecutionRoleArn: Description: ARN of the application execution role Value: !GetAtt ApplicationExecutionRole.Arn Export: Name: !Sub "${AWS::StackName}-ExecutionRoleArn"
CrossAccountReadRoleArn: Description: ARN for cross-account read access Value: !GetAtt CrossAccountReadRole.Arn Export: Name: !Sub "${AWS::StackName}-CrossAccountReadRoleArn"
CrossAccountReadRoleExternalId: Description: External ID for cross-account role assumption Value: !Ref ExternalId Export: Name: !Sub "${AWS::StackName}-CrossAccountExternalId"

```yaml
AWSTemplateFormatVersion: 2010-09-09 Description: Core IAM infrastructure stack
Resources:

应用程序执行角色

ApplicationExecutionRole: Type: AWS::IAM::Role Properties: RoleName: !Sub "${AWS::StackName}-execution-role" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole MaxSessionDuration: 3600

跨账户访问角色

CrossAccountReadRole: Type: AWS::IAM::Role Properties: RoleName: !Sub "${AWS::StackName}-crossaccount-read" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: AWS: !Sub "arn:aws:iam::${TargetAccountId}:root" Action: sts:AssumeRole Condition: StringEquals: sts:Externalid: !Ref ExternalId Policies: - PolicyName: ReadOnlyAccess PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - s3:GetObject - s3:GetObjectVersion Resource: !Ref SourceBucketArn - Effect: Allow Action: - dynamodb:Query - dynamodb:Scan - dynamodb:GetItem Resource: !Ref SourceTableArn
Outputs: ApplicationExecutionRoleArn: Description: ARN of the application execution role Value: !GetAtt ApplicationExecutionRole.Arn Export: Name: !Sub "${AWS::StackName}-ExecutionRoleArn"
CrossAccountReadRoleArn: Description: ARN for cross-account read access Value: !GetAtt CrossAccountReadRole.Arn Export: Name: !Sub "${AWS::StackName}-CrossAccountReadRoleArn"
CrossAccountReadRoleExternalId: Description: External ID for cross-account role assumption Value: !Ref ExternalId Export: Name: !Sub "${AWS::StackName}-CrossAccountExternalId"

```yaml

Stack B - Application Stack (imports from IAM Stack)

Stack B - 应用栈(从IAM栈导入资源)

AWSTemplateFormatVersion: 2010-09-09 Description: Application stack importing IAM roles
Parameters: IAMStackName: Type: String Default: iam-core Description: Name of the IAM stack
Resources: LambdaFunction: Type: AWS::Lambda::Function Properties: FunctionName: !Sub "${AWS::StackName}-processor" Runtime: python3.11 Handler: app.handler Code: S3Bucket: !Ref CodeBucket S3Key: lambda/function.zip Role: !ImportValue !Sub "${IAMStackName}-ExecutionRoleArn" Environment: Variables: TARGET_BUCKET: !Ref TargetBucket
undefined
AWSTemplateFormatVersion: 2010-09-09 Description: Application stack importing IAM roles
Parameters: IAMStackName: Type: String Default: iam-core Description: Name of the IAM stack
Resources: LambdaFunction: Type: AWS::Lambda::Function Properties: FunctionName: !Sub "${AWS::StackName}-processor" Runtime: python3.11 Handler: app.handler Code: S3Bucket: !Ref CodeBucket S3Key: lambda/function.zip Role: !ImportValue !Sub "${IAMStackName}-ExecutionRoleArn" Environment: Variables: TARGET_BUCKET: !Ref TargetBucket
undefined

Nested Stacks for IAM Modularity

用于IAM模块化的嵌套栈

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Main stack with nested IAM stacks

Resources:
  # Nested stack for users
  IAMUsersStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/bucket/iam-users.yaml
      TimeoutInMinutes: 15
      Parameters:
        Environment: !Ref Environment
        UserNames: !Ref UserNames

  # Nested stack for roles
  IAMRolesStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/bucket/iam-roles.yaml
      TimeoutInMinutes: 15
      Parameters:
        Environment: !Ref Environment
        TrustedServices: !Ref TrustedServices

  # Nested stack for policies
  IAMPoliciesStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/bucket/iam-policies.yaml
      TimeoutInMinutes: 15
      Parameters:
        Environment: !Ref Environment
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Main stack with nested IAM stacks

Resources:
  # 用户嵌套栈
  IAMUsersStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/bucket/iam-users.yaml
      TimeoutInMinutes: 15
      Parameters:
        Environment: !Ref Environment
        UserNames: !Ref UserNames

  # 角色嵌套栈
  IAMRolesStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/bucket/iam-roles.yaml
      TimeoutInMinutes: 15
      Parameters:
        Environment: !Ref Environment
        TrustedServices: !Ref TrustedServices

  # 策略嵌套栈
  IAMPoliciesStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/bucket/iam-policies.yaml
      TimeoutInMinutes: 15
      Parameters:
        Environment: !Ref Environment

IAM Users

IAM用户

User with Access Keys

带访问密钥的用户

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM user with programmatic access

Resources:
  AppUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Sub "${AWS::StackName}-app-user"
      Tags:
        - Key: Environment
          Value: !Ref Environment
        - Key: Project
          Value: !Ref ProjectName

  UserAccessKey:
    Type: AWS::IAM::AccessKey
    Properties:
      UserName: !Ref AppUser
      Status: Active
      Serial: 1

  UserSecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: !Sub "${AWS::StackName}/iam-user-credentials"
      Description: IAM user access key credentials
      SecretString: !Sub |
        {
          "username": "${AppUser.UserName}",
          "access_key": "${UserAccessKey.Ref}",
          "secret_key": "{{resolve:secretsmanager:${UserAccessKey.SecretAccessKey}}}"
        }

Outputs:
  AccessKeyId:
    Description: Access Key ID for the user
    Value: !Ref UserAccessKey
    Export:
      Name: !Sub "${AWS::StackName}-AccessKeyId"

  SecretArn:
    Description: ARN of the secret containing credentials
    Value: !Ref UserSecret
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM user with programmatic access

Resources:
  AppUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Sub "${AWS::StackName}-app-user"
      Tags:
        - Key: Environment
          Value: !Ref Environment
        - Key: Project
          Value: !Ref ProjectName

  UserAccessKey:
    Type: AWS::IAM::AccessKey
    Properties:
      UserName: !Ref AppUser
      Status: Active
      Serial: 1

  UserSecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: !Sub "${AWS::StackName}/iam-user-credentials"
      Description: IAM user access key credentials
      SecretString: !Sub |
        {
          "username": "${AppUser.UserName}",
          "access_key": "${UserAccessKey.Ref}",
          "secret_key": "{{resolve:secretsmanager:${UserAccessKey.SecretAccessKey}}}"
        }

Outputs:
  AccessKeyId:
    Description: Access Key ID for the user
    Value: !Ref UserAccessKey
    Export:
      Name: !Sub "${AWS::StackName}-AccessKeyId"

  SecretArn:
    Description: ARN of the secret containing credentials
    Value: !Ref UserSecret

User with Console Password

带控制台密码的用户

yaml
Resources:
  ConsoleUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Sub "${AWS::StackName}-console-user"

  UserLoginProfile:
    Type: AWS::IAM::UserLoginProfile
    Properties:
      UserName: !Ref ConsoleUser
      Password: !Ref InitialPassword
      PasswordResetRequired: true

  UserPasswordSecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: !Sub "${AWS::StackName}/console-password"
      Description: Initial console login password
      SecretString: !Ref InitialPassword
yaml
Resources:
  ConsoleUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Sub "${AWS::StackName}-console-user"

  UserLoginProfile:
    Type: AWS::IAM::UserLoginProfile
    Properties:
      UserName: !Ref ConsoleUser
      Password: !Ref InitialPassword
      PasswordResetRequired: true

  UserPasswordSecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: !Sub "${AWS::StackName}/console-password"
      Description: Initial console login password
      SecretString: !Ref InitialPassword

User with Permissions Boundary

带权限边界的用户

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM user with permissions boundary

Resources:
  # Permissions boundary policy
  ReadOnlyBoundaryPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      Description: Read-only permissions boundary
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Deny
            Action: "*"
            Resource: "*"
            NotPrincipal:
              - !GetAtt ReadOnlyRole.Arn

  AppUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Sub "${AWS::StackName}-restricted-user"
      PermissionsBoundary: !Ref ReadOnlyBoundaryPolicy
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM user with permissions boundary

Resources:
  # 权限边界策略
  ReadOnlyBoundaryPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      Description: Read-only permissions boundary
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Deny
            Action: "*"
            Resource: "*"
            NotPrincipal:
              - !GetAtt ReadOnlyRole.Arn

  AppUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Sub "${AWS::StackName}-restricted-user"
      PermissionsBoundary: !Ref ReadOnlyBoundaryPolicy
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess

IAM Roles

IAM角色

Role for Lambda Execution

Lambda执行角色

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Lambda execution role with least privilege

Resources:
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-lambda-execution"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
        - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-dynamodb-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - dynamodb:Query
                  - dynamodb:Scan
                  - dynamodb:GetItem
                  - dynamodb:PutItem
                  - dynamodb:UpdateItem
                  - dynamodb:DeleteItem
                Resource: !GetAtt DataTable.Arn
                Condition:
                  StringEquals:
                    dynamodb:TableName: !Ref TableName
              - Effect: Allow
                Action:
                  - dynamodb:DescribeTable
                Resource: "*"
        - PolicyName: !Sub "${AWS::StackName}-secrets-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - secretsmanager:GetSecretValue
                  - secretsmanager:DescribeSecret
                Resource: !Ref SecretsArn
        - PolicyName: !Sub "${AWS::StackName}-kms-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - kms:Decrypt
                  - kms:DescribeKey
                Resource: !Ref KmsKeyArn

  DataTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: !Ref TableName
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: pk
          AttributeType: S
        - AttributeName: sk
          AttributeType: S
      KeySchema:
        - AttributeName: pk
          KeyType: HASH
        - AttributeName: sk
          KeyType: RANGE
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Lambda execution role with least privilege

Resources:
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-lambda-execution"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
        - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-dynamodb-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - dynamodb:Query
                  - dynamodb:Scan
                  - dynamodb:GetItem
                  - dynamodb:PutItem
                  - dynamodb:UpdateItem
                  - dynamodb:DeleteItem
                Resource: !GetAtt DataTable.Arn
                Condition:
                  StringEquals:
                    dynamodb:TableName: !Ref TableName
              - Effect: Allow
                Action:
                  - dynamodb:DescribeTable
                Resource: "*"
        - PolicyName: !Sub "${AWS::StackName}-secrets-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - secretsmanager:GetSecretValue
                  - secretsmanager:DescribeSecret
                Resource: !Ref SecretsArn
        - PolicyName: !Sub "${AWS::StackName}-kms-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - kms:Decrypt
                  - kms:DescribeKey
                Resource: !Ref KmsKeyArn

  DataTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: !Ref TableName
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: pk
          AttributeType: S
        - AttributeName: sk
          AttributeType: S
      KeySchema:
        - AttributeName: pk
          KeyType: HASH
        - AttributeName: sk
          KeyType: RANGE

Role for ECS Tasks

ECS任务角色

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: ECS task execution role

Resources:
  ECSTaskExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-ecs-task-execution"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-ecr-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - ecr:GetDownloadUrlForLayer
                  - ecr:BatchGetImage
                  - ecr:BatchCheckLayerAvailability
                Resource: !Ref EcrRepositoryArn
              - Effect: Allow
                Action:
                  - ecr:GetAuthorizationToken
                Resource: "*"
        - PolicyName: !Sub "${AWS::StackName}-cloudwatch-logs"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - logs:CreateLogGroup
                Resource: !Ref LogGroupArn

  ECSTaskRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-ecs-task"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-app-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - sqs:ReceiveMessage
                  - sqs:DeleteMessage
                  - sqs:GetQueueAttributes
                Resource: !GetAtt Queue.Arn
              - Effect: Allow
                Action:
                  - sns:Publish
                Resource: !Ref TopicArn
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: ECS task execution role

Resources:
  ECSTaskExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-ecs-task-execution"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-ecr-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - ecr:GetDownloadUrlForLayer
                  - ecr:BatchGetImage
                  - ecr:BatchCheckLayerAvailability
                Resource: !Ref EcrRepositoryArn
              - Effect: Allow
                Action:
                  - ecr:GetAuthorizationToken
                Resource: "*"
        - PolicyName: !Sub "${AWS::StackName}-cloudwatch-logs"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - logs:CreateLogGroup
                Resource: !Ref LogGroupArn

  ECSTaskRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-ecs-task"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-app-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - sqs:ReceiveMessage
                  - sqs:DeleteMessage
                  - sqs:GetQueueAttributes
                Resource: !GetAtt Queue.Arn
              - Effect: Allow
                Action:
                  - sns:Publish
                Resource: !Ref TopicArn

Role for Cross-Account Access

跨账户访问角色

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Cross-account access role

Parameters:
  SourceAccountId:
    Type: String
    Description: AWS account ID that can assume this role

  ExternalId:
    Type: String
    Description: External ID for trust relationship

Resources:
  CrossAccountReadRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-crossaccount-read"
      Description: Role for cross-account read access
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Sub "arn:aws:iam::${SourceAccountId}:root"
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                sts:Externalid: !Ref ExternalId
              IpAddress:
                aws:SourceIp:
                  - 10.0.0.0/8
                  - 172.16.0.0/12
      MaxSessionDuration: 7200
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-s3-read"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                  - s3:ListBucket
                Resource:
                  - !Ref SourceBucketArn
                  - !Sub "${SourceBucketArn}/*"
        - PolicyName: !Sub "${AWS::StackName}-dynamodb-read"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - dynamodb:Query
                  - dynamodb:Scan
                  - dynamodb:GetItem
                  - dynamodb:DescribeTable
                Resource:
                  - !GetAtt SourceTable.Arn
                  - !Sub "${GetAtt SourceTable.Arn}/index/*"

Outputs:
  RoleArn:
    Description: ARN of the cross-account role
    Value: !GetAtt CrossAccountReadRole.Arn
    Export:
      Name: !Sub "${AWS::StackName}-CrossAccountRoleArn"
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Cross-account access role

Parameters:
  SourceAccountId:
    Type: String
    Description: AWS account ID that can assume this role

  ExternalId:
    Type: String
    Description: External ID for trust relationship

Resources:
  CrossAccountReadRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-crossaccount-read"
      Description: Role for cross-account read access
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Sub "arn:aws:iam::${SourceAccountId}:root"
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                sts:Externalid: !Ref ExternalId
              IpAddress:
                aws:SourceIp:
                  - 10.0.0.0/8
                  - 172.16.0.0/12
      MaxSessionDuration: 7200
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-s3-read"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                  - s3:ListBucket
                Resource:
                  - !Ref SourceBucketArn
                  - !Sub "${SourceBucketArn}/*"
        - PolicyName: !Sub "${AWS::StackName}-dynamodb-read"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - dynamodb:Query
                  - dynamodb:Scan
                  - dynamodb:GetItem
                  - dynamodb:DescribeTable
                Resource:
                  - !GetAtt SourceTable.Arn
                  - !Sub "${GetAtt SourceTable.Arn}/index/*"

Outputs:
  RoleArn:
    Description: ARN of the cross-account role
    Value: !GetAtt CrossAccountReadRole.Arn
    Export:
      Name: !Sub "${AWS::StackName}-CrossAccountRoleArn"

Role for API Gateway with Cognito

API Gateway与Cognito角色

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: API Gateway execution role for Cognito authorization

Resources:
  ApiGatewayCognitoAuthorizerRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-apigw-cognito-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: apigateway.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-cognito-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - cognito-idp:DescribeUserPool
                  - cognito-idp:DescribeUserPoolClient
                Resource: !Ref UserPoolArn

  ApiGatewayExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-apigw-execution"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: apigateway.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-lambda-invoke"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - lambda:InvokeFunction
                Resource: !Ref LambdaFunctionArn
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: API Gateway execution role for Cognito authorization

Resources:
  ApiGatewayCognitoAuthorizerRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-apigw-cognito-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: apigateway.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-cognito-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - cognito-idp:DescribeUserPool
                  - cognito-idp:DescribeUserPoolClient
                Resource: !Ref UserPoolArn

  ApiGatewayExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-apigw-execution"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: apigateway.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-lambda-invoke"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - lambda:InvokeFunction
                Resource: !Ref LambdaFunctionArn

Role for EKS Pods

EKS Pod角色

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM role for EKS pod execution

Resources:
  EKSPodRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-eks-pod-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: eks.amazonaws.com
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                aws:SourceArn: !Sub "arn:aws:eks:${AWS::Region}:${AWS::AccountId}:cluster/${EKSClusterName}"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/SecretsManagerReadWrite
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-s3-read"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                Resource: !Sub "${DataBucketArn}/*"

  EKSPodExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-eks-execution"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: eks.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
        - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
        - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
        - arn:aws:iam::aws:policy/CloudWatchLogsReadOnly
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM role for EKS pod execution

Resources:
  EKSPodRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-eks-pod-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: eks.amazonaws.com
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                aws:SourceArn: !Sub "arn:aws:eks:${AWS::Region}:${AWS::AccountId}:cluster/${EKSClusterName}"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/SecretsManagerReadWrite
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-s3-read"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                Resource: !Sub "${DataBucketArn}/*"

  EKSPodExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-eks-execution"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: eks.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
        - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
        - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
        - arn:aws:iam::aws:policy/CloudWatchLogsReadOnly

Role for CodeBuild

CodeBuild角色

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM role for CodeBuild project

Resources:
  CodeBuildRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-codebuild-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: codebuild.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
        - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-source-access"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                Resource:
                  - !Ref SourceBucketArn
                  - !Sub "${SourceBucketArn}/*"
              - Effect: Allow
                Action:
                  - s3:PutObject
                Resource:
                  - !Ref BuildOutputBucketArn
                  - !Sub "${BuildOutputBucketArn}/*"
              - Effect: Allow
                Action:
                  - codecommit:GitPull
                Resource: !Ref CodecommitRepositoryArn
              - Effect: Allow
                Action:
                  - codebuild:CreateReportGroup
                  - codebuild:CreateReport
                  - codebuild:UpdateReport
                  - codebuild:BatchPutTestCases
                  - codebuild:BatchPutCodeCoverages
                Resource: "*"
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM role for CodeBuild project

Resources:
  CodeBuildRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-codebuild-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: codebuild.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
        - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-source-access"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                Resource:
                  - !Ref SourceBucketArn
                  - !Sub "${SourceBucketArn}/*"
              - Effect: Allow
                Action:
                  - s3:PutObject
                Resource:
                  - !Ref BuildOutputBucketArn
                  - !Sub "${BuildOutputBucketArn}/*"
              - Effect: Allow
                Action:
                  - codecommit:GitPull
                Resource: !Ref CodecommitRepositoryArn
              - Effect: Allow
                Action:
                  - codebuild:CreateReportGroup
                  - codebuild:CreateReport
                  - codebuild:UpdateReport
                  - codebuild:BatchPutTestCases
                  - codebuild:BatchPutCodeCoverages
                Resource: "*"

Role for Step Functions

Step Functions角色

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM role for Step Functions state machine

Resources:
  StepFunctionsExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-stepfunctions-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: states.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-lambda-tasks"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - lambda:InvokeFunction
                  - lambda:InvokeAsync
                Resource:
                  - !Ref ProcessFunctionArn
                  - !Ref ValidateFunctionARN
                  - !Ref NotifyFunctionArn
        - PolicyName: !Sub "${AWS::StackName}-dynamodb-tasks"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - dynamodb:GetItem
                  - dynamodb:PutItem
                  - dynamodb:UpdateItem
                  - dynamodb:DeleteItem
                  - dynamodb:Query
                  - dynamodb:Scan
                Resource:
                  - !GetAtt WorkflowTable.Arn
                  - !Sub "${GetAtt WorkflowTable.Arn}/*"
        - PolicyName: !Sub "${AWS::StackName}-sns-tasks"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - sns:Publish
                Resource: !Ref NotificationTopicArn
        - PolicyName: !Sub "${AWS::StackName}-events"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - events:PutTargets
                  - events:PutRule
                  - events:DescribeRule
                Resource: "*"
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM role for Step Functions state machine

Resources:
  StepFunctionsExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-stepfunctions-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: states.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-lambda-tasks"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - lambda:InvokeFunction
                  - lambda:InvokeAsync
                Resource:
                  - !Ref ProcessFunctionArn
                  - !Ref ValidateFunctionARN
                  - !Ref NotifyFunctionArn
        - PolicyName: !Sub "${AWS::StackName}-dynamodb-tasks"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - dynamodb:GetItem
                  - dynamodb:PutItem
                  - dynamodb:UpdateItem
                  - dynamodb:DeleteItem
                  - dynamodb:Query
                  - dynamodb:Scan
                Resource:
                  - !GetAtt WorkflowTable.Arn
                  - !Sub "${GetAtt WorkflowTable.Arn}/*"
        - PolicyName: !Sub "${AWS::StackName}-sns-tasks"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - sns:Publish
                Resource: !Ref NotificationTopicArn
        - PolicyName: !Sub "${AWS::StackName}-events"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - events:PutTargets
                  - events:PutRule
                  - events:DescribeRule
                Resource: "*"

IAM Policies

IAM策略

Inline Policy for S3 Access

S3访问内联策略

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Role with S3 access policies

Resources:
  S3AccessRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-s3-access"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-s3-readonly"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                  - s3:GetBucketPolicy
                  - s3:GetBucketPolicyStatus
                Resource:
                  - !Ref DataBucketArn
                  - !Sub "${DataBucketArn}/*"
              - Effect: Allow
                Action:
                  - s3:ListBucket
                Resource: !Ref DataBucketArn
                Condition:
                  StringLike:
                    s3:prefix:
                      - ""
                      - "documents/*"
                      - "reports/*"

        - PolicyName: !Sub "${AWS::StackName}-s3-write"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:PutObject
                  - s3:PutObjectAcl
                  - s3:DeleteObject
                Resource: !Sub "${DataBucketArn}/processed/*"
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Role with S3 access policies

Resources:
  S3AccessRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-s3-access"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-s3-readonly"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                  - s3:GetBucketPolicy
                  - s3:GetBucketPolicyStatus
                Resource:
                  - !Ref DataBucketArn
                  - !Sub "${DataBucketArn}/*"
              - Effect: Allow
                Action:
                  - s3:ListBucket
                Resource: !Ref DataBucketArn
                Condition:
                  StringLike:
                    s3:prefix:
                      - ""
                      - "documents/*"
                      - "reports/*"

        - PolicyName: !Sub "${AWS::StackName}-s3-write"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:PutObject
                  - s3:PutObjectAcl
                  - s3:DeleteObject
                Resource: !Sub "${DataBucketArn}/processed/*"

Custom Managed Policy

自定义托管策略

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Custom managed policy for DynamoDB access

Resources:
  DynamoDBFullAccessPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      Description: Full access to specific DynamoDB tables
      ManagedPolicyName: !Sub "${AWS::StackName}-dynamodb-full-access"
      Groups:
        - !Ref AppUserGroup
      Roles:
        - !Ref AppExecutionRole
      Users:
        - !Ref AppUser
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - dynamodb:CreateTable
              - dynamodb:UpdateTable
              - dynamodb:DeleteTable
              - dynamodb:DescribeTable
              - dynamodb:DescribeTimeToLive
              - dynamodb:ListTagsOfResource
            Resource: !GetAtt DataTable.Arn
          - Effect: Allow
            Action:
              - dynamodb:Query
              - dynamodb:Scan
              - dynamodb:GetItem
              - dynamodb:PutItem
              - dynamodb:UpdateItem
              - dynamodb:DeleteItem
              - dynamodb:BatchGetItem
              - dynamodb:BatchWriteItem
            Resource:
              - !GetAtt DataTable.Arn
              - !Sub "${GetAtt DataTable.Arn}/index/*"
          - Effect: Allow
            Action:
              - dynamodb:DescribeLimits
              - dynamodb:ListTables
            Resource: "*"
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Custom managed policy for DynamoDB access

Resources:
  DynamoDBFullAccessPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      Description: Full access to specific DynamoDB tables
      ManagedPolicyName: !Sub "${AWS::StackName}-dynamodb-full-access"
      Groups:
        - !Ref AppUserGroup
      Roles:
        - !Ref AppExecutionRole
      Users:
        - !Ref AppUser
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - dynamodb:CreateTable
              - dynamodb:UpdateTable
              - dynamodb:DeleteTable
              - dynamodb:DescribeTable
              - dynamodb:DescribeTimeToLive
              - dynamodb:ListTagsOfResource
            Resource: !GetAtt DataTable.Arn
          - Effect: Allow
            Action:
              - dynamodb:Query
              - dynamodb:Scan
              - dynamodb:GetItem
              - dynamodb:PutItem
              - dynamodb:UpdateItem
              - dynamodb:DeleteItem
              - dynamodb:BatchGetItem
              - dynamodb:BatchWriteItem
            Resource:
              - !GetAtt DataTable.Arn
              - !Sub "${GetAtt DataTable.Arn}/index/*"
          - Effect: Allow
            Action:
              - dynamodb:DescribeLimits
              - dynamodb:ListTables
            Resource: "*"

Policy with Conditions

带条件的策略

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Policy with IP and time-based conditions

Resources:
  RestrictedAccessRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-restricted-access"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-conditional-access"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                Resource: !Sub "${DataBucketArn}/*"
                Condition:
                  IpAddress:
                    aws:SourceIp:
                      - 10.0.0.0/8
                      - 192.168.1.0/24
                  StringEquals:
                    s3:ExistingObjectTag/classification: internal
              - Effect: Allow
                Action:
                  - dynamodb:GetItem
                  - dynamodb:Query
                Resource: !GetAtt DataTable.Arn
                Condition:
                  StringEquals:
                    dynamodb:Select: SPECIFIC_ATTRIBUTES
                    dynamodb:Attributes:
                      - id
                      - name
                      - status
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Policy with IP and time-based conditions

Resources:
  RestrictedAccessRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-restricted-access"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-conditional-access"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                Resource: !Sub "${DataBucketArn}/*"
                Condition:
                  IpAddress:
                    aws:SourceIp:
                      - 10.0.0.0/8
                      - 192.168.1.0/24
                  StringEquals:
                    s3:ExistingObjectTag/classification: internal
              - Effect: Allow
                Action:
                  - dynamodb:GetItem
                  - dynamodb:Query
                Resource: !GetAtt DataTable.Arn
                Condition:
                  StringEquals:
                    dynamodb:Select: SPECIFIC_ATTRIBUTES
                    dynamodb:Attributes:
                      - id
                      - name
                      - status

Permission Boundaries

权限边界

Permission Boundary for Developers

开发者权限边界

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Permission boundary for developer roles

Resources:
  DeveloperBoundaryPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      Description: Permission boundary for developers - denies production write access
      ManagedPolicyName: !Sub "${AWS::StackName}-developer-boundary"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Deny
            Action:
              - "*"
            Resource: "*"
            Condition:
              StringEquals:
                aws:RequestedRegion:
                  - us-east-1
                  - us-west-2
              StringLike:
                aws:ResourceTag/environment:
                  - production
                  - prod
          - Effect: Deny
            Action:
              - iam:CreateUser
              - iam:DeleteUser
              - iam:PutUserPolicy
              - iam:AttachUserPolicy
              - iam:DetachUserPolicy
            Resource: "*"
          - Effect: Deny
            Action:
              - iam:CreateRole
              - iam:DeleteRole
              - iam:AttachRolePolicy
              - iam:DetachRolePolicy
            Resource: "*"
          - Effect: Allow
            Action:
              - s3:Get*
              - s3:List*
            Resource: "*"
          - Effect: Allow
            Action:
              - dynamodb:Get*
              - dynamodb:Query
              - dynamodb:Scan
            Resource: "*"
          - Effect: Allow
            Action:
              - lambda:InvokeFunction
              - lambda:GetFunction
            Resource: "*"

  DeveloperRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-developer"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Ref DeveloperUserArn
            Action: sts:AssumeRole
      PermissionsBoundary: !Ref DeveloperBoundaryPolicy
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Permission boundary for developer roles

Resources:
  DeveloperBoundaryPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      Description: Permission boundary for developers - denies production write access
      ManagedPolicyName: !Sub "${AWS::StackName}-developer-boundary"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Deny
            Action:
              - "*"
            Resource: "*"
            Condition:
              StringEquals:
                aws:RequestedRegion:
                  - us-east-1
                  - us-west-2
              StringLike:
                aws:ResourceTag/environment:
                  - production
                  - prod
          - Effect: Deny
            Action:
              - iam:CreateUser
              - iam:DeleteUser
              - iam:PutUserPolicy
              - iam:AttachUserPolicy
              - iam:DetachUserPolicy
            Resource: "*"
          - Effect: Deny
            Action:
              - iam:CreateRole
              - iam:DeleteRole
              - iam:AttachRolePolicy
              - iam:DetachRolePolicy
            Resource: "*"
          - Effect: Allow
            Action:
              - s3:Get*
              - s3:List*
            Resource: "*"
          - Effect: Allow
            Action:
              - dynamodb:Get*
              - dynamodb:Query
              - dynamodb:Scan
            Resource: "*"
          - Effect: Allow
            Action:
              - lambda:InvokeFunction
              - lambda:GetFunction
            Resource: "*"

  DeveloperRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-developer"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Ref DeveloperUserArn
            Action: sts:AssumeRole
      PermissionsBoundary: !Ref DeveloperBoundaryPolicy
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess

IAM Identity Center (SSO)

IAM Identity Center(SSO)

SSO Permission Set

SSO权限集

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM Identity Center permission set

Resources:
  SSOPermissionSet:
    Type: AWS::SSO::PermissionSet
    Properties:
      InstanceArn: !Ref SSOInstanceArn
      PermissionSetName: !Sub "${AWS::StackName}-admin-permissions"
      Description: Administrator access permission set
      SessionDuration: PT8H
      RelayStateType: sso.amazonaws.com
      ManagedPolicies:
        - arn:aws:iam::aws:policy/AdministratorAccess
      InlinePolicy: |
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "aws-portal:*Billing",
                "aws-portal:*Usage"
              ],
              "Resource": "*"
            }
          ]
        }

  SSOAssignment:
    Type: AWS::SSO::AccountAssignment
    Properties:
      InstanceArn: !Ref SSOInstanceArn
      PermissionSetArn: !Ref SSOPermissionSet
      PrincipalId: !Ref SSOGroupId
      PrincipalType: GROUP
      TargetId: !Ref TargetAWSAccountId
      TargetType: AWS_ACCOUNT
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM Identity Center permission set

Resources:
  SSOPermissionSet:
    Type: AWS::SSO::PermissionSet
    Properties:
      InstanceArn: !Ref SSOInstanceArn
      PermissionSetName: !Sub "${AWS::StackName}-admin-permissions"
      Description: Administrator access permission set
      SessionDuration: PT8H
      RelayStateType: sso.amazonaws.com
      ManagedPolicies:
        - arn:aws:iam::aws:policy/AdministratorAccess
      InlinePolicy: |
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "aws-portal:*Billing",
                "aws-portal:*Usage"
              ],
              "Resource": "*"
            }
          ]
        }

  SSOAssignment:
    Type: AWS::SSO::AccountAssignment
    Properties:
      InstanceArn: !Ref SSOInstanceArn
      PermissionSetArn: !Ref SSOPermissionSet
      PrincipalId: !Ref SSOGroupId
      PrincipalType: GROUP
      TargetId: !Ref TargetAWSAccountId
      TargetType: AWS_ACCOUNT

SSO Custom Policy with Conditions

带自定义策略的SSO权限集

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: SSO permission set with custom policies

Resources:
  ReadOnlyPermissionSet:
    Type: AWS::SSO::PermissionSet
    Properties:
      InstanceArn: !Ref SSOInstanceArn
      PermissionSetName: !Sub "${AWS::StackName}-read-only"
      Description: Read-only access for auditors
      SessionDuration: PT4H
      ManagedPolicies:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
      InlinePolicy: |
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:ListBucket"
              ],
              "Resource": [
                "arn:aws:s3:::${DataBucketArn}",
                "arn:aws:s3:::${DataBucketArn}/*"
              ]
            },
            {
              "Effect": "Deny",
              "Action": [
                "s3:DeleteObject",
                "s3:PutObject"
              ],
              "Resource": [
                "arn:aws:s3:::${DataBucketArn}/*"
              ]
            }
          ]
        }
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: SSO permission set with custom policies

Resources:
  ReadOnlyPermissionSet:
    Type: AWS::SSO::PermissionSet
    Properties:
      InstanceArn: !Ref SSOInstanceArn
      PermissionSetName: !Sub "${AWS::StackName}-read-only"
      Description: Read-only access for auditors
      SessionDuration: PT4H
      ManagedPolicies:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
      InlinePolicy: |
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:ListBucket"
              ],
              "Resource": [
                "arn:aws:s3:::${DataBucketArn}",
                "arn:aws:s3:::${DataBucketArn}/*"
              ]
            },
            {
              "Effect": "Deny",
              "Action": [
                "s3:DeleteObject",
                "s3:PutObject"
              ],
              "Resource": [
                "arn:aws:s3:::${DataBucketArn}/*"
              ]
            }
          ]
        }

Service Control Policies (SCP)

服务控制策略(SCP)

SCP for Organizational Units

生产OU的服务控制策略

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Service control policy for production OU

Resources:
  ProductionSCP:
    Type: AWS::Organizations::Policy
    Properties:
      Name: !Sub "${AWS::StackName}-production-restrictions"
      Description: SCP to restrict actions in production accounts
      Type: SERVICE_CONTROL_POLICY
      Content:
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "DenyDeleteResources",
              "Effect": "Deny",
              "Action": [
                "s3:DeleteBucket",
                "dynamodb:DeleteTable",
                "rds:DeleteDBInstance",
                "lambda:DeleteFunction"
              ],
              "Resource": "*",
              "Condition": {
                "StringEquals": {
                  "aws:ResourceTag/environment": "production"
                }
              }
            },
            {
              "Sid": "RequireEncryption",
              "Effect": "Deny",
              "Action": [
                "s3:PutObject",
                "dynamodb:PutItem"
              ],
              "Resource": "*",
              "Condition": {
                "StringNotEquals": {
                  "s3:x-amz-server-side-encryption": "AES256"
                }
              }
            },
            {
              "Sid": "DenyRootAccess",
              "Effect": "Deny",
              "Action": [
                "iam:CreateAccessKey",
                "iam:CreateLoginProfile",
                "iam:EnableMFADevice"
              ],
              "Resource": "*",
              "Condition": {
                "StringEquals": {
                  "aws:PrincipalTag/role": "breakglass"
                }
              }
            },
            {
              "Sid": "AllowKnownServices",
              "Effect": "Allow",
              "Action": "*",
              "Resource": "*",
              "NotPrincipal": {
                "AWS": [
                  "arn:aws:iam::aws:policy/AdministratorAccess"
                ]
              }
            }
          ]
        }
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Service control policy for production OU

Resources:
  ProductionSCP:
    Type: AWS::Organizations::Policy
    Properties:
      Name: !Sub "${AWS::StackName}-production-restrictions"
      Description: SCP to restrict actions in production accounts
      Type: SERVICE_CONTROL_POLICY
      Content:
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "DenyDeleteResources",
              "Effect": "Deny",
              "Action": [
                "s3:DeleteBucket",
                "dynamodb:DeleteTable",
                "rds:DeleteDBInstance",
                "lambda:DeleteFunction"
              ],
              "Resource": "*",
              "Condition": {
                "StringEquals": {
                  "aws:ResourceTag/environment": "production"
                }
              }
            },
            {
              "Sid": "RequireEncryption",
              "Effect": "Deny",
              "Action": [
                "s3:PutObject",
                "dynamodb:PutItem"
              ],
              "Resource": "*",
              "Condition": {
                "StringNotEquals": {
                  "s3:x-amz-server-side-encryption": "AES256"
                }
              }
            },
            {
              "Sid": "DenyRootAccess",
              "Effect": "Deny",
              "Action": [
                "iam:CreateAccessKey",
                "iam:CreateLoginProfile",
                "iam:EnableMFADevice"
              ],
              "Resource": "*",
              "Condition": {
                "StringEquals": {
                  "aws:PrincipalTag/role": "breakglass"
                }
              }
            },
            {
              "Sid": "AllowKnownServices",
              "Effect": "Allow",
              "Action": "*",
              "Resource": "*",
              "NotPrincipal": {
                "AWS": [
                  "arn:aws:iam::aws:policy/AdministratorAccess"
                ]
              }
            }
          ]
        }

Conditions and Transform

条件与转换

Conditions for Environment-Specific Roles

环境特定角色的条件

yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM resources with conditional configurations

Parameters:
  Environment:
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - staging
      - production

Conditions:
  IsProduction: !Equals [!Ref Environment, production]
  IsDevelopment: !Equals [!Ref Environment, dev]
  CreateAdminRole: !Or [!Equals [!Ref Environment, staging], !Equals [!Ref Environment, production]]

Resources:
  # Base role for all environments
  BaseExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-base-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      MaxSessionDuration: !FindInMap [EnvironmentConfig, !Ref Environment, MaxSessionDuration]
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-base-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "*"

  # Admin role only for staging and production
  AdminRole:
    Type: AWS::IAM::Role
    Condition: CreateAdminRole
    Properties:
      RoleName: !Sub "${AWS::StackName}-admin-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Ref AdminUserArn
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
        - !If
          - IsProduction
          - arn:aws:iam::aws:policy/ViewBilling
          - !Ref AWS::NoValue

Mappings:
  EnvironmentConfig:
    dev:
      MaxSessionDuration: 3600
    staging:
      MaxSessionDuration: 7200
    production:
      MaxSessionDuration: 43200
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM resources with conditional configurations

Parameters:
  Environment:
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - staging
      - production

Conditions:
  IsProduction: !Equals [!Ref Environment, production]
  IsDevelopment: !Equals [!Ref Environment, dev]
  CreateAdminRole: !Or [!Equals [!Ref Environment, staging], !Equals [!Ref Environment, production]]

Resources:
  # 所有环境的基础角色
  BaseExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-base-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      MaxSessionDuration: !FindInMap [EnvironmentConfig, !Ref Environment, MaxSessionDuration]
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-base-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "*"

  # 仅预发布和生产环境的管理员角色
  AdminRole:
    Type: AWS::IAM::Role
    Condition: CreateAdminRole
    Properties:
      RoleName: !Sub "${AWS::StackName}-admin-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Ref AdminUserArn
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
        - !If
          - IsProduction
          - arn:aws:iam::aws:policy/ViewBilling
          - !Ref AWS::NoValue

Mappings:
  EnvironmentConfig:
    dev:
      MaxSessionDuration: 3600
    staging:
      MaxSessionDuration: 7200
    production:
      MaxSessionDuration: 43200

Transform for Policy Reuse

策略复用的转换

yaml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: Using SAM Transform for IAM patterns

Globals:
  Function:
    Timeout: 30
    Runtime: python3.11
    Policies:
      - S3ReadPolicy:
          BucketName: !Ref DataBucket
      - DynamoDBCrudPolicy:
          TableName: !Ref DataTable
      - SecretsManagerReadWrite:
          SecretArn: !Ref AppSecret

Resources:
  ProcessorFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-processor"
      Handler: app.handler
      CodeUri: lambda_function/
      Environment:
        Variables:
          LOG_LEVEL: INFO
yaml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: Using SAM Transform for IAM patterns

Globals:
  Function:
    Timeout: 30
    Runtime: python3.11
    Policies:
      - S3ReadPolicy:
          BucketName: !Ref DataBucket
      - DynamoDBCrudPolicy:
          TableName: !Ref DataTable
      - SecretsManagerReadWrite:
          SecretArn: !Ref AppSecret

Resources:
  ProcessorFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-processor"
      Handler: app.handler
      CodeUri: lambda_function/
      Environment:
        Variables:
          LOG_LEVEL: INFO

Best Practices

最佳实践

Security

安全

  • Always apply least privilege: start with minimal permissions and add only what's needed
  • Use IAM Access Analyzer to identify excessive permissions
  • Implement permission boundaries to limit maximum permissions
  • Use condition keys for granular restrictions (aws:SourceIp, aws:ResourceTag, aws:RequestedRegion)
  • Enable MFA for all IAM users
  • Rotate access keys regularly (max 90 days)
  • Use roles instead of long-term credentials where possible
  • Implement external ID for cross-account trust
  • Use service-linked roles for AWS services
  • 始终应用最小权限原则:从最小权限开始,仅添加必要的权限
  • 使用IAM Access Analyzer识别过度权限
  • 实现权限边界以限制最大权限范围
  • 使用条件键进行细粒度限制(aws:SourceIp、aws:ResourceTag、aws:RequestedRegion)
  • 为所有IAM用户启用MFA
  • 定期轮换访问密钥(最长90天)
  • 尽可能使用角色而非长期凭证
  • 为跨账户信任实现外部ID
  • 为AWS服务使用服务关联角色

Template Organization

模板组织

  • Separate IAM into dedicated stacks for clear ownership
  • Use nested stacks for modularity
  • Export only necessary values for cross-stack references
  • Always document intent with Description fields
  • Use Parameters for environment-specific configuration
  • Implement conditions to manage variants without duplication
  • Tag all IAM resources for tracking and cost allocation
  • 将IAM拆分为专用栈以明确所有权
  • 使用嵌套栈实现模块化
  • 仅导出跨栈引用所需的值
  • 始终使用Description字段记录意图
  • 使用Parameters配置环境特定参数
  • 实现条件以管理不同变体而无需重复代码
  • 为所有IAM资源添加标签以进行跟踪和成本分配

Monitoring

监控

  • Enable CloudTrail for audit of all IAM actions
  • Configure S3 Object Lock for critical policy files
  • Use IAM Access Analyzer for periodic reports
  • Implement SCP for organizational guardrails
  • Create alarms for unauthorized access
  • 启用CloudTrail以审计所有IAM操作
  • 为关键策略文件配置S3 Object Lock
  • 定期使用IAM Access Analyzer生成报告
  • 为组织防护策略实现SCP
  • 为未授权访问创建告警

Compliance

合规

  • Implement separation of duties policies
  • Use AWS managed policies for standard compliance
  • Document all deviations from standards
  • Maintain audit trail for at least 90 days
  • Apply encryption at rest and in transit
  • 实现职责分离策略
  • 使用AWS托管策略以符合标准合规要求
  • 记录所有与标准的偏差
  • 保留至少90天的审计跟踪
  • 应用静态和传输中的加密

CloudFormation Stack Management Best Practices

CloudFormation栈管理最佳实践

Stack Policies

栈策略

Stack Policies prevent unintended updates to critical resources during stack updates.
yaml
Resources:
  # Stack Policy to protect IAM roles from updates
  IAMStackPolicy:
    Type: AWS::CloudFormation::StackPolicy
    Properties:
      PolicyDocument:
        Statement:
          - Effect: Deny
            Action: Update:Replace
            UpdateReplacePolicy: Retain
            Resource: "*"
            Condition:
              StringEquals:
                aws:ResourceTag/Protected: "true"
          - Effect: Allow
            Action: Update:*
            Resource: "*"
栈策略可防止在栈更新期间意外更新关键资源。
yaml
Resources:
  # 保护IAM角色不被更新的栈策略
  IAMStackPolicy:
    Type: AWS::CloudFormation::StackPolicy
    Properties:
      PolicyDocument:
        Statement:
          - Effect: Deny
            Action: Update:Replace
            UpdateReplacePolicy: Retain
            Resource: "*"
            Condition:
              StringEquals:
                aws:ResourceTag/Protected: "true"
          - Effect: Allow
            Action: Update:*
            Resource: "*"

Termination Protection

终止保护

Enable termination protection to prevent accidental stack deletion.
yaml
Resources:
  ProductionStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/bucket/iam-template.yaml
      TerminationProtection: true
CLI commands for termination protection:
bash
undefined
启用终止保护以防止意外删除栈。
yaml
Resources:
  ProductionStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/bucket/iam-template.yaml
      TerminationProtection: true
启用/禁用终止保护的CLI命令:
bash
undefined

Enable termination protection

启用终止保护

aws cloudformation update-termination-protection
--stack-name my-iam-stack
--enable-termination-protection
aws cloudformation update-termination-protection
--stack-name my-iam-stack
--enable-termination-protection

Disable termination protection

禁用终止保护

aws cloudformation update-termination-protection
--stack-name my-iam-stack
--no-enable-termination-protection
undefined
aws cloudformation update-termination-protection
--stack-name my-iam-stack
--no-enable-termination-protection
undefined

Drift Detection

漂移检测

Detect when infrastructure has diverged from the template definition.
bash
undefined
检测基础设施与模板定义的偏差。
bash
undefined

Detect drift on a stack

检测栈漂移

aws cloudformation detect-drift
--stack-name my-iam-stack
aws cloudformation detect-drift
--stack-name my-iam-stack

Get drift detection status

获取漂移检测状态

aws cloudformation describe-stack-drift-detection-status
--stack-drift-detection-id <detection-id>
aws cloudformation describe-stack-drift-detection-status
--stack-drift-detection-id <detection-id>

Get drift detection results

获取漂移检测结果

aws cloudformation describe-stack-resource-drifts
--stack-name my-iam-stack
undefined
aws cloudformation describe-stack-resource-drifts
--stack-name my-iam-stack
undefined

Change Sets

变更集

Preview and review changes before executing them.
bash
undefined
在执行前预览和审查变更。
bash
undefined

Create a change set

创建变更集

aws cloudformation create-change-set
--stack-name my-iam-stack
--change-set-name my-changeset
--template-body file://template.yaml
--capabilities CAPABILITY_IAM
aws cloudformation create-change-set
--stack-name my-iam-stack
--change-set-name my-changeset
--template-body file://template.yaml
--capabilities CAPABILITY_IAM

List change sets

列出变更集

aws cloudformation list-change-sets
--stack-name my-iam-stack
aws cloudformation list-change-sets
--stack-name my-iam-stack

Describe change set

描述变更集

aws cloudformation describe-change-set
--stack-name my-iam-stack
--change-set-name my-changeset
aws cloudformation describe-change-set
--stack-name my-iam-stack
--change-set-name my-changeset

Execute change set

执行变更集

aws cloudformation execute-change-set
--stack-name my-iam-stack
--change-set-name my-changeset
aws cloudformation execute-change-set
--stack-name my-iam-stack
--change-set-name my-changeset

Delete change set (if not executing)

删除变更集(如果不执行)

aws cloudformation delete-change-set
--stack-name my-iam-stack
--change-set-name my-changeset
undefined
aws cloudformation delete-change-set
--stack-name my-iam-stack
--change-set-name my-changeset
undefined

Related Resources

相关资源

Additional Files

附加文件

For complete details on IAM resources and their properties, see:
  • REFERENCE.md - Detailed reference guide for all CloudFormation IAM resources
  • EXAMPLES.md - Complete production-ready examples
有关IAM资源及其属性的完整详细信息,请参阅:
  • REFERENCE.md - 所有CloudFormation IAM资源的详细参考指南
  • EXAMPLES.md - 完整的生产就绪示例