[AWS Basics] AWS CDK
Table of contents
Tại sao nên sử dụng CDK?
- Overcome được những giới hạn của CloudFormation, thay vì viết 1000 dòng code thì sẽ viết 50 dòng thôi
Ví dụ đoạn code dưới đây để define VPC:
import * as cdk from '@aws-cdk/core';
import * as ec2 from '@aws-cdk/aws-ec2';
export class NetworkStack extends cdk.Stack {
public readonly vpc: ec2.Vpc;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
this.vpc = new ec2.Vpc(this, 'VPC', {
cidr: '10.0.0.0/16',
natGatewaySubnets: {
subnetName: 'Public'
},
subnetConfiguration: [
{
cidrMask: 26,
name: 'Public',
subnetType: ec2.SubnetType.PUBLIC
},
{
name: 'Application',
subnetType: ec2.SubnetType.PRIVATE
},
{
cidrMask: 27,
name: 'Database',
subnetType: ec2.SubnetType.ISOLATED
}
]
});
const vpcSecurityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {
vpc: this.vpc,
description: 'Allow ssh access to ec2 instances',
allowAllOutbound: true
});
vpcSecurityGroup.addIngressRule(
ec2.Peer.anyIpv4(),
ec2.Port.tcp(22),
'allow ssh access from the world'
);
}
}
- Là một version developer – friendly của CloudFormation
Các ngôn ngữ declarative như HCL, YAM, JSON người làm dev có thể không quen thuộc.
CDK sử dụng object-oriented để cung cấp các abstraction technique, có thể tạo các modules để share giữ các project, có thể sử dụng build-in lib
Support các ngôn ngữ lập trình như Java, JS, Python, TypeScript và .NET, thay vì phải học một syntax mới thì có thể tận dụng khả năng lập trình sẵn có
Có thể sử dụng các logic (if – else, for-loop, etc) để define infrastructure. Ví dụ:
CDK cho phép thực hiện snapshot tests, fine-grained assertions, không cần phải có 1 tool khác để test như CloudFormation. Chi tiết về test, xem thêm: https://aws.amazon.com/blogs/developer/testing-infrastructure-with-the-aws-cloud-development-kit-cdk/
Docs CDK của AWS: https://docs.aws.amazon.com/cdk/v2/guide/home.html
API reference: https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html
Construct Hub: https://constructs.dev/search?q=&cdk=aws-cdk&cdkver=2&sort=downloadsDesc&offset=0
Các concepts: https://docs.aws.amazon.com/cdk/v2/guide/core_concepts.html
Các khái niệm:
Construct:
Thể hiện 1 cloud components và encapsulate tất cả những gì CloudFormation cần để tạo ra component đó
Construct được implement trong các class extend Construct base class.
Tất cả các construct gồm có 3 parameter:
scope: Bạn nên pass this (self)
id: identifier phải duy nhất trong scipt, sẽ sử dụng để tạo resource name và AWS CloudFormation logical IDs.
props: Các properties hoặc keyword arguments định nghĩa intitial configuratiuon của construct. Nếu không định nghĩa pros thì construct sẽ cung cấp các giá trị default.
from aws_cdk import App, Stack
import aws_cdk.aws_s3 as s3
from constructs import Construct
class HelloCdkStack(Stack):
def __init__(self, scope: Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
s3.Bucket(self, "MyFirstBucket", versioned=True)
app = App()
HelloCdkStack(app, "HelloCdkStack")
L1 construct: Chính xác là resource sẽ được define bởi CFn, không hơn không kém. Bạn sẽ phải tự định nghĩa các configuration. VD:
bucket = s3.CfnBucket(self, "MyBucket", bucket_name="MyBucket")
L2 construct: define S3 bucket bằng cách tạo ra 1 instance của Bucket class:
import aws_cdk.aws_s3 as s3
# "self" is HelloCdkStack
s3.Bucket(self, "MyFirstBucket", versioned=True)
Tự viết construct của bạn: Để declare 1 construct mới, thì tạo 1 class extend Construct base classs, VD:
class NotifyingBucket(Construct):
def __init__(self, scope: Construct, id: str, *, prefix=None):
super().__init__(scope, id)
bucket = s3.Bucket(self, "bucket")
topic = sns.Topic(self, "topic")
bucket.add_object_created_notification(s3notify.SnsDestination(topic),
s3.NotificationKeyFilter(prefix=prefix))
Sử dụng:
NotifyingBucket(self, "MyNotifyingBucket")
or:
NotifyingBucket(self, "MyNotifyingBucket", prefix="images/")
Chi tiết xem thêm: https://docs.aws.amazon.com/cdk/v2/guide/constructs.html#constructs_author
App:
#!/usr/bin/env python3
import os
import aws_cdk as cdk
from demo_cdk.demo_cdk_stack import DemoCdkStack
app = cdk.App()
DemoCdkStack(app, "DemoCdkStack",
# If you don't specify 'env', this stack will be environment-agnostic.
# Account/Region-dependent features and context lookups will not work,
# but a single synthesized template can be deployed anywhere.
# Uncomment the next line to specialize this stack for the AWS Account
# and Region that are implied by the current CLI configuration.
#env=cdk.Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'), region=os.getenv('CDK_DEFAULT_REGION')),
# Uncomment the next line if you know exactly what Account and Region you
# want to deploy the stack to. */
#env=cdk.Environment(account='123456789012', region='us-east-1'),
# For more information, see <https://docs.aws.amazon.com/cdk/latest/guide/environments.html>
)
app.synth()
App lifecyle:
Construction → Preparation → Validation → Synthesis → Deployment
Stack:
Một đơn vị deployment thì gọi là một stack, những aws resource define trong scope của 1 stack thì được provision như một single unit.
CDK stack thì được implement thông qua CloudFormation stack, và cũng sẽ có những limitation của CloudFormation (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html)
Bạn có thể define một hoặc nhiều stack trong CDK app.
VD: code CDK app sau define app bằng 2 stack:
app = App()
MyFirstStack(app, 'stack1')
MySecondStack(app, 'stack2')
app.synth()
Để list tất cả các stack trong app: sử dụng câu lệnh cdk ls
Khi chạy câu lệnh cdk synth với nhiều stack, thì bạn phải chỉ định stack. VD:
cdk synth stack1
Cách tiếp cận này khác so với các CloudFormation thường được dùng: template có thể deploy nhiều lần và sẽ được parameter hóa dựa vào AWS CloudFormation parameter.
Thông thường thì sẽ không khuyến khích việc sử dụng AWS CloudFormation parameter trong stack bởi vì AWS CloudFormation parameter chỉ được resolve trong quá trình deploy. Điều này có nghĩa là bạn sẽ phải quyết định giá trị của các parameter trong code. Ví dụ, để include 1 resource theo điều kiện ở trong app dựa vào value của parameter, bạn sẽ phải tạo một CFn condition và tag resource với condition này. Bởi vì CDK tiếp cận theo hướng những template rời rạc được resolved ở thời gian synthesis, bạn có thể sử dụng if statement để kiểm tra value để quyết định xem resource có được apply không.
stacks có thể được composed thành group.
Vd: Code dưới đây mô tả một ví dụ về service bao gồm 3 stack. Service construct được define 2 lần: 1 ở beta env và 1 ở prod env:
from aws_cdk import App, Stack
from constructs import Construct
# imagine these stacks declare a bunch of related resources
class ControlPlane(Stack): pass
class DataPlane(Stack): pass
class Monitoring(Stack): pass
class MyService(Construct):
def __init__(self, scope: Construct, id: str, *, prod=False):
super().__init__(scope, id)
# we might use the prod argument to change how the service is configured
ControlPlane(self, "cp")
DataPlane(self, "data")
Monitoring(self, "mon")
app = App();
MyService(app, "beta")
MyService(app, "prod", prod=True)
app.synth()
cdk app này thực ra sẽ bao gồm 6 stacks, 3 cho mỗi môi trường:
$ cdk ls
betacpDA8372D3
betadataE23DB2BA
betamon632BD457
prodcp187264CE
proddataF7378CE5
prodmon631A1083
Tên của AWS CloudFormation stack sẽ được định nghĩa với CDK dựa vào stack’s construct path
Nested stacks: NestedStack construct offer khoảng 500 resource limit cho stacks. Một nested stack được count là 1 resource trong stack chứa nó, nhưng nó có thể chứa tới 500 resources.
Scope của nested stack phải là Stack hoặc NestedStack construct.
Nested stack sẽ không được coi là deployment artifacts đọc lập, và sẽ không xuất hiện trong kết quả của cdk list hay cdk deploy
References giữa các stack cha và nested stack được translate tự động thành stack paramenters và output ở CloudFormation stack.
Environment:
Mỗi CDK stack sẽ được associate với 1 môi trường explicitly or implicitly. Một môi trường là target AWS account và region mà stack sẽ được deploy.
Nếu bạn không chỉ định môi trường khi khởi tạo 1 stack (environment-agnostic stack), thì CloudFormation template từ các stack này sẽ sử dụng deploy-time resolution ở các biến liên quan môi tường như stack.account, stack.region, stack.availability_zones
Khi deploy, các environment-agnostic stack, AWS CDK CLI sẽ dựa AWS CLI profile để quyết định sẽ deploy ở đâu.
Chỉ định môi trường:
env_EU = cdk.Environment(account="8373873873", region="eu-west-1")
env_USA = cdk.Environment(account="2383838383", region="us-west-2")
MyFirstStack(app, "first-stack-us", env=env_USA)
MyFirstStack(app, "first-stack-eu", env=env_EU
hardcode như trên thì stack sẽ luôn được deploy vào account và region đã set. Để làm stack deploy vào một target khác, stack của bạn sẽ sử dụng 2 env variables được cung cấp bới CDK CLI: CDK_DEFAULT_ACCOUNT
và CDK_DEFAULT_REGION
(These variables are set based on the AWS profile specified using the –profile option, or the default AWS profile if you don’t specify one.)
import os
MyDevStack(app, "dev", env=cdk.Environment(
account=os.environ["CDK_DEFAULT_ACCOUNT"],
region=os.environ["CDK_DEFAULT_REGION"]))
Resources:
import aws_cdk.aws_sqs as sqs
sqs.Queue(self, "MyQueue", encryption=sqs.QueueEncryption.KMS_MANAGED)
resource attribute:
import aws_cdk.aws_sqs as sqs
queue = sqs.Queue(self, "MyQueue")
url = queue.queue_url # => A string representing a deploy-time value
referencing resource:
cluster = ecs.Cluster(self, "Cluster")
service = ecs.Ec2Service(self, "Service", cluster=cluster)
access resource ở stack khác:
prod = cdk.Environment(account="123456789012", region="us-east-1")
stack1 = StackThatProvidesABucket(app, "Stack1", env=prod)
# stack2 will take a property "bucket"
stack2 = StackThatExpectsABucket(app, "Stack2", bucket=stack1.bucket, env=prod)
import 1 external resource đã tồn tại:
# Construct a resource (bucket) just by its name (must be same account)
s3.Bucket.from_bucket_name(self, "MyBucket", "my-bucket-name")
# Construct a resource (bucket) by its full ARN (can be cross account)
s3.Bucket.from_bucket_arn(self, "MyBucket", "arn:aws:s3:::my-bucket-name")
# Construct a resource by giving attribute(s) (complex resources)
ec2.Vpc.from_vpc_attributes(self, "MyVpc", vpc_id="vpc-1234567890abcdef")
Xem thêm: https://docs.aws.amazon.com/cdk/v2/guide/resources.html
Identifiers:
Construct IDs: phải unique trong scope, ví dụ dưới đây cùng tên nhưng khác scope nên OK:
from aws_cdk import App, Construct, Stack, StackProps
from constructs import Construct
from aws_cdk import aws_s3 as s3
class MyStack(Stack):
def __init__(self, scope: Construct, id: str, **kwargs):
super().__init__(scope, id, **kwargs)
s3.Bucket(self, "MyBucket")
app = App()
MyStack(app, 'Stack1')
MyStack(app, 'Stack2')
Paths: Refer đên scollections của IDs của các construct, parent construct,… → path
path = my_construct.node.path
Unique ID:
uid = Names.unique_id(my_construct)
addr = my_construct.node.addr
Logical IDs:
Stack2MyBucket4DD88B4F
Chi tiết: https://docs.aws.amazon.com/cdk/v2/guide/identifiers.html
Tokens:
Thể hiện các giá trị chỉ có thể được resolve trong giai đoạn sau của app lifecycle. VD: tên của S3 bucket mà bạn định nghĩa ở CDK app thì chỉ được allocated khi CloudFormation template được synthesize.
bucket = s3.Bucket(self, "MyBucket")
fn = lambda_.Function(stack, "MyLambda",
environment=dict(BUCKET_NAME=bucket.bucket_name))
Token và token encoding: sử dụng các static methods trong cdk.Token class:
Token.asString to generate a string encoding (or call .toString() on the token object)
Token.asList to generate a list encoding
Token.asNumber to generate a numeric encoding
Để kiểm tra xem một value có 1 unresolved token không thì:
if not Token.is_unresolved(name) and len(name) > 10:
raise ValueError("Maximum length for name is 10 characters")
Xem thêm về token: https://docs.aws.amazon.com/cdk/v2/guide/tokens.html
Parameter: bạn có thể define parameter cho các thuộc tính của construct, vừa có thể deploy stack chứa parameter.
Định nghĩa parameter:
upload_bucket_name = CfnParameter(self, "uploadBucketName", type="String",
description="The name of the Amazon S3 bucket where uploaded files will be stored.")
use the parameter:
bucket = Bucket(self, "myBucket",
bucket_name=upload_bucket_name.value_as_string)
Deploy với parameter:
cdk deploy MyStack --parameters uploadBucketName=UploadBucket
cdk deploy MyStack --parameters uploadBucketName=UpBucket --parameters downloadBucketName=DownBucket
Xem thêm: https://docs.aws.amazon.com/cdk/v2/guide/parameters.html
Boostraping:
Deploy một CDK app lên 1 AWS environment yêu cầu bạn phải provision resources mà CDK cần để thực hiện deploy. Những resource này bao gồm S3 bucket để lưu trữ files, IAM roles cho phép các quyền cần thiết để thực hiện deployments. Quá trình provisioning các resource này gọi là bootstraping.
Xem thêm về bootstraping: https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html
Xem thêm về Tagging, Assests, Permissions, Context, Feature flags, aspects và escape hatches tại: https://docs.aws.amazon.com/cdk/v2/guide/core_concepts.html
Tạo 1 CDK app:
Để tạo CDK app và setup các dependencies:
mkdir demo-cdk
cd demo-cdk
cdk init --language python
source .venv/bin/activate
pip install -r requirements.txt
Có 2 file cần lưu ý:
app.py: Main entry point
demo_cdk_stack.py: service stack
Để tạo 1 CDK app, chúng ta có thể sử dụng câu lệnh:
cdk init app --language=[csharp|fsharp|go|java|javascript|python|typescript]
Tại file demo_cdk_stack.py: Tạo 1 S3 bucket
from aws_cdk import (
# Duration,
Stack,
# aws_sqs as sqs,
)
import aws_cdk as cdk
import aws_cdk.aws_s3 as s3
from constructs import Construct
class DemoCdkStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
bucket = s3.Bucket(self, "MyFirstBucket", versioned=True)
# The code that defines your stack goes here
# example resource
# queue = sqs.Queue(
# self, "DemoCdkQueue",
# visibility_timeout=Duration.seconds(300),
# )
Bucket: construct. Có 3 parameter:
scope: Cho bucket biết bằng stack là parent của nó: được defile trong trong scope của stack. Trong hầu hết các case thì scope là this (self trong Python), có nghĩa là construct bao gồm bucket: the stack
id: ở đây là thuộc tính bucketName
props: các giá trị define properties của bucket, ở đây chúng ta mới chỉ define 1 properties: versioned
Synthesize 1 CloudFormation template cho app:
cdk synth
Nếu app của bạn có nhiều stack thì sẽ phải chỉ định stack để synth
cdk synth command chạy app của bạn, và resource sẽ được define rồi translate thành 1 CFn template.
Kết quả có dạng như sau:
Resources:
MyFirstBucketB8884501:
Type: AWS::S3::Bucket
Properties:
VersioningConfiguration:
Status: Enabled
UpdateReplacePolicy: Retain
DeletionPolicy: Retain
Metadata:
aws:cdk:path: DemoCdkStack/MyFirstBucket/Resource
CDKMetadata:
Type: AWS::CDK::Metadata
Properties:
Analytics: v2:deflate64:H4sIAAAAAAAA/yXIWw5AMBBA0bX4b8ejVsAGhAVIVcUo00SnERF7R3zdk1uAyqFI9BGkGZ1ccYCrY22ceFcfFFxVNM6yqCf6dX9sbfBxN/Zz7WlERk+3aE6ePaUK8gzKZAmIco/EuFlo/z4DpsAGcAAAAA==
Metadata:
aws:cdk:path: DemoCdkStack/CDKMetadata/Default
Condition: CDKMetadataAvailable
Conditions:
CDKMetadataAvailable:
Fn::Or:
- Fn::Or:
- Fn::Equals:
- Ref: AWS::Region
- af-south-1
- Fn::Equals:
- Ref: AWS::Region
- ap-east-1
- Fn::Equals:
- Ref: AWS::Region
- ap-northeast-1
- Fn::Equals:
- Ref: AWS::Region
- ap-northeast-2
- Fn::Equals:
- Ref: AWS::Region
- ap-south-1
- Fn::Equals:
- Ref: AWS::Region
- ap-southeast-1
- Fn::Equals:
- Ref: AWS::Region
- ap-southeast-2
- Fn::Equals:
- Ref: AWS::Region
- ca-central-1
- Fn::Equals:
- Ref: AWS::Region
- cn-north-1
- Fn::Equals:
- Ref: AWS::Region
- cn-northwest-1
- Fn::Or:
- Fn::Equals:
- Ref: AWS::Region
- eu-central-1
- Fn::Equals:
- Ref: AWS::Region
- eu-north-1
- Fn::Equals:
- Ref: AWS::Region
- eu-south-1
- Fn::Equals:
- Ref: AWS::Region
- eu-west-1
- Fn::Equals:
- Ref: AWS::Region
- eu-west-2
- Fn::Equals:
- Ref: AWS::Region
- eu-west-3
- Fn::Equals:
- Ref: AWS::Region
- me-south-1
- Fn::Equals:
- Ref: AWS::Region
- sa-east-1
- Fn::Equals:
- Ref: AWS::Region
- us-east-1
- Fn::Equals:
- Ref: AWS::Region
- us-east-2
- Fn::Or:
- Fn::Equals:
- Ref: AWS::Region
- us-west-1
- Fn::Equals:
- Ref: AWS::Region
- us-west-2
Parameters:
BootstrapVersion:
Type: AWS::SSM::Parameter::Value<String>
Default: /cdk-bootstrap/hnb659fds/version
Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]
Rules:
CheckBootstrapVersion:
Assertions:
- Assert:
Fn::Not:
- Fn::Contains:
- - "1"
- "2"
- "3"
- "4"
- "5"
- Ref: BootstrapVersion
AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.
Deploy stack:
cdk bootstrap
cdk deploy sẽ hiển thị thông tin quá trình stack của bạn được deploy:
Bootstrapping environment aws://240724612589/ap-northeast-1...
Trusted accounts for deployment: (none)
Trusted accounts for lookup: (none)
Using default execution policy of 'arn:aws:iam::aws:policy/AdministratorAccess'. Pass '--cloudformation-execution-policies' to customize.
CDKToolkit: creating CloudFormation changeset...
CDKToolkit | 0/12 | 5:44:25 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | CDKToolkit User Initiated
CDKToolkit | 0/12 | 5:44:31 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | CDKToolkit User Initiated
CDKToolkit | 0/12 | 5:44:36 PM | CREATE_IN_PROGRESS | AWS::SSM::Parameter | CdkBootstrapVersion
CDKToolkit | 0/12 | 5:44:36 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | FilePublishingRole
CDKToolkit | 0/12 | 5:44:37 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | CloudFormationExecutionRole
CDKToolkit | 0/12 | 5:44:37 PM | CREATE_IN_PROGRESS | AWS::ECR::Repository | ContainerAssetsRepository
CDKToolkit | 0/12 | 5:44:37 PM | CREATE_IN_PROGRESS | AWS::S3::Bucket | StagingBucket
CDKToolkit | 0/12 | 5:44:37 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | LookupRole
CDKToolkit | 0/12 | 5:44:37 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | ImagePublishingRole
CDKToolkit | 0/12 | 5:44:38 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | CloudFormationExecutionRole Resource creation Initiated
CDKToolkit | 0/12 | 5:44:38 PM | CREATE_IN_PROGRESS | AWS::SSM::Parameter | CdkBootstrapVersion Resource creation Initiated
CDKToolkit | 0/12 | 5:44:38 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | ImagePublishingRole Resource creation Initiated
CDKToolkit | 0/12 | 5:44:38 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | FilePublishingRole Resource creation Initiated
CDKToolkit | 0/12 | 5:44:38 PM | CREATE_IN_PROGRESS | AWS::S3::Bucket | StagingBucket Resource creation Initiated
CDKToolkit | 0/12 | 5:44:38 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | LookupRole Resource creation Initiated
CDKToolkit | 0/12 | 5:44:38 PM | CREATE_IN_PROGRESS | AWS::ECR::Repository | ContainerAssetsRepository Resource creation Initiated
CDKToolkit | 1/12 | 5:44:39 PM | CREATE_COMPLETE | AWS::SSM::Parameter | CdkBootstrapVersion
CDKToolkit | 2/12 | 5:44:39 PM | CREATE_COMPLETE | AWS::ECR::Repository | ContainerAssetsRepository
CDKToolkit | 3/12 | 5:45:00 PM | CREATE_COMPLETE | AWS::S3::Bucket | StagingBucket
CDKToolkit | 3/12 | 5:45:03 PM | CREATE_IN_PROGRESS | AWS::S3::BucketPolicy | StagingBucketPolicy
CDKToolkit | 3/12 | 5:45:04 PM | CREATE_IN_PROGRESS | AWS::S3::BucketPolicy | StagingBucketPolicy Resource creation Initiated
CDKToolkit | 4/12 | 5:45:05 PM | CREATE_COMPLETE | AWS::S3::BucketPolicy | StagingBucketPolicy
CDKToolkit | 5/12 | 5:45:07 PM | CREATE_COMPLETE | AWS::IAM::Role | ImagePublishingRole
CDKToolkit | 6/12 | 5:45:07 PM | CREATE_COMPLETE | AWS::IAM::Role | FilePublishingRole
CDKToolkit | 7/12 | 5:45:07 PM | CREATE_COMPLETE | AWS::IAM::Role | CloudFormationExecutionRole
CDKToolkit | 8/12 | 5:45:09 PM | CREATE_COMPLETE | AWS::IAM::Role | LookupRole
CDKToolkit | 8/12 | 5:45:10 PM | CREATE_IN_PROGRESS | AWS::IAM::Policy | FilePublishingRoleDefaultPolicy
CDKToolkit | 8/12 | 5:45:10 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | DeploymentActionRole
CDKToolkit | 8/12 | 5:45:11 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | DeploymentActionRole Resource creation Initiated
CDKToolkit | 8/12 | 5:45:12 PM | CREATE_IN_PROGRESS | AWS::IAM::Policy | FilePublishingRoleDefaultPolicy Resource creation Initiated
CDKToolkit | 8/12 | 5:45:26 PM | CREATE_IN_PROGRESS | AWS::IAM::Policy | ImagePublishingRoleDefaultPolicy
CDKToolkit | 8/12 | 5:45:27 PM | CREATE_IN_PROGRESS | AWS::IAM::Policy | ImagePublishingRoleDefaultPolicy Resource creation Initiated
CDKToolkit | 9/12 | 5:45:40 PM | CREATE_COMPLETE | AWS::IAM::Policy | FilePublishingRoleDefaultPolicy
CDKToolkit | 10/12 | 5:45:42 PM | CREATE_COMPLETE | AWS::IAM::Role | DeploymentActionRole
CDKToolkit | 11/12 | 5:45:56 PM | CREATE_COMPLETE | AWS::IAM::Policy | ImagePublishingRoleDefaultPolicy
CDKToolkit | 12/12 | 5:45:58 PM | CREATE_COMPLETE | AWS::CloudFormation::Stack | CDKToolkit
Environment aws://240724612589/ap-northeast-1 bootstrapped.
Deploy:
cdk deploy
Kết quả:
Synthesis time: 15.87s
DemoCdkStack: deploying...
[0%] start: Publishing 1e696634082569459c276ce1bd276a090623f063fb0b01e8600666699fca1335:current_account-current_region
[100%] success: Published 1e696634082569459c276ce1bd276a090623f063fb0b01e8600666699fca1335:current_account-current_region
DemoCdkStack: creating CloudFormation changeset...
DemoCdkStack | 0/3 | 5:47:23 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | DemoCdkStack User Initiated
DemoCdkStack | 0/3 | 5:47:29 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | DemoCdkStack User Initiated
DemoCdkStack | 0/3 | 5:47:33 PM | CREATE_IN_PROGRESS | AWS::S3::Bucket | MyFirstBucket (MyFirstBucketB8884501)
DemoCdkStack | 0/3 | 5:47:34 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata)
DemoCdkStack | 0/3 | 5:47:35 PM | CREATE_IN_PROGRESS | AWS::S3::Bucket | MyFirstBucket (MyFirstBucketB8884501) Resource creation Initiated
DemoCdkStack | 0/3 | 5:47:35 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated
DemoCdkStack | 1/3 | 5:47:35 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata)
DemoCdkStack | 2/3 | 5:47:56 PM | CREATE_COMPLETE | AWS::S3::Bucket | MyFirstBucket (MyFirstBucketB8884501)
DemoCdkStack | 3/3 | 5:47:57 PM | CREATE_COMPLETE | AWS::CloudFormation::Stack | DemoCdkStack
DemoCdkStack
Deployment time: 44.35s
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:240724612589:stack/DemoCdkStack/fe1131d0-0ff4-11ed-a195-0e293aa6eda3
Total time: 60.23s
Thực hiện thay đổi stack:
thay đổi từ:
bucket = s3.Bucket(self, "MyFirstBucket", versioned=True)
thành:
bucket = s3.Bucket(self, "MyFirstBucket",
versioned=True,
removal_policy=cdk.RemovalPolicy.DESTROY,
auto_delete_objects=True)
Diff thay đổi:
cdk diff
Kết quả như sau:
Stack DemoCdkStack
IAM Statement Changes
┌───┬───────────────────────────────────────────────────────────────┬────────┬───────────────────────────────────────┬───────────────────────────────────────────────────────────────────┬───────────┐
│ │ Resource │ Effect │ Action │ Principal │ Condition │
├───┼───────────────────────────────────────────────────────────────┼────────┼───────────────────────────────────────┼───────────────────────────────────────────────────────────────────┼───────────┤
│ + │ ${Custom::S3AutoDeleteObjectsCustomResourceProvider/Role.Arn} │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws.com │ │
├───┼───────────────────────────────────────────────────────────────┼────────┼───────────────────────────────────────┼───────────────────────────────────────────────────────────────────┼───────────┤
│ + │ ${MyFirstBucket.Arn} │ Allow │ s3:DeleteObject* │ AWS:${Custom::S3AutoDeleteObjectsCustomResourceProvider/Role.Arn} │ │
│ │ ${MyFirstBucket.Arn}/* │ │ s3:GetBucket* │ │ │
│ │ │ │ s3:List* │ │ │
└───┴───────────────────────────────────────────────────────────────┴────────┴───────────────────────────────────────┴───────────────────────────────────────────────────────────────────┴───────────┘
IAM Policy Changes
┌───┬───────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────┐
│ │ Resource │ Managed Policy ARN │
├───┼───────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────┤
│ + │ ${Custom::S3AutoDeleteObjectsCustomResourceProvider/Role} │ {"Fn::Sub":"arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"} │
└───┴───────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See <https://github.com/aws/aws-cdk/issues/1299>)
Resources
[+] AWS::S3::BucketPolicy MyFirstBucket/Policy MyFirstBucketPolicy3243DEFD
[+] Custom::S3AutoDeleteObjects MyFirstBucket/AutoDeleteObjectsCustomResource MyFirstBucketAutoDeleteObjectsCustomResourceC52FCF6E
[+] AWS::IAM::Role Custom::S3AutoDeleteObjectsCustomResourceProvider/Role CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092
[+] AWS::Lambda::Function Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F
[~] AWS::S3::Bucket MyFirstBucket MyFirstBucketB8884501
├─ [+] Tags
│ └─ [{"Key":"aws-cdk:auto-delete-objects","Value":"true"}]
├─ [~] DeletionPolicy
│ ├─ [-] Retain
│ └─ [+] Delete
└─ [~] UpdateReplacePolicy
├─ [-] Retain
└─ [+] Delete
Để thực hiện thay đổi thì chạy lại lệnh deploy
cdk deploy
Kết quả như sau:
Synthesis time: 16.4s
This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:
IAM Statement Changes
┌───┬───────────────────────────────────────────────────────────────┬────────┬───────────────────────────────────────┬───────────────────────────────────────────────────────────────────┬───────────┐
│ │ Resource │ Effect │ Action │ Principal │ Condition │
├───┼───────────────────────────────────────────────────────────────┼────────┼───────────────────────────────────────┼───────────────────────────────────────────────────────────────────┼───────────┤
│ + │ ${Custom::S3AutoDeleteObjectsCustomResourceProvider/Role.Arn} │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws.com │ │
├───┼───────────────────────────────────────────────────────────────┼────────┼───────────────────────────────────────┼───────────────────────────────────────────────────────────────────┼───────────┤
│ + │ ${MyFirstBucket.Arn} │ Allow │ s3:DeleteObject* │ AWS:${Custom::S3AutoDeleteObjectsCustomResourceProvider/Role.Arn} │ │
│ │ ${MyFirstBucket.Arn}/* │ │ s3:GetBucket* │ │ │
│ │ │ │ s3:List* │ │ │
└───┴───────────────────────────────────────────────────────────────┴────────┴───────────────────────────────────────┴───────────────────────────────────────────────────────────────────┴───────────┘
IAM Policy Changes
┌───┬───────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────┐
│ │ Resource │ Managed Policy ARN │
├───┼───────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────┤
│ + │ ${Custom::S3AutoDeleteObjectsCustomResourceProvider/Role} │ {"Fn::Sub":"arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"} │
└───┴───────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See <https://github.com/aws/aws-cdk/issues/1299>)
Do you wish to deploy these changes (y/n)? yes
DemoCdkStack: deploying...
[0%] start: Publishing ac9d3642b3e0626d3a6d8c4f5f56507a478c329febdf1dcfbbf7c7db9812cd30:current_account-current_region
[0%] start: Publishing cd710b04e8b395151576fa01974908b918c2c021c1f9f929550744a5ae3b247b:current_account-current_region
[50%] success: Published cd710b04e8b395151576fa01974908b918c2c021c1f9f929550744a5ae3b247b:current_account-current_region
[100%] success: Published ac9d3642b3e0626d3a6d8c4f5f56507a478c329febdf1dcfbbf7c7db9812cd30:current_account-current_region
DemoCdkStack: creating CloudFormation changeset...
DemoCdkStack | 0/8 | 5:53:08 PM | UPDATE_IN_PROGRESS | AWS::CloudFormation::Stack | DemoCdkStack User Initiated
DemoCdkStack | 0/8 | 5:53:13 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | Custom::S3AutoDeleteObjectsCustomResourceProvider/Role (CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092)
DemoCdkStack | 0/8 | 5:53:13 PM | UPDATE_IN_PROGRESS | AWS::S3::Bucket | MyFirstBucket (MyFirstBucketB8884501)
DemoCdkStack | 0/8 | 5:53:13 PM | UPDATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata)
DemoCdkStack | 0/8 | 5:53:13 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | Custom::S3AutoDeleteObjectsCustomResourceProvider/Role (CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092) Resource creation Initiated
DemoCdkStack | 1/8 | 5:53:15 PM | UPDATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata)
DemoCdkStack | 2/8 | 5:53:33 PM | UPDATE_COMPLETE | AWS::S3::Bucket | MyFirstBucket (MyFirstBucketB8884501)
DemoCdkStack | 3/8 | 5:53:42 PM | CREATE_COMPLETE | AWS::IAM::Role | Custom::S3AutoDeleteObjectsCustomResourceProvider/Role (CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092)
DemoCdkStack | 3/8 | 5:53:44 PM | CREATE_IN_PROGRESS | AWS::Lambda::Function | Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler (CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F)
DemoCdkStack | 3/8 | 5:53:45 PM | CREATE_IN_PROGRESS | AWS::S3::BucketPolicy | MyFirstBucket/Policy (MyFirstBucketPolicy3243DEFD)
DemoCdkStack | 3/8 | 5:53:46 PM | CREATE_IN_PROGRESS | AWS::S3::BucketPolicy | MyFirstBucket/Policy (MyFirstBucketPolicy3243DEFD) Resource creation Initiated
DemoCdkStack | 4/8 | 5:53:46 PM | CREATE_COMPLETE | AWS::S3::BucketPolicy | MyFirstBucket/Policy (MyFirstBucketPolicy3243DEFD)
DemoCdkStack | 4/8 | 5:53:47 PM | CREATE_IN_PROGRESS | AWS::Lambda::Function | Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler (CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F) Resource creation Initiated
DemoCdkStack | 5/8 | 5:53:53 PM | CREATE_COMPLETE | AWS::Lambda::Function | Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler (CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F)
DemoCdkStack | 5/8 | 5:53:55 PM | CREATE_IN_PROGRESS | Custom::S3AutoDeleteObjects | MyFirstBucket/AutoDeleteObjectsCustomResource/Default (MyFirstBucketAutoDeleteObjectsCustomResourceC52FCF6E)
DemoCdkStack | 5/8 | 5:54:02 PM | CREATE_IN_PROGRESS | Custom::S3AutoDeleteObjects | MyFirstBucket/AutoDeleteObjectsCustomResource/Default (MyFirstBucketAutoDeleteObjectsCustomResourceC52FCF6E) Resource creation Initiated
DemoCdkStack | 6/8 | 5:54:02 PM | CREATE_COMPLETE | Custom::S3AutoDeleteObjects | MyFirstBucket/AutoDeleteObjectsCustomResource/Default (MyFirstBucketAutoDeleteObjectsCustomResourceC52FCF6E)
DemoCdkStack | 7/8 | 5:54:03 PM | UPDATE_COMPLETE_CLEA | AWS::CloudFormation::Stack | DemoCdkStack
DemoCdkStack | 8/8 | 5:54:04 PM | UPDATE_COMPLETE | AWS::CloudFormation::Stack | DemoCdkStack
DemoCdkStack
Deployment time: 74.22s
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:240724612589:stack/DemoCdkStack/fe1131d0-0ff4-11ed-a195-0e293aa6eda3
Total time: 90.62s
Destroy:
cdk destroy
Kết quả:
Are you sure you want to delete: DemoCdkStack (y/n)? y
DemoCdkStack: destroying...
DemoCdkStack | 0 | 5:57:40 PM | DELETE_IN_PROGRESS | AWS::CloudFormation::Stack | DemoCdkStack User Initiated
DemoCdkStack | 0 | 5:57:43 PM | DELETE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata)
DemoCdkStack | 0 | 5:57:43 PM | DELETE_IN_PROGRESS | Custom::S3AutoDeleteObjects | MyFirstBucket/AutoDeleteObjectsCustomResource/Default (MyFirstBucketAutoDeleteObjectsCustomResourceC52FCF6E)
DemoCdkStack | 1 | 5:57:44 PM | DELETE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata)
DemoCdkStack | 2 | 5:57:45 PM | DELETE_COMPLETE | Custom::S3AutoDeleteObjects | MyFirstBucket/AutoDeleteObjectsCustomResource/Default (MyFirstBucketAutoDeleteObjectsCustomResourceC52FCF6E)
DemoCdkStack | 2 | 5:57:46 PM | DELETE_IN_PROGRESS | AWS::Lambda::Function | Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler (CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F)
DemoCdkStack | 2 | 5:57:46 PM | DELETE_IN_PROGRESS | AWS::S3::BucketPolicy | MyFirstBucket/Policy (MyFirstBucketPolicy3243DEFD)
DemoCdkStack | 3 | 5:57:47 PM | DELETE_COMPLETE | AWS::S3::BucketPolicy | MyFirstBucket/Policy (MyFirstBucketPolicy3243DEFD)
DemoCdkStack | 4 | 5:57:53 PM | DELETE_COMPLETE | AWS::Lambda::Function | Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler (CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F)
DemoCdkStack | 4 | 5:57:53 PM | DELETE_IN_PROGRESS | AWS::IAM::Role | Custom::S3AutoDeleteObjectsCustomResourceProvider/Role (CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092)
DemoCdkStack | 4 | 5:57:53 PM | DELETE_IN_PROGRESS | AWS::S3::Bucket | MyFirstBucket (MyFirstBucketB8884501)
DemoCdkStack: destroyed
Note: để test construct: https://docs.aws.amazon.com/cdk/v2/guide/testing.html
\======
Workshop: https://cdkworkshop.com
Quickstart SDK: https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html