Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow all sts options for roles assumed by the cli #31089

Merged
merged 94 commits into from
Sep 23, 2024
Merged
Changes from 1 commit
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
4f7a820
WIP: add placeholder integ test
sumupitchayan Aug 12, 2024
d02e7d2
WIP: CLI bootstrap integ test is passing, even though it should be fa…
sumupitchayan Aug 12, 2024
e50a57c
cleanup comments in app.js
sumupitchayan Aug 12, 2024
9f2e54b
Integ test now 'successfully' fails as intended; switched session tag…
sumupitchayan Aug 12, 2024
da3ee2b
add principaltag to deployrole policy
sumupitchayan Aug 13, 2024
2720e81
WIP: make framework changes
sumupitchayan Aug 13, 2024
52c049e
Merge branch 'main' into sumughan/session-tags
sumupitchayan Aug 13, 2024
0595021
add session tags to cloud assembly schema, fixing compiler errors
sumupitchayan Aug 13, 2024
47e947b
WIP: CLI changes in sdk-provider
sumupitchayan Aug 13, 2024
35a2c86
Integ test successfully failing
sumupitchayan Aug 14, 2024
53a70ee
add tags to lambda stack
sumupitchayan Aug 14, 2024
c6ba899
fix department session tag in app.js example
sumupitchayan Aug 14, 2024
7fd801b
WIP: update CFN schema, add session tags prop in different places
sumupitchayan Aug 15, 2024
bc3f498
TEMP FIX - to use local source version of aws-cdk-lib in cli integ tests
sumupitchayan Aug 15, 2024
b36fb70
remove commented out code in app.js
sumupitchayan Aug 16, 2024
9cdcd24
remove changes to cx-api/lib/artifacts/cloudformation-artifact.ts
sumupitchayan Aug 16, 2024
7197399
add tags to file asset role in integ test
sumupitchayan Aug 16, 2024
1d361bf
Update packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js
sumupitchayan Aug 19, 2024
c529bd9
Update packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js
sumupitchayan Aug 19, 2024
f195dee
typo: rename sessiontagslambdastack
sumupitchayan Aug 19, 2024
a4e3736
Add (and assert on) session tags for the docker image role in Integ t…
sumupitchayan Aug 19, 2024
7a3a80e
Add session tags to core README
sumupitchayan Aug 19, 2024
de1e557
WIP: add custom synthesizer integ test which is succeeding when it SH…
sumupitchayan Aug 20, 2024
1ec5f87
WIP
sumupitchayan Aug 20, 2024
251287b
add assumeRoleSessionTags to CloudFormationStackArtifact
sumupitchayan Aug 20, 2024
0ad122f
add assumeRoleSessionTags to ClientOptions interfact in cdk-assets/
sumupitchayan Aug 20, 2024
f86fe91
WIP: custom synth integ test now deploys! (without session tags in bo…
sumupitchayan Aug 20, 2024
2365552
add Session Tag conditional to Lambda policy statement - integ test n…
sumupitchayan Aug 20, 2024
05d2b79
add assumeRoleSessionTags inside prepareSdkWithLookupRoleFor function
sumupitchayan Aug 20, 2024
53eb52f
add unit test for aws-cdk-lib/core/lib/stack-synthesizers
sumupitchayan Aug 20, 2024
8927b6a
add lookup role to synth unit test
sumupitchayan Aug 20, 2024
555255f
add Engineering session tag to customsynth integ test stack
sumupitchayan Aug 21, 2024
1cca0e2
missing comma
sumupitchayan Aug 21, 2024
fe327c0
Add TagSession permission to roles in custom bootstrap stacks to make…
sumupitchayan Aug 23, 2024
12e60f6
remove unused imports from app.js
sumupitchayan Aug 23, 2024
6b92bd5
add custom synthesizer in separate file, also unit test for it
sumupitchayan Aug 24, 2024
11195e1
update core README
sumupitchayan Aug 24, 2024
ab9b26c
remove hardcoded path from lib/with-cdk-app.ts
sumupitchayan Aug 24, 2024
45a86d7
remove cdk-assets and cloud-assembly-schema directories
sumupitchayan Aug 24, 2024
4bc8830
add back cloud-assembly-schema dir with README and index.ts
sumupitchayan Aug 24, 2024
40227e2
Merge branch 'main' into sumughan/session-tags
sumupitchayan Aug 24, 2024
e8195d3
Update packages/@aws-cdk-testing/cli-integ/lib/with-cdk-app.ts
sumupitchayan Aug 26, 2024
da43281
add explanation comments inside custom bootstrap templates on TagSess…
sumupitchayan Aug 26, 2024
37a8ad5
Update packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js
sumupitchayan Aug 26, 2024
95d990b
Update packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/boot…
sumupitchayan Aug 26, 2024
94dc868
cleanup app.js
sumupitchayan Aug 26, 2024
ad33968
Merge branch 'sumughan/session-tags' of https://github.com/aws/aws-cd…
sumupitchayan Aug 26, 2024
d114fc7
rename CustomSynthesizer to NoExecutionRoleCustomSynthesizer in app.js
sumupitchayan Aug 26, 2024
59c1098
WIP: core README
sumupitchayan Aug 26, 2024
3a7a948
add comment in sdk-provider.ts explaining why we use transitive tag keys
sumupitchayan Aug 26, 2024
2bb8381
remove extra line in cloud-assembly-schema/README.md
sumupitchayan Aug 26, 2024
06de35a
delete custom-synthesizer file, write it inline core unit test instea…
sumupitchayan Aug 26, 2024
ec4b07d
add example using CustomSynthesizer to core README
sumupitchayan Aug 26, 2024
d920463
Merge branch 'main' into sumughan/session-tags
sumupitchayan Aug 26, 2024
278dc4e
add sdk-provider unit test, including adding sessionTags and transiti…
sumupitchayan Aug 26, 2024
1a44756
Merge branch 'sumughan/session-tags' of https://github.com/aws/aws-cd…
sumupitchayan Aug 26, 2024
a8fc420
sts:TagSession to bootstrap template and adjust bootstrap versions re…
iliapolo Aug 28, 2024
b3c62c9
mid work
iliapolo Aug 29, 2024
e5a369e
mid work
iliapolo Sep 1, 2024
2a9ef1f
mid work
iliapolo Sep 1, 2024
d4a43b1
Merge branch 'main' into sumughan/session-tags
iliapolo Sep 1, 2024
67160f1
mid work
iliapolo Sep 2, 2024
a1bfbdf
mid work
iliapolo Sep 2, 2024
d9374a2
mid work
iliapolo Sep 4, 2024
5d7b601
mid work
iliapolo Sep 10, 2024
a51622a
mid work
iliapolo Sep 11, 2024
007f23f
Merge branch 'main' into sumughan/session-tags
iliapolo Sep 11, 2024
30ce9f8
mid work
iliapolo Sep 11, 2024
315b169
test vpc lookup
iliapolo Sep 12, 2024
ff0034d
mid work
iliapolo Sep 12, 2024
8cc1d92
mid work
iliapolo Sep 12, 2024
b24e879
mid work
iliapolo Sep 12, 2024
fc455f1
mid work
iliapolo Sep 12, 2024
ff9b20a
mid work
iliapolo Sep 12, 2024
da2cb72
mid work
iliapolo Sep 12, 2024
1539bfe
mid work
iliapolo Sep 15, 2024
da328ee
mid work
iliapolo Sep 15, 2024
bcdf94f
Merge branch 'main' into sumughan/session-tags
iliapolo Sep 15, 2024
0b47cd7
mid work
iliapolo Sep 15, 2024
0ae1a1b
mid work
iliapolo Sep 15, 2024
f778c2c
Merge branch 'main' into sumughan/session-tags
iliapolo Sep 18, 2024
07137e3
mid work
iliapolo Sep 19, 2024
22b1069
Merge branch 'main' into sumughan/session-tags
iliapolo Sep 19, 2024
4734465
mid work
iliapolo Sep 19, 2024
50ef70f
Merge branch 'main' into sumughan/session-tags
iliapolo Sep 19, 2024
ebce5fe
mid work
iliapolo Sep 20, 2024
d923ec6
Merge branch 'main' into sumughan/session-tags
iliapolo Sep 20, 2024
b32c570
mid work
iliapolo Sep 20, 2024
6e08d60
Merge branch 'main' into sumughan/session-tags
iliapolo Sep 20, 2024
217b08b
Merge branch 'main' into sumughan/session-tags
iliapolo Sep 23, 2024
a33c6e2
mid work
iliapolo Sep 23, 2024
c57f0ba
mid work
iliapolo Sep 23, 2024
4a70851
Merge branch 'main' into sumughan/session-tags
iliapolo Sep 23, 2024
0c753cf
Merge branch 'main' into sumughan/session-tags
mergify[bot] Sep 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
WIP: add custom synthesizer integ test which is succeeding when it SH…
…OULDN'T

Signed-off-by: Sumu <[email protected]>
sumupitchayan committed Aug 20, 2024
commit de1e557a6695e4339d3ab0d6251249a56e6d7d73
Original file line number Diff line number Diff line change
@@ -0,0 +1,670 @@
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
# "cdk-(qualifier)-image-publishing-role-(account)-(region)" needs to be <= 64 chars
# account = 12, region <= 14, 10 chars for qualifier and 28 for rest of role name
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:
# Not actually everyone -- see below for Conditions
AWS: "*"
Resource: "*"
Condition:
StringEquals:
# See https://docs.aws.amazon.com/kms/latest/developerguide/policy-conditions.html#conditions-kms-caller-account
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
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:
# Exising objects will never be overwritten but Security Hub wants this rule to exist
- Id: CleanupOldVersions
Status: Enabled
NoncurrentVersionExpiration:
NoncurrentDays: 365
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
# Untagged images should never exist but Security Hub wants this rule to exist
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:
# Necessary for Lambda container images
# https://docs.aws.amazon.com/lambda/latest/dg/configuration-images.html#configuration-images-permissions
- 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:*" }
FilePublishingRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- 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}
Tags:
- Key: aws-cdk:bootstrap-role
Value: file-publishing
ImagePublishingRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- 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}
Tags:
- Key: aws-cdk:bootstrap-role
Value: image-publishing
LookupRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- 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
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: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
Resource: "*"
- Sid: PipelineCrossAccountArtifactsBucket
# Read/write buckets in different accounts. Permissions to buckets in
# same account are granted by bucket policies.
#
# Write permissions necessary to write outputs to the cross-region artifact replication bucket
# https://aws.amazon.com/premiumsupport/knowledge-center/codepipeline-deploy-cloudformation/.
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
# Use keys only for the purposes of reading encrypted files from S3.
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
# - Action: lambda:CreateFunction
# Effect: Allow
# Resource: '*'
# Condition:
# StringEquals:
# aws:PrincipalTag/Department: 'Engineering'
- Effect: Deny
Action: lambda:CreateFunction
Resource: "*"
Condition:
StringNotEquals:
"aws:PrincipalTag/Hello": "true"
- Sid: CliPermissions
Action:
# Permissions needed by the CLI when doing `cdk deploy`.
# Our CI/CD does not need DeleteStack,
# but we also want to use this role from the CLI,
# and there you can call `cdk destroy`
- cloudformation:DescribeStackEvents
- cloudformation:GetTemplate
- cloudformation:DeleteStack
- cloudformation:UpdateTerminationProtection
- sts:GetCallerIdentity
# `cdk import`
- 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 # CreateChangeSet uses this to evaluate any SSM parameters (like `CdkBootstrapVersion`)
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}
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
# # The CLI will prevent this case from occurring
# - Ref: AWS::NoValue
# # The CLI will advertise that we picked this implicitly
# - - 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: AWS::NoValue
CdkBoostrapPermissionsBoundaryPolicy:
# Edit the template prior to boostrap in order to have this example policy created
Condition: ShouldCreatePermissionsBoundary
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Statement:
# If permission boundaries do not have an explicit `allow`, then the effect is `deny`
- Sid: ExplicitAllowAll
Action:
- "*"
Effect: Allow
Resource: "*"
# Default permissions to prevent privilege escalation
- 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: "*"
# Forbid the policy itself being edited
- 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}
# Forbid removing the permissions boundary from any user or role that has it associated
- Sid: DenyRemovalOfPermBoundaryFromAnyUserOrRole
Action:
- iam:DeleteUserPermissionsBoundary
- iam:DeleteRolePermissionsBoundary
Effect: Deny
Resource: "*"
# Add your specific organizational security policy here
# Uncomment the example to deny access to AWS Config
#- Sid: OrganizationalSecurityPolicy
# Action:
# - "config:*"
# Effect: Deny
# Resource: "*"
Version: "2012-10-17"
Description: "Bootstrap Permission Boundary"
ManagedPolicyName:
Fn::Sub: cdk-${Qualifier}-permissions-boundary-${AWS::AccountId}-${AWS::Region}
Path: /
# The SSM parameter is used in pipeline-deployed templates to verify the version
# of the bootstrap resources.
CdkBootstrapVersion:
Type: AWS::SSM::Parameter
Properties:
Type: String
Name:
Fn::Sub: '/cdk-bootstrap/${Qualifier}/version'
Value: '21'
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}"
# @deprecated - This Export can be removed at some future point in time.
# We can't do it today because if there are stacks that use it, the bootstrap
# stack cannot be updated. Not used anymore by apps >= 1.60.0
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}"
# The Output is used by the CLI to verify the version of the bootstrap resources.
BootstrapVersion:
Description: The version of the bootstrap resources that are currently mastered
in this stack
Value:
Fn::GetAtt: [CdkBootstrapVersion, Value]
105 changes: 102 additions & 3 deletions packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js
Original file line number Diff line number Diff line change
@@ -17,7 +17,10 @@ if (process.env.PACKAGE_LAYOUT_VERSION === '1') {
var cdk = require('aws-cdk-lib');
var {
DefaultStackSynthesizer,
StackSynthesizer,
LegacyStackSynthesizer,
AssetManifestBuilder,
assertBound,
aws_ec2: ec2,
aws_ecs: ecs,
aws_sso: sso,
@@ -30,6 +33,9 @@ if (process.env.PACKAGE_LAYOUT_VERSION === '1') {
aws_ecr_assets: docker,
Stack
} = require('aws-cdk-lib');
var {
sumupitchayan marked this conversation as resolved.
Show resolved Hide resolved
StringSpecializer
} = require('aws-cdk-lib/core/lib/helpers-internal');
}

const { Annotations } = cdk;
@@ -439,21 +445,113 @@ class SessionTagsStack extends cdk.Stack {
})
});

// Lambda Function to test AssetPublishingRole
const fn = new lambda.Function(this, 'my-function', {
code: lambda.Code.asset(path.join(__dirname, 'lambda')),
runtime: lambda.Runtime.NODEJS_LATEST,
handler: 'index.handler'
});
new cdk.CfnOutput(this, 'FunctionArn', { value: fn.functionArn });
sumupitchayan marked this conversation as resolved.
Show resolved Hide resolved

// DockerImageAsset to test ImageAssetPublishingRole
new docker.DockerImageAsset(this, 'image', {
directory: path.join(__dirname, 'docker')
});

// Add at least a single resource (WaitConditionHandle), otherwise this stack will never
// be deployed (and its assets never built)
new cdk.CfnResource(this, 'Handle', {
type: 'AWS::CloudFormation::WaitConditionHandle'
});
}
}

class CustomSynthesizer extends cdk.StackSynthesizer {
assetManifest = new AssetManifestBuilder();
fileAssetPublishingRoleArn;
bucketName = 'cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}'
bucketPrefix = '';
bootstrapStackVersionSsmParameter = '/cdk-bootstrap/hnb659fds/version';
qualifier = '';
props;

DEFAULT_FILE_ASSET_PUBLISHING_ROLE_ARN = 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}';
BOOTSTRAP_QUALIFIER_CONTEXT = '@aws-cdk/core:bootstrapQualifier';
DEFAULT_DEPLOY_ROLE_ARN = 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}';
DEFAULT_LOOKUP_ROLE_ARN = 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}';

DEFAULT_QUALIFIER = 'hnb659fds';

constructor(props) {
super();
this.props = props;
}

bind(stack) {
super.bind(stack);

const qualifier = stack.node.tryGetContext(this.BOOTSTRAP_QUALIFIER_CONTEXT) ?? this.DEFAULT_QUALIFIER;
this.qualifier = qualifier;

this.fileAssetPublishingRoleArn = this.DEFAULT_FILE_ASSET_PUBLISHING_ROLE_ARN;
}

addFileAsset(asset) {
const location = this.assetManifest.defaultAddFileAsset(this.boundStack, asset, {
bucketName: this.bucketName,
bucketPrefix: this.bucketPrefix,
role: this.fileAssetPublishingRoleArn ? {
assumeRoleArn: this.fileAssetPublishingRoleArn,
assumeRoleExternalId: this.props.fileAssetPublishingExternalId,
assumeRoleSessionTags: this.props.fileAssetPublishingRoleSessionTags,
} : undefined,
});
return this.cloudFormationLocationFromFileAsset(location);
}

synthesize(session) {
const templateAssetSource = this.synthesizeTemplate(session, this.lookupRoleArn);
const templateAsset = this.addFileAsset(templateAssetSource);

const assetManifestId = this.assetManifest.emitManifest(this.boundStack, session, {
requiresBootstrapStackVersion: 6,
bootstrapStackVersionSsmParameter: '/cdk-bootstrap/hnb659fds/version',
});

this.emitArtifact(session, {
assumeRoleExternalId: this.props.deployRoleExternalId,
assumeRoleArn: this.deployRoleArn,
assumeRoleSessionTags: this.props.deployRoleSessionTags,
// Pass in undefined for the CFN exec role:
cloudFormationExecutionRoleArn: undefined,
stackTemplateAssetObjectUrl: templateAsset.s3ObjectUrlWithPlaceholders,
requiresBootstrapStackVersion: 6,
bootstrapStackVersionSsmParameter: '/cdk-bootstrap/hnb659fds/version',
additionalDependencies: [assetManifestId],
lookupRole: this.useLookupRoleForStackOperations && this.lookupRoleArn ? {
arn: this.lookupRoleArn,
assumeRoleExternalId: this.props.lookupRoleExternalId,
assumeRoleSessionTags: this.props.lookupRoleSessionTags,
requiresBootstrapStackVersion: 6,
bootstrapStackVersionSsmParameter: this.bootstrapStackVersionSsmParameter,
} : undefined,
});
}
}

class SessionTagsWithCustomSynthesizerStack extends cdk.Stack {
constructor(parent, id, props) {
super(parent, id, {
...props,
synthesizer: new CustomSynthesizer({
// deployRoleSessionTags: {
// 'Department' : 'Engineering',
// },
})
});

const fn = new lambda.Function(this, 'my-function', {
code: lambda.Code.asset(path.join(__dirname, 'lambda')),
runtime: lambda.Runtime.NODEJS_LATEST,
handler: 'index.handler'
});

new cdk.CfnOutput(this, 'FunctionArn', { value: fn.functionArn });
}
@@ -709,6 +807,7 @@ switch (stackSet) {

new LambdaStack(app, `${stackPrefix}-lambda`);
new SessionTagsStack(app, `${stackPrefix}-session-tags`);
new SessionTagsWithCustomSynthesizerStack(app, `${stackPrefix}-session-tags-with-custom-synthesizer`);
new LambdaHotswapStack(app, `${stackPrefix}-lambda-hotswap`);
new EcsHotswapStack(app, `${stackPrefix}-ecs-hotswap`);
new DockerStack(app, `${stackPrefix}-docker`);
Original file line number Diff line number Diff line change
@@ -82,7 +82,7 @@ integTest('can and deploy if omitting execution policies', withoutBootstrap(asyn
});
}));

// Custom Bootstrap test with Session Tags on the DeployRole
// Custom Bootstrap test with Session Tags on the Deploy, FileAssetPublishing and ImageAssetPublishing Roles
integTest('can deploy with session tags on the deploy, file asset, and image asset publishing roles', withoutBootstrap(async (fixture) => {
const bootstrapStackName = fixture.bootstrapStackName;

@@ -100,6 +100,24 @@ integTest('can deploy with session tags on the deploy, file asset, and image ass
});
}));

// Custom Bootstrap test without CloudFormationExecutionRole and Session Tags on the DeployRole
integTest('can deploy with session tags using custom synthesizer', withoutBootstrap(async (fixture) => {
sumupitchayan marked this conversation as resolved.
Show resolved Hide resolved
const bootstrapStackName = fixture.bootstrapStackName;

await fixture.cdkBootstrapModern({
toolkitStackName: bootstrapStackName,
bootstrapTemplate: path.join(__dirname, '..', '..', 'resources', 'bootstrap-templates', 'custom-bootstrap-with-session-tags.yaml'),
});

await fixture.cdkDeploy('session-tags-with-custom-synthesizer', {
options: [
'--toolkit-stack-name', bootstrapStackName,
'--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`,
'--context', '@aws-cdk/core:newStyleStackSynthesis=1',
],
});
}));

integTest('deploy new style synthesis to new style bootstrap', withoutBootstrap(async (fixture) => {
const bootstrapStackName = fixture.bootstrapStackName;