0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS CloudFormation】CLIでのスタック操作まとめ

0
Posted at

はじめに

今回は、AWS CloudFormationテンプレートを使用した、CLIコマンドでのインフラ環境構築手順についてまとめてみました。

  1. 単一スタックの場合
  2. クロススタックの場合
  3. ネストスタックの場合

1. 単一スタックの場合

テンプレートおよび手動デプロイに関してはこちらの記事をご参照ください。

①スタックのデプロイ

aws cloudformation deployコマンドを使用します。
引数に「template-file」と「stack-name」の指定が必須となります。

その他にも複数のオプションを設定することが可能です。
例:
--no-execute-changeset: 変更セットだけ作成してデプロイせずに差分確認が可能
--capabilities: IAMリソース操作が含まれる場合に明示的に許可するために必要
--parameter-overrides: スタックテンプレートの入力パラメータを指定するために必要
--s3-bucket: 51,200バイトを超えるサイズのテンプレートをデプロイする場合には必要(超えない場合はそのままAPIで送信されるため、テンプレートファイル保存用のs3バケットは作成されない)

詳しくは公式ドキュメントをご参照ください。

zsh
aws cloudformation deploy \
  --template-file test.yaml \
  --stack-name test-stack \
  --profile project-a-dev
  • このdeployコマンドは、内部で変更セットを作成 → 適用までをセットで自動的に行います
  • スタックが存在しなければ新規作成、あれば更新を自動で判断して行います

※似たコマンドに、create-stackがありますが、こちらは単純に「スタックを作成する」コマンドであるため、更新の際は別コマンドupdate-stackが必要になり、使い分ける必要があります。
deployコマンドでの更新時は、update-stackが内部的に実行されています。
実務ではdeployコマンドのみに統一するのが推奨されています。

②スタックの更新

デプロイ同様、aws cloudformation deployコマンドを使用します。
もしくは、事前に

  1. --no-execute-changesetオプションで実行
  2. 作成された変更セットをaws cloudformation describe-change-setで差分を確認
  3. 問題なければaws cloudformation execute-change-setで反映

するとより安全です。
※Replacement(既存インスタンスの削除→置き換え)が発生するかどうかの確認は重要です

③スタックの削除

aws cloudformation delete-stackコマンドを使用します。
引数に「stack-name」の指定が必須となります。
スタック配下のリソースがすべて削除対象ですが、
・S3バケットが空でない
DeletionPolicy: Retainが設定されている
場合など、削除が失敗してしまうため注意が必要です。

また、削除は非同期(すぐ終わらない)のため、CI/CDやスクリプトを使用した自動構成の環境下では、確実に削除完了を待つためaws cloudformation delete-stackコマンドの使用後に続けてaws cloudformation wait stack-delete-completeコマンドを使用するのがおすすめです。

④手動で変更/削除してしまった場合

以下の手順で差分を確認することができます。

1. ドリフト検知を開始

zsh
aws cloudformation detect-stack-drift \
  --stack-name test-stack \
  --profile project-a-dev

するとドリフトIDが出力されます。

zsh
{
  "StackDriftDetectionId": "abc123-xxxx"
}

2. 検知完了まで待つ

先ほど取得したIDを使用して以下のコマンドを実行します。

zsh
aws cloudformation describe-stack-drift-detection-status \
  --stack-drift-detection-id abc123-xxxx \
  --profile project-a-dev

結果が表示されます。
・DETECTION_IN_PROGRESS:実行中
・DETECTION_COMPLETE:完了
・DETECTION_FAILED:失敗

3. 差分(ドリフト結果)を取得

DETECTION_COMPLETEになったら以下のコマンドを実行し、テンプレートと実際のAWS環境の差分を確認します。

zsh
aws cloudformation describe-stack-resource-drifts \
  --stack-name test-stack \
  --profile project-a-dev

4. テンプレートに合わせ修正

基本は再デプロイすることでテンプレートに合わせます(上書き/修正される)
ただし、CLIではテンプレート自体に変更がない場合、変更セットを作成することができません。
AWSコンソールではドリフト結果から変更セットを作成する機能が提供されているため、現状はそちらを使用することになりそうです。

※ドリフト検知対象外のリソースも存在します
※手動での修正対応が必要になるケースも存在します

2. クロススタックの場合

テンプレートおよび手動デプロイに関してはこちらの記事をご参照ください。

①スタックのデプロイ

単一スタックの場合と同様にデプロイしますが、順番はExportしている側→Importしている側の順にデプロイします。

②スタックの更新

単一スタックの場合と同様に更新しますが、スタック間の依存関係に注意が必要です。
例:Export値が更新されたのにImport値は更新されていない(古い値を参照)

③スタックの削除

単一スタックの場合と同様に削除しますが、順番はImportしている側→Exportしている側の順に削除します。

3. ネストスタックの場合

テンプレートおよび手動デプロイに関してはこちらの記事をご参照ください。

①スタックのデプロイ

ネストスタックのCLIデプロイでは、packageコマンドを使用します。
詳しくはこちらの記事をご参照ください。

root.ymlを以下のように書き換えます。

root.yml
AWSTemplateFormatVersion: "2010-09-09"
Description: Root Stack

Resources:
  NetworkStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: network.yaml

  AppStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: app.yaml
      Parameters:
        SubnetId: !GetAtt NetworkStack.Outputs.SubnetId
        SecurityGroupId: !GetAtt NetworkStack.Outputs.SecurityGroupId

以下のようなスクリプトを作成します。

deploy.sh
#!/bin/bash
set -euo pipefail

STACK_NAME="${1:-my-nested-stack}"
S3_BUCKET="${2}"
PROFILE="${3:-default}"
REGION=$(aws configure get region --profile "${PROFILE}")
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"

# テンプレート保存用s3の作成
aws s3api create-bucket \
  --bucket "${S3_BUCKET}" \
  --region "${REGION}" \
  --create-bucket-configuration LocationConstraint="${REGION}" \
  --profile "${PROFILE}"

# packageコマンドの実行
aws cloudformation package \
  --template-file "${SCRIPT_DIR}/root.yaml" \
  --s3-bucket "${S3_BUCKET}" \
  --output-template-file "${SCRIPT_DIR}/packaged.yaml" \
  --profile "${PROFILE}"

# 生成されたテンプレートの実行
aws cloudformation deploy \
  --template-file "${SCRIPT_DIR}/packaged.yaml" \
  --stack-name "${STACK_NAME}" \
  --profile "${PROFILE}"

スクリプトを実行します。

zsh
./deploy.sh <スタック名> <s3バケット名(世界で一意)> <awsプロファイル名>

②スタックの更新

単一スタックの場合と同様に更新します(root/親スタックが対象)

③スタックの削除

単一スタックの場合と同様に削除します(root/親スタックが対象)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?