AWS CLI で CloudFormation の change set を作って実行するまで

チラ裏. AWS CLI で CloudFormation の change set の作成、実行、または削除をする手順。

## 説明しないこと

* CloudFormation の基本概念
* Stack の作り方
* CloudFormation テンプレートの書き方

## バリデーション

CloudFormation テンプレートを書いたあと、まずは validation すると便利。

```
$ aws cloudformation validate-template --template-body=file://$PWD/cfn.yml
```

python モジュールに `cfn-lint` というものもあるのでそれも使うとまた便利

```
$ pip install cfn-lint
$ cfn-lint cnf.yml
```

## ChangeSet の作成

仮にスタック名、および ChangetSet 名を以下のように定義したものとする

```
STACK=stack01
CHANGE_SET=${STACK}-$(date +%Y%m%d%H%M%S) # 例 stack01-20190114152714
```

ChangeSet の作成

IAMユーザを作るような CloudFormation テンプレートの場合、`--capabilities` への指定が必要。
パスワードのような値を CloudFormation テンプレートに書きたくない場合、`--parameters` で値を渡す。

```
$ aws cloudformation create-change-set --stack-name ${STACK} --change-set-name=${CHANGE_SET} \
  --template-body=file://$PWD/cfn.yml --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM \
  --parameters ParameterKey=RDSMasterUserPassword,ParameterValue=xxxxx,UsePreviousValue=false
{
    "Id": "arn:aws:cloudformation:ap-northeast-1:xxxxxx:changeSet/stack01-20190114152714/xxx-xxx-xxx-xxx",
    "StackId": "arn:aws:cloudformation:ap-northeast-1:xxxxx:stack/stack01/xxx-xxx-xxx-xxx"
}
```

## ChangeSet の確認

一覧

```
$ aws cloudformation list-change-sets --stack-name ${STACK}
{
    "Summaries": [
        {
            "StackId": "arn:aws:cloudformation:ap-northeast-1:xxxxx:stack/stack01/xxx-xxx-xxx-xxx",
            "StackName": "stack01",
            "ChangeSetId": "arn:aws:cloudformation:ap-northeast-1:xxxxx:changeSet/stack01-20190114152714/xxx-xxx-xxx-xxx",
            "ChangeSetName": "stack01-20190114152714",
            "ExecutionStatus": "AVAILABLE",
            "Status": "CREATE_COMPLETE",
            "CreationTime": "2019-01-14T06:27:14.447Z"
        }
    ]
}
```

変更の確認 (以下は RDS のパスワードが変更された例)

```
$ aws cloudformation describe-change-set --stack-name ${STACK} --change-set-name ${CHANGE_SET}
{
    "ChangeSetName": "stack01-20190114152714",
    "ChangeSetId": "arn:aws:cloudformation:ap-northeast-1:xxxxx:changeSet/stack01-20190114152714/xxx-xxx-xxx-xxx",
    "StackId": "arn:aws:cloudformation:ap-northeast-1:xxxxx:stack/stack01/xxx-xxx-xxx-xx",
    "StackName": "stack01",
    "Parameters": [
    ],
    "CreationTime": "2019-01-14T06:27:14.447Z",
    "ExecutionStatus": "AVAILABLE",
    "Status": "CREATE_COMPLETE",
    "NotificationARNs": [],
    "RollbackConfiguration": {
        "RollbackTriggers": []
    },
    "Capabilities": [
        "CAPABILITY_IAM",
        "CAPABILITY_NAMED_IAM"
    ],
    "Changes": [
        {
            "Type": "Resource",
            "ResourceChange": {
                "Action": "Modify",
                "LogicalResourceId": "RDSDBCluster",
                "PhysicalResourceId": "stack01-rdsdbclusterg-icyaselsdyot",
                "ResourceType": "AWS::RDS::DBCluster",
                "Replacement": "False",
                "Scope": [
                    "Properties"
                ],
                "Details": [
                    {
                        "Target": {
                            "Attribute": "Properties",
                            "Name": "MasterUserPassword",
                            "RequiresRecreation": "Never"
                        },
                        "Evaluation": "Dynamic",
                        "ChangeSource": "DirectModification"
                    },
                    {
                        "Target": {
                            "Attribute": "Properties",
                            "Name": "MasterUserPassword",
                            "RequiresRecreation": "Never"
                        },
                        "Evaluation": "Static",
                        "ChangeSource": "ParameterReference",
                        "CausingEntity": "RDSMasterUserPassword"
                    }
                ]
            }
        }
    ]
}
```

## ChangeSet の実行、または削除

実行

```
$ aws cloudformation execute-change-set --stack-name ${STACK} --change-set-name ${CHANGE_SET}
```

または削除

```
$ aws cloudformation delete-change-set --stack-name ${STACK} --change-set-name ${CHANGE_SET}
```

一覧表示で確認

```
$ aws cloudformation list-change-sets --stack-name ${STACK}
{
    "Summaries": []
}
```