Hori Blog

フリーランスでバックエンドエンジニアとして活動している Ryota Hori のブログです。
最近はテック系記事より雑記ブログ気味。

CloudFrontのawscliでjson管理できる環境を整備した

CloudFront をマネジメントコンソールでぽちぽち管理するのつらい!!

ということで、awscli と jq を使用して json 管理できる環境を整備して GitHub に公開しました。

CloudFront Manager

個人使用のために作成したので、細かいアレコレはご容赦ください。レビューは大歓迎です。

以下、記事公開時点の README.md と同内容です。

コマンドによって json のプロパティ順が違うようなので、作業後は fetchall.sh でお掃除することを推奨。

CloudFront の設定は失敗するとサービスにとって致命傷となるので、使用は自己責任でお願いします。

下準備

依存ツール

cloudfront コマンドは preview 版なので有効にする

aws configure set preview.cloudfront true

(基礎知識)主要な aws コマンド

distribution 一覧取得

aws cloudfront list-distributions

distribution 個別取得

aws cloudfront get-distribution --id ${distributionId}

distribution 更新

aws cloudfront update-distribution --cli-input-json file://${jsonFileName}

update の対象 distributionId は json 内に記述されているのでコマンドで指定はしない

distribution 作成

aws cloudfront create-distribution --cli-input-json file://${jsonFileName}

ディレクトリ構成

backup/ # 更新時に旧jsonを退避 # gitignore対象
draft/  # 作成用の下書き置き場 # gitignore対象
json/   # cloudfrontから取得したjson置き場

backup ディレクトリは diff を取りやすくするため配置。git 管理なので本来は不要ですが、実行時の保険として。

作成はマネジメントコンソールでポチって作るか、後述のコマンドで既存からコピーするのがいいかと思います。

更新は json ディレクトリ内のファイルを更新して cloudfront に反映、返ってきた result で json を上書きします。

json ディレクトリを GitHub に push すると構成が見えてしまうので、必要に応じて gitignore してください(pull-request でレビューできなくなりますが)。

スクリプト

vim の quickrun で叩きやすくするため、dirname などでのパス解決はしていないです。 cloudfront-manager/ ディレクトリ直下で実行してください。

fetchall.sh

初期化用。cloudfront から Enabled 状態の distributions を取ってきて json ディレクトリに反映。

削除済み distribution の json 削除は行わないので、削除も必要なら json ディレクトリを削除後に実行してください。

update.sh

./update.sh ${targetCName}

更新用。get-distribution の json と update-distribution の形式は若干違うので、jq コマンドで整形したものを入力へ。

結果を元に json ディレクトリ内の該当 json を上書きします。

createDraft.sh

./createDraft.sh ${targetName} [${srcJsonFile}]

新規作成用に下書きを draft/ 下に作成。 srcJsonFile を指定すればコピーして create 用 Json に整形。指定がなければ skeleton 作成。

CallerReference の値はdate +%s コマンドでタイムスタンプを使用していますが、distribution 間で unique にする必要があるようなので必要に応じて調整。

create.sh

./create.sh ${targetName}

draft/ 下の下書きから新規作成。結果を json ディレクトリ内に保存。

Location プロパティは邪魔なので削除。

補足

スクリプトは基礎的なコマンドとして、for 文で実行するスクリプトを別途用意すると便利。

#!/bin/bash

set -eu

targets=(
"DISTRIBUTION_ID_1"
"DISTRIBUTION_ID_2"
)

customErrorResponses='
      {
        "Items": [
          {
            "ErrorCode": 400,
            "ResponsePagePath": "",
            "ResponseCode": "",
            "ErrorCachingMinTTL": 1
          }
        ],
        "Quantity": 1
      }
'

dir='json'

for (( i = 0; i < ${#targets[@]}; i++ )); do
  target=${targets[$i]}
  echo "target = $target"

  jsonPath="$dir/$target.json"

  if [ ! -e $jsonPath ]; then
    echo "json file not found [$jsonPath]"
    exit 1
  fi

  srcJson=`cat $jsonPath`

  echo $srcJson | jq ".Distribution.DistributionConfig.CustomErrorResponses=$customErrorResponses" > $jsonPath

  ./update.sh $target
done

みたいな。

TODO

  • distributionId 管理だと視認性が悪いので alias をつけたい。
    • cname がわかりやすいけど複数 cname を使用するときに困るので悩み中。
    • tag 機能もあるけど awscli 経由だと情報が取得できていなさそうなので様子見。

以上

ということで、一括で distribution の json を取得し、編集して更新をかけられる環境が構築できました。

json 管理にすることで差分のレビューもできるので、個人的には非常に捗っております。

CloudFront の設定をコマンドラインから更新する

CloudFront の設定をコマンドラインから作成する

の集大成でした。