はじめに
CDKを用いたAWSリソースの構築でも始めようかなと思ったときに、「いい感じで最低限のアクセス制限だけしたい」ということで試行錯誤した結果をまとめたものです。
どうやら、CDK環境のBootstrap時にアクセス許可境界の設定をすれば良いと分かったので、CDKが何かとかBootstrapとは、というのは置いといて、自分が行った設定の仕方を備忘録として書きます。
ベストプラクティスというわけではないので、あしからず。
動作環境
- AWS CDK: v2.1004.0
- Node.js: v23.10.0
IAMのアクセス許可境界
AWSアカウント内で「管理者権限」と「開発者権限」を分け、普段使用する開発者用のエンティティ(IAMユーザー/IAMロール)では権限を制限させたくなります。AWS IAMには、それを叶える機能として、アクセス許可境界(Permissions Boundary)があります。(知らなかった。)
簡単に説明すると、IAMユーザーやIAMロールへアタッチする制限事項であり、それによって権限の昇格を阻止します。許可ポリシーの方でアクセス許可されたアクションでも、許可境界のポリシーで拒否されていたら、そのアクションは実行できません。
アクセス許可境界を設定するには、そのためのポリシーを作成するのがいいらしいです。こちらのAWSブログの記事の紹介を参考にポリシーを作ります。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ExplicitAllowAll",
"Effect": "Allow",
"Action": "*",
"Resource": "*"
},
{
"Sid": "DenyAccessIfRequiredPermBoundaryIsNotBeingApplied",
"Effect": "Deny",
"Action": [
"iam:PutRolePermissionsBoundary",
"iam:PutUserPermissionsBoundary",
"iam:CreateRole",
"iam:CreateUser"
],
"Resource": "*",
"Condition": {
"ArnNotEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::{AccountId}:policy/permissions-boundary-policy"
}
}
},
{
"Sid": "DenyUpdateIfRequiredPermBoundaryIsNotBeingApplied",
"Effect": "Deny",
"Action": [
"iam:DetachRolePolicy",
"iam:DeleteRolePolicy",
"iam:PutUserPolicy",
"iam:DeleteUserPolicy",
"iam:AttachUserPolicy",
"iam:AttachRolePolicy",
"iam:PutRolePolicy",
"iam:DetachUserPolicy"
],
"Resource": [
"arn:aws:iam::{AccountId}:role/*",
"arn:aws:iam::{AccountId}:user/*"
],
"Condition": {
"ArnNotEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::{AccountId}:policy/permissions-boundary-policy"
}
}
},
{
"Sid": "DenyPermBoundaryIAMPolicyAlteration",
"Effect": "Deny",
"Action": [
"iam:DeletePolicy",
"iam:CreatePolicyVersion",
"iam:DeletePolicyVersion",
"iam:SetDefaultPolicyVersion"
],
"Resource": "arn:aws:iam::{AccountId}:policy/permissions-boundary-policy"
},
{
"Sid": "DenyRemovalOfPermBoundaryFromAnyUserOrRole",
"Effect": "Deny",
"Action": [
"iam:DeleteUserPermissionsBoundary",
"iam:DeleteRolePermissionsBoundary"
],
"Resource": "*"
},
{
"Sid": "CustomizedDenyActions1",
"Effect": "Deny",
"Action": [
"iam:AttachGroupPolicy",
"iam:AttachUserPolicy",
"iam:AttachRolePolicy",
"iam:DetachGroupPolicy",
"iam:DetachUserPolicy",
"iam:DetachRolePolicy"
],
"Resource": [
"arn:aws:iam::{AccountId}:role/*",
"arn:aws:iam::{AccountId}:user/*",
"arn:aws:iam::{AccountId}:group/*"
],
"Condition": {
"ArnEquals": {
"iam:PolicyARN": "arn:aws:iam::aws:policy/AdministratorAccess"
}
}
}
]
}
上記のポリシーの"CustomizedDenyActions1"
のように、開発者に実行させたくないアクションがあればここに追加していく、という運用方法です。これが許可境界として設定されたエンティティは、このポリシーを編集できません。
permissions-boundary-policyの補足
"DenyUpdateIfRequiredPermBoundaryIsNotBeingApplied"
は、参考にしたブログ内には無いステートメントです。
これは、以下のような抜け道が考えられると思ったので、ポリシーに追加しました。
- 許可境界が設定されていない既存のロールに、最高権限のポリシーをアタッチする
- そのロールを何かのエンティティに付与する
上記のステートメントは、この内の 1. の操作を防ぎます。
アクセス許可境界をCDKデプロイに適用
次は、先程作成した許可境界を、CDKのデプロイの際に適用されるようにしたいと思います。
以降はcdkコマンドを実行する開発者用エンティティに、permissions-boundary-policy
の許可境界が設定されている前提です。
Bootstrap時に指定
CDKについて調べると、AWSリソースを作成するデプロイに使用されるロールは、CDKのBootstrapの実行時に生成されるようです。したがって、公式のドキュメントにもある通り、Bootstrap時に適用したいアクセス許可境界を指定します。
しかし、開発者がこのまま以下コマンドでBootstrapすると、エラーで失敗します。
cdk bootstrap --custom-permissions-boundary permissions-boundary-policy
なぜなら、Bootstrapで生成されるロールに、今回のアクセス許可境界が設定されないロールがあり、iam:CreateRole
を実行できないからです。
色々回避策は考えられますが、自分は「自動生成されるロールすべてにアクセス許可境界を設定する」方法で行きたいと思います。
自動生成されるロールすべてにアクセス許可境界を設定
この設定をするためには、Bootstrapに用いられるテンプレートをカスタマイズする必要があるみたいです。1
まず、デフォルトで用いられるテンプレートをyamlファイルに出力します。
cdk bootstrap --show-template > bootstrap-template.yaml
このyamlファイルの中身はcfnテンプレート
そして、そのyamlファイルを編集して、生成されるロールに自前のポリシーをアクセス許可境界として設定します。以下はその手順についてです。
-
Bootstrap時には以下のロールを作成します2。つまり、yamlファイルの
Resources
に記載されていますCloudFormationExecutionRole
DeploymentActionRole
FilePublishingRole
ImagePublishingRole
LookupRole
-
そのうちの
CloudFormationExecutionRole
だけは、--custom-permissions-boundary
オプションで指定されたポリシーを許可境界に設定するように実装されていますPermissionsBoundary: Fn::If: - PermissionsBoundarySet - Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/${InputPermissionsBoundary} - Ref: CdkBoostrapPermissionsBoundaryPolicy
-
ということなので、他の4つのロールに↑の実装をコピーします
以上で、テンプレートのカスタマイズは完了です。
編集後のyamlファイルの全コードは、本記事のおわりに貼付しています。
CDK Bootstrapを再度実行
必要な設定が終わったので、以下コマンドで再度Bootstrapを実行します。
※ --qualifier
オプションについては → 参考記事
cdk bootstrap \
--template bootstrap-template.yaml \
--custom-permissions-boundary permissions-boundary-policy \
--qualifier hoge
✅ Environment aws://{AccountId}/{Region} bootstrapped.
Bootstrapが成功しました。これで、CDKで利用されるロールにアクセス許可境界が設定されています。
CDK デプロイのための設定
Bootstrapで、アクセス許可境界やQualifierをカスタマイズした場合は、cdk.json
に以下を追記します。
{
...
"context": {
...
+ "@aws-cdk/core:permissionsBoundary": {
+ "name": "permissions-boundary-policy"
+ },
+ "@aws-cdk/core:bootstrapQualifier": "hoge"
}
}
これにより、CDKで構築したIAMエンティティには自動で、permissions-boundary-policy
が許可境界として適用されるようになります。
Bootstrapのやり直し方
Bootstrapをやり直したい場合、以下の手順で作成されたリソースを完全に削除します。
- CloudFormationのスタック削除
デフォルトならスタック名は、CDKToolkit
- S3のバケット削除
デフォルトならバケット名は、cdk-{Qualifier}-assets-{AccountId}-{Region}
CloudFormationのスタックを消しても、S3のバケットだけは残り続ける点に注意。
実験してみた
今回のpermissions-boundary-policy
では、マネージドポリシーのAdministratorAccess
のアタッチを禁止にしているので、これをCDKのデプロイで試してみます。
const role = new iam.Role(scope, 'SampleAdministratorRole', {
roleName: 'SampleAdministratorRole',
managedPolicies: [
iam.ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess')
]
});
cdk deploy SampleRoleStack
すると、期待通り権限エラーが発生しデプロイは失敗しました。
User: arn:aws:sts:: (略) /AWSCloudFormation is not authorized to perform: iam:AttachRolePolicy on resource: role SampleAdministratorRole with an explicit deny in a permissions boundary
おわり
以上で、CDKによるデプロイに対するアクセス制限を設定できました。
必要十分であるという確証はないですが、最低限の制限はできたかと思っています。アクセス許可境界を理解するために2日間頭を悩ませた甲斐がありました。
コード
編集後のbootstrap-template.yamlの全コード
Description: This stack includes resources needed to deploy AWS CDK apps into this environment
Parameters:
TrustedAccounts:
Description: List of AWS accounts that are trusted to publish assets and deploy stacks to this environment
Default: ""
Type: CommaDelimitedList
TrustedAccountsForLookup:
Description: List of AWS accounts that are trusted to look up values in this environment
Default: ""
Type: CommaDelimitedList
CloudFormationExecutionPolicies:
Description: List of the ManagedPolicy ARN(s) to attach to the CloudFormation deployment role
Default: ""
Type: CommaDelimitedList
FileAssetsBucketName:
Description: The name of the S3 bucket used for file assets
Default: ""
Type: String
FileAssetsBucketKmsKeyId:
Description: Empty to create a new key (default), 'AWS_MANAGED_KEY' to use a managed S3 key, or the ID/ARN of an existing key.
Default: ""
Type: String
ContainerAssetsRepositoryName:
Description: A user-provided custom name to use for the container assets ECR repository
Default: ""
Type: String
Qualifier:
Description: An identifier to distinguish multiple bootstrap stacks in the same environment
Default: hnb659fds
Type: String
AllowedPattern: "[A-Za-z0-9_-]{1,10}"
ConstraintDescription: Qualifier must be an alphanumeric identifier of at most 10 characters
PublicAccessBlockConfiguration:
Description: Whether or not to enable S3 Staging Bucket Public Access Block Configuration
Default: "true"
Type: String
AllowedValues:
- "true"
- "false"
InputPermissionsBoundary:
Description: Whether or not to use either the CDK supplied or custom permissions boundary
Default: ""
Type: String
UseExamplePermissionsBoundary:
Default: "false"
AllowedValues:
- "true"
- "false"
Type: String
BootstrapVariant:
Type: String
Default: "AWS CDK: Default Resources"
Description: Describe the provenance of the resources in this bootstrap stack. Change this when you customize the template. To prevent accidents, the CDK CLI will not overwrite bootstrap stacks with a different variant.
Conditions:
HasTrustedAccounts:
Fn::Not:
- Fn::Equals:
- ""
- Fn::Join:
- ""
- Ref: TrustedAccounts
HasTrustedAccountsForLookup:
Fn::Not:
- Fn::Equals:
- ""
- Fn::Join:
- ""
- Ref: TrustedAccountsForLookup
HasCloudFormationExecutionPolicies:
Fn::Not:
- Fn::Equals:
- ""
- Fn::Join:
- ""
- Ref: CloudFormationExecutionPolicies
HasCustomFileAssetsBucketName:
Fn::Not:
- Fn::Equals:
- ""
- Ref: FileAssetsBucketName
CreateNewKey:
Fn::Equals:
- ""
- Ref: FileAssetsBucketKmsKeyId
UseAwsManagedKey:
Fn::Equals:
- AWS_MANAGED_KEY
- Ref: FileAssetsBucketKmsKeyId
ShouldCreatePermissionsBoundary:
Fn::Equals:
- "true"
- Ref: UseExamplePermissionsBoundary
PermissionsBoundarySet:
Fn::Not:
- Fn::Equals:
- ""
- Ref: InputPermissionsBoundary
HasCustomContainerAssetsRepositoryName:
Fn::Not:
- Fn::Equals:
- ""
- Ref: ContainerAssetsRepositoryName
UsePublicAccessBlockConfiguration:
Fn::Equals:
- "true"
- Ref: PublicAccessBlockConfiguration
Resources:
FileAssetsBucketEncryptionKey:
Type: AWS::KMS::Key
Properties:
KeyPolicy:
Statement:
- Action:
- kms:Create*
- kms:Describe*
- kms:Enable*
- kms:List*
- kms:Put*
- kms:Update*
- kms:Revoke*
- kms:Disable*
- kms:Get*
- kms:Delete*
- kms:ScheduleKeyDeletion
- kms:CancelKeyDeletion
- kms:GenerateDataKey
- kms:TagResource
- kms:UntagResource
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
Resource: "*"
- Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Principal:
AWS: "*"
Resource: "*"
Condition:
StringEquals:
kms:CallerAccount:
Ref: AWS::AccountId
kms:ViaService:
- Fn::Sub: s3.${AWS::Region}.amazonaws.com
- Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Principal:
AWS:
Fn::Sub: ${FilePublishingRole.Arn}
Resource: "*"
Condition: CreateNewKey
UpdateReplacePolicy: Delete
DeletionPolicy: Delete
FileAssetsBucketEncryptionKeyAlias:
Condition: CreateNewKey
Type: AWS::KMS::Alias
Properties:
AliasName:
Fn::Sub: alias/cdk-${Qualifier}-assets-key
TargetKeyId:
Ref: FileAssetsBucketEncryptionKey
StagingBucket:
Type: AWS::S3::Bucket
Properties:
BucketName:
Fn::If:
- HasCustomFileAssetsBucketName
- Fn::Sub: ${FileAssetsBucketName}
- Fn::Sub: cdk-${Qualifier}-assets-${AWS::AccountId}-${AWS::Region}
AccessControl: Private
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
KMSMasterKeyID:
Fn::If:
- CreateNewKey
- Fn::Sub: ${FileAssetsBucketEncryptionKey.Arn}
- Fn::If:
- UseAwsManagedKey
- Ref: AWS::NoValue
- Fn::Sub: ${FileAssetsBucketKmsKeyId}
PublicAccessBlockConfiguration:
Fn::If:
- UsePublicAccessBlockConfiguration
- BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
- Ref: AWS::NoValue
VersioningConfiguration:
Status: Enabled
LifecycleConfiguration:
Rules:
- Id: CleanupOldVersions
Status: Enabled
NoncurrentVersionExpiration:
NoncurrentDays: 30
- Id: AbortIncompleteMultipartUploads
Status: Enabled
AbortIncompleteMultipartUpload:
DaysAfterInitiation: 1
UpdateReplacePolicy: Retain
DeletionPolicy: Retain
StagingBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: StagingBucket
PolicyDocument:
Id: AccessControl
Version: "2012-10-17"
Statement:
- Sid: AllowSSLRequestsOnly
Action: s3:*
Effect: Deny
Resource:
- Fn::Sub: ${StagingBucket.Arn}
- Fn::Sub: ${StagingBucket.Arn}/*
Condition:
Bool:
aws:SecureTransport: "false"
Principal: "*"
ContainerAssetsRepository:
Type: AWS::ECR::Repository
Properties:
ImageTagMutability: IMMUTABLE
LifecyclePolicy:
LifecyclePolicyText: |
{
"rules": [
{
"rulePriority": 1,
"description": "Untagged images should not exist, but expire any older than one year",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 365
},
"action": { "type": "expire" }
}
]
}
RepositoryName:
Fn::If:
- HasCustomContainerAssetsRepositoryName
- Fn::Sub: ${ContainerAssetsRepositoryName}
- Fn::Sub: cdk-${Qualifier}-container-assets-${AWS::AccountId}-${AWS::Region}
RepositoryPolicyText:
Version: "2012-10-17"
Statement:
- Sid: LambdaECRImageRetrievalPolicy
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action:
- ecr:BatchGetImage
- ecr:GetDownloadUrlForLayer
Condition:
StringLike:
aws:sourceArn:
Fn::Sub: arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:*
- Sid: EmrServerlessImageRetrievalPolicy
Effect: Allow
Principal:
Service: emr-serverless.amazonaws.com
Action:
- ecr:BatchGetImage
- ecr:GetDownloadUrlForLayer
- ecr:DescribeImages
Condition:
StringLike:
aws:sourceArn:
Fn::Sub: arn:${AWS::Partition}:emr-serverless:${AWS::Region}:${AWS::AccountId}:/applications/*
FilePublishingRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:TagSession
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- Fn::If:
- HasTrustedAccounts
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: TrustedAccounts
- Ref: AWS::NoValue
RoleName:
Fn::Sub: cdk-${Qualifier}-file-publishing-role-${AWS::AccountId}-${AWS::Region}
PermissionsBoundary:
Fn::If:
- PermissionsBoundarySet
- Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/${InputPermissionsBoundary}
- Ref: CdkBoostrapPermissionsBoundaryPolicy
Tags:
- Key: aws-cdk:bootstrap-role
Value: file-publishing
ImagePublishingRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:TagSession
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- Fn::If:
- HasTrustedAccounts
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: TrustedAccounts
- Ref: AWS::NoValue
RoleName:
Fn::Sub: cdk-${Qualifier}-image-publishing-role-${AWS::AccountId}-${AWS::Region}
PermissionsBoundary:
Fn::If:
- PermissionsBoundarySet
- Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/${InputPermissionsBoundary}
- Ref: CdkBoostrapPermissionsBoundaryPolicy
Tags:
- Key: aws-cdk:bootstrap-role
Value: image-publishing
LookupRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:TagSession
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- Fn::If:
- HasTrustedAccountsForLookup
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: TrustedAccountsForLookup
- Ref: AWS::NoValue
- Fn::If:
- HasTrustedAccounts
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: TrustedAccounts
- Ref: AWS::NoValue
RoleName:
Fn::Sub: cdk-${Qualifier}-lookup-role-${AWS::AccountId}-${AWS::Region}
ManagedPolicyArns:
- Fn::Sub: arn:${AWS::Partition}:iam::aws:policy/ReadOnlyAccess
Policies:
- PolicyDocument:
Statement:
- Sid: DontReadSecrets
Effect: Deny
Action:
- kms:Decrypt
Resource: "*"
Version: "2012-10-17"
PolicyName: LookupRolePolicy
PermissionsBoundary:
Fn::If:
- PermissionsBoundarySet
- Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/${InputPermissionsBoundary}
- Ref: CdkBoostrapPermissionsBoundaryPolicy
Tags:
- Key: aws-cdk:bootstrap-role
Value: lookup
FilePublishingRoleDefaultPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- s3:GetObject*
- s3:GetBucket*
- s3:GetEncryptionConfiguration
- s3:List*
- s3:DeleteObject*
- s3:PutObject*
- s3:Abort*
Resource:
- Fn::Sub: ${StagingBucket.Arn}
- Fn::Sub: ${StagingBucket.Arn}/*
Condition:
StringEquals:
aws:ResourceAccount:
- Fn::Sub: ${AWS::AccountId}
Effect: Allow
- Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Resource:
Fn::If:
- CreateNewKey
- Fn::Sub: ${FileAssetsBucketEncryptionKey.Arn}
- Fn::Sub: arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/${FileAssetsBucketKmsKeyId}
Version: "2012-10-17"
Roles:
- Ref: FilePublishingRole
PolicyName:
Fn::Sub: cdk-${Qualifier}-file-publishing-role-default-policy-${AWS::AccountId}-${AWS::Region}
ImagePublishingRoleDefaultPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- ecr:PutImage
- ecr:InitiateLayerUpload
- ecr:UploadLayerPart
- ecr:CompleteLayerUpload
- ecr:BatchCheckLayerAvailability
- ecr:DescribeRepositories
- ecr:DescribeImages
- ecr:BatchGetImage
- ecr:GetDownloadUrlForLayer
Resource:
Fn::Sub: ${ContainerAssetsRepository.Arn}
Effect: Allow
- Action:
- ecr:GetAuthorizationToken
Resource: "*"
Effect: Allow
Version: "2012-10-17"
Roles:
- Ref: ImagePublishingRole
PolicyName:
Fn::Sub: cdk-${Qualifier}-image-publishing-role-default-policy-${AWS::AccountId}-${AWS::Region}
DeploymentActionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:TagSession
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- Fn::If:
- HasTrustedAccounts
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: TrustedAccounts
- Ref: AWS::NoValue
Policies:
- PolicyDocument:
Statement:
- Sid: CloudFormationPermissions
Effect: Allow
Action:
- cloudformation:CreateChangeSet
- cloudformation:DeleteChangeSet
- cloudformation:DescribeChangeSet
- cloudformation:DescribeStacks
- cloudformation:ExecuteChangeSet
- cloudformation:CreateStack
- cloudformation:UpdateStack
- cloudformation:RollbackStack
- cloudformation:ContinueUpdateRollback
Resource: "*"
- Sid: PipelineCrossAccountArtifactsBucket
Effect: Allow
Action:
- s3:GetObject*
- s3:GetBucket*
- s3:List*
- s3:Abort*
- s3:DeleteObject*
- s3:PutObject*
Resource: "*"
Condition:
StringNotEquals:
s3:ResourceAccount:
Ref: AWS::AccountId
- Sid: PipelineCrossAccountArtifactsKey
Effect: Allow
Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Resource: "*"
Condition:
StringEquals:
kms:ViaService:
Fn::Sub: s3.${AWS::Region}.amazonaws.com
- Action: iam:PassRole
Resource:
Fn::Sub: ${CloudFormationExecutionRole.Arn}
Effect: Allow
- Sid: CliPermissions
Action:
- cloudformation:DescribeStackEvents
- cloudformation:GetTemplate
- cloudformation:DeleteStack
- cloudformation:UpdateTerminationProtection
- sts:GetCallerIdentity
- cloudformation:GetTemplateSummary
Resource: "*"
Effect: Allow
- Sid: CliStagingBucket
Effect: Allow
Action:
- s3:GetObject*
- s3:GetBucket*
- s3:List*
Resource:
- Fn::Sub: ${StagingBucket.Arn}
- Fn::Sub: ${StagingBucket.Arn}/*
- Sid: ReadVersion
Effect: Allow
Action:
- ssm:GetParameter
- ssm:GetParameters
Resource:
- Fn::Sub: arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter${CdkBootstrapVersion}
Version: "2012-10-17"
PolicyName: default
RoleName:
Fn::Sub: cdk-${Qualifier}-deploy-role-${AWS::AccountId}-${AWS::Region}
PermissionsBoundary:
Fn::If:
- PermissionsBoundarySet
- Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/${InputPermissionsBoundary}
- Ref: CdkBoostrapPermissionsBoundaryPolicy
Tags:
- Key: aws-cdk:bootstrap-role
Value: deploy
CloudFormationExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: cloudformation.amazonaws.com
Version: "2012-10-17"
ManagedPolicyArns:
Fn::If:
- HasCloudFormationExecutionPolicies
- Ref: CloudFormationExecutionPolicies
- Fn::If:
- HasTrustedAccounts
- Ref: AWS::NoValue
- - Fn::Sub: arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess
RoleName:
Fn::Sub: cdk-${Qualifier}-cfn-exec-role-${AWS::AccountId}-${AWS::Region}
PermissionsBoundary:
Fn::If:
- PermissionsBoundarySet
- Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/${InputPermissionsBoundary}
- Ref: CdkBoostrapPermissionsBoundaryPolicy
CdkBoostrapPermissionsBoundaryPolicy:
Condition: ShouldCreatePermissionsBoundary
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Statement:
- Sid: ExplicitAllowAll
Action:
- "*"
Effect: Allow
Resource: "*"
- Sid: DenyAccessIfRequiredPermBoundaryIsNotBeingApplied
Action:
- iam:CreateUser
- iam:CreateRole
- iam:PutRolePermissionsBoundary
- iam:PutUserPermissionsBoundary
Condition:
StringNotEquals:
iam:PermissionsBoundary:
Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/cdk-${Qualifier}-permissions-boundary-${AWS::AccountId}-${AWS::Region}
Effect: Deny
Resource: "*"
- Sid: DenyPermBoundaryIAMPolicyAlteration
Action:
- iam:CreatePolicyVersion
- iam:DeletePolicy
- iam:DeletePolicyVersion
- iam:SetDefaultPolicyVersion
Effect: Deny
Resource:
Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/cdk-${Qualifier}-permissions-boundary-${AWS::AccountId}-${AWS::Region}
- Sid: DenyRemovalOfPermBoundaryFromAnyUserOrRole
Action:
- iam:DeleteUserPermissionsBoundary
- iam:DeleteRolePermissionsBoundary
Effect: Deny
Resource: "*"
Version: "2012-10-17"
Description: Bootstrap Permission Boundary
ManagedPolicyName:
Fn::Sub: cdk-${Qualifier}-permissions-boundary-${AWS::AccountId}-${AWS::Region}
Path: /
CdkBootstrapVersion:
Type: AWS::SSM::Parameter
Properties:
Type: String
Name:
Fn::Sub: /cdk-bootstrap/${Qualifier}/version
Value: "27"
Outputs:
BucketName:
Description: The name of the S3 bucket owned by the CDK toolkit stack
Value:
Fn::Sub: ${StagingBucket}
BucketDomainName:
Description: The domain name of the S3 bucket owned by the CDK toolkit stack
Value:
Fn::Sub: ${StagingBucket.RegionalDomainName}
FileAssetKeyArn:
Description: The ARN of the KMS key used to encrypt the asset bucket (deprecated)
Value:
Fn::If:
- CreateNewKey
- Fn::Sub: ${FileAssetsBucketEncryptionKey.Arn}
- Fn::Sub: ${FileAssetsBucketKmsKeyId}
Export:
Name:
Fn::Sub: CdkBootstrap-${Qualifier}-FileAssetKeyArn
ImageRepositoryName:
Description: The name of the ECR repository which hosts docker image assets
Value:
Fn::Sub: ${ContainerAssetsRepository}
BootstrapVersion:
Description: The version of the bootstrap resources that are currently mastered in this stack
Value:
Fn::GetAtt:
- CdkBootstrapVersion
- Value
参考リンク