###### tags: `AWS` `CDK`
# AWS CDK 學習
## 前置作業
1. 確認 NodeJS
```
$ node -v
v14.8.0
```
2. 確認 NPM
```
$ npm -v
6.14.8
```
3. 安裝AWS CDK
```
npm i -g aws-cdk
```
4. 安裝AWS CLI
- 使用 brew 安裝
```
$ brew install awscli
```
- AWS configure 設定
```
$ aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-west-2
Default output format [None]:
```
5. 額外補充,如使用 profile 的方式設定 configure,可以帶以下指令,
```
$ aws configure --profile test
AWS Access Key ID [None]: 123456
AWS Secret Access Key [None]: 123456
Default region name [None]: us-east-1
Default output format [None]:
```
> 使用其他 CDK 指令如需帶到 profile 資料也可以這樣帶
## 相關指令介紹
### cdk init
```
cdk init 模版名稱(app|lib|sample-app) --language=使用的程式語言(csharp|fsharp|java|javascript|python|typescript)
```
```
$ cdk init --list
Available templates:
* app: Template for a CDK Application
└─ cdk init app --language=[csharp|fsharp|java|javascript|python|typescript]
* lib: Template for a CDK Construct Library
└─ cdk init lib --language=typescript
* sample-app: Example CDK Application with some constructs
└─ cdk init sample-app --language=[csharp|fsharp|java|javascript|python|typescript]
```
### cdk list
列出所有的 stack list,也可使用縮寫指令`cdk ls`
```
$ cdk list
HelloCdkStack
```
### cdk synthesize
查看目前程式產生的 CloudFormation,短指令是 `cdk synth`
```
$ cdk synth HelloCdkStack
Resources:
HelloCdkQueueB56C77B9:
Type: AWS::SQS::Queue
Properties:
VisibilityTimeout: 300
Metadata:
aws:cdk:path: HelloCdkStack/HelloCdkQueue/Resource
HelloCdkQueuePolicy027FC30A:
Type: AWS::SQS::QueuePolicy
Properties:
PolicyDocument:
Statement:
- Action: sqs:SendMessage
Condition:
ArnEquals:
aws:SourceArn:
Ref: HelloCdkTopic1F583424
Effect: Allow
Principal:
Service: sns.amazonaws.com
Resource:
Fn::GetAtt:
- HelloCdkQueueB56C77B9
- Arn
Version: "2012-10-17"
Queues:
- Ref: HelloCdkQueueB56C77B9
Metadata:
aws:cdk:path: HelloCdkStack/HelloCdkQueue/Policy/Resource
HelloCdkQueueHelloCdkStackHelloCdkTopic850E0FBD36A066B9:
Type: AWS::SNS::Subscription
Properties:
Protocol: sqs
TopicArn:
Ref: HelloCdkTopic1F583424
Endpoint:
Fn::GetAtt:
- HelloCdkQueueB56C77B9
- Arn
Metadata:
aws:cdk:path: HelloCdkStack/HelloCdkQueue/HelloCdkStackHelloCdkTopic850E0FBD/Resource
HelloCdkTopic1F583424:
Type: AWS::SNS::Topic
Metadata:
aws:cdk:path: HelloCdkStack/HelloCdkTopic/Resource
CDKMetadata:
Type: AWS::CDK::Metadata
Properties:
Modules: aws-cdk=1.63.0,@aws-cdk/aws-cloudwatch=1.63.0,@aws-cdk/aws-iam=1.63.0,@aws-cdk/aws-kms=1.63.0,@aws-cdk/aws-sns=1.63.0,@aws-cdk/aws-sns-subscriptions=1.63.0,@aws-cdk/aws-sqs=1.63.0,@aws-cdk/cloud-assembly-schema=1.63.0,@aws-cdk/core=1.63.0,@aws-cdk/cx-api=1.63.0,@aws-cdk/region-info=1.63.0,jsii-runtime=node.js/v12.16.3
Condition: CDKMetadataAvailable
Conditions:
CDKMetadataAvailable:
Fn::Or:
- Fn::Or:
- 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::Equals:
- Ref: AWS::Region
- eu-central-1
- Fn::Or:
- Fn::Equals:
- Ref: AWS::Region
- eu-north-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::Equals:
- Ref: AWS::Region
- us-west-1
- Fn::Equals:
- Ref: AWS::Region
- us-west-2
```
### cdk bootstrap
第一次要執行 cdk 部署前要執行的指令,它會在 S3 開啟一個 bucket 裡面會放有需要執行 CloudFormation 必要的東西
```
$ cdk bootstrap
⏳ Bootstrapping environment aws://888888888888/us-west-2...
✅ Environment aws://888888888888/us-west-2 bootstrapped (no changes).
```
### cdk deploy
部署 CDK 腳本指令
```
$ cdk deploy
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 │
├───┼───────────────────┼────────┼───────────────────┼───────────────────┼─────────────────────┤
│ + │ ${HelloCdkQueue.A │ Allow │ sqs:SendMessage │ Service:sns.amazo │ "ArnEquals": { │
│ │ rn} │ │ │ naws.com │ "aws:SourceArn": │
│ │ │ │ │ │ "${HelloCdkTopic}" │
│ │ │ │ │ │ } │
└───┴───────────────────┴────────┴───────────────────┴───────────────────┴─────────────────────┘
(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)?
```
### cdk destroy
移除 CloudFormation 部屬上去的東西
```
$ cdk destroy
Are you sure you want to delete: HelloCdkStack (y/n)? y
HelloCdkStack: destroying...
✅ HelloCdkStack: destroyed
```
### cdk diff
比較當前版本與線上版本的差異
```
$ cdk diff
IAM Statement Changes
┌───┬───────────────────┬────────┬───────────────────┬───────────────────┬─────────────────────┐
│ │ Resource │ Effect │ Action │ Principal │ Condition │
├───┼───────────────────┼────────┼───────────────────┼───────────────────┼─────────────────────┤
│ + │ ${HelloCdkQueue.A │ Allow │ sqs:SendMessage │ Service:sns.amazo │ "ArnEquals": { │
│ │ rn} │ │ │ naws.com │ "aws:SourceArn": │
│ │ │ │ │ │ "${HelloCdkTopic}" │
│ │ │ │ │ │ } │
└───┴───────────────────┴────────┴───────────────────┴───────────────────┴─────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)
Conditions
[+] Condition CDKMetadataAvailable: {"Fn::Or":[{"Fn::Or":[{"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::Equals":[{"Ref":"AWS::Region"},"eu-central-1"]}]},{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-north-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::Equals":[{"Ref":"AWS::Region"},"us-west-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-west-2"]}]}]}
Resources
[+] AWS::SQS::Queue HelloCdkQueue HelloCdkQueueB56C77B9
[+] AWS::SQS::QueuePolicy HelloCdkQueue/Policy HelloCdkQueuePolicy027FC30A
[+] AWS::SNS::Subscription HelloCdkQueue/HelloCdkStackHelloCdkTopic850E0FBD HelloCdkQueueHelloCdkStackHelloCdkTopic850E0FBD36A066B9
[+] AWS::SNS::Topic HelloCdkTopic HelloCdkTopic1F583424
```
### cdk docs
快速搜尋文件,它會幫我們開啟瀏覽器並且帶我們到 https://docs.aws.amazon.com/cdk/api/latest/

### cdk doctor
此指令會收集目前的 env 與 CDK 版本資訊
```
$ cdk doctor
ℹ️ CDK Version: 1.63.0 (build 7a68125)
ℹ️ AWS environment variables:
- AWS_STS_REGIONAL_ENDPOINTS = regional
- AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
- AWS_SDK_LOAD_CONFIG = 1
ℹ️ No CDK environment variables
```
## 資料夾檔案介紹
- lib/cdk-workshop-stack.ts:CDK 主要的程式位置
- bin/cdk-workshop.ts:主要的程式進入點預設會引用 lib/cdk-workshop-stack.ts
- package.json:npm 模組清單裡面定義了套件的版本與指令,例如:build、watch、test 與 cdk
- cdk.json:告訴 toolkit 如何執行 app
- tsconfig.json:typescript 設定檔
- .gitignore:告訴 git 應該要排除的文件
- .npmignore:告訴 npm 應該要排除的文件
- node_modules:nodejs 套件包執行完 npm install 後的文件都會安裝在此資料夾裡面
- test:CDK 測試的程式位置

## 學習過程遇到的問題與解決方法
1. npm安裝時相依問題
```
error message:
npm RESOLVE unable to resolve dependency tree ...
解決方法
於 npm i 後方加上 -f or --force 即可
ex:
npm i -f 欲安裝之套件名稱
```
2. 部屬時的lambda文件必須使用.js格式
## 參考資料
- [用 CDK 定義 AWS 架構 系列](https://ithelp.ithome.com.tw/users/20117701/ironman/3734)
- [AWS CDK 初探](https://azole.medium.com/aws-cdk-%E5%88%9D%E6%8E%A2-5b481d3970bd)