CloudFrontキャッシュを削除するシェルスクリプトを書いてみた。


**AWS CLI** を使えば、 **AWS Console** へアクセスすることなく
CloudFrontキャッシュの削除も行えます。

削除対象が多い場合はその対象を記したjsonファイルを用意して、
**AWS CLI** からそのjsonファイルを利用して **CloudFrontキャッシュ** の削除を行うのですが、
毎回書き換えが必要な項目がjsonファイル内にあります。

手作業で毎回書き換えてましたがさすがに面倒になってきたので
シェルスクリプトを書きました。

**Mac**ユーザーなので **Mac**での作業想定で書きます。

## 概要
**AWS Console**アクセスすれば、
**Cloud Front**のキャッシュ手動削除はできるのですが、
面倒なので **AWS CLI** を使ってシェルスクリプトから
削除できるようにしたものです。

## 必要な準備
### AWS CLI のローカルインストール
詳しいインストール手順は[こちら](http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html)

**macOS**の場合は **Python 2.6.3** 以降が必要なので

```bash
$ curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
$ sudo python get-pip.py
```

で pip をインストールしてから

```bash
$ sudo pip install awscli
```

して

```bash
$ aws help
```

でヘルプが出ればOKです。

### AWS CLI の設定
CLI利用するのに専用の configure 設定を一度行う必要があります。
これも上記URLに設定方法があるのですが、

* AWS Access Key ID（以下 AKID）
* AWS Secret Access Key（以下 SAK）
* region name
* output format

の4つが必要です。
この設定プロファイルは

```bash
~/.aws/credentials # AKID と SAK
```

と

```bash
~/.aws/config # region name と output format
```

に入ります。

プロファイル名を付ければ複数のプロファイルを格納できます。
この2ファイルは1回設定しちゃえばあとはいじらなくてOKです！

↓こんな感じ

```bash:~/.aws/credentials
[profile hogehoge]
aws_access_key_id=****************      # AKID
aws_secret_access_key=****************  # SAK
```

```bash:~/.aws/config
[profile hogehoge]
region=ap-northeast-1                   # region name
output=json                             # output format
```

### invalidation-batch の準備
削除対象を指定するバッチファイル（json）のベースを作成します。
↓こんな感じです。

```bash:invbatch_base.json
{
	"Paths"  : {
		"Quantity": 5,
		"Items"  : [
			"/",
			"/sp/",
			"/css/main.css",
			"/js/libs.js",
			"/js/main.js"
		]
	},
	"CallerReference": "YYYYMMDD-HHNNSS"
}
```

なぜベースかというと CallerReference が仮だからです。
ここはユニークな文字列であればなんでもアリです。
被りづらくするために実行時の年月日時分秒にしてます。

`Items`に削除対象を **DocumentRoot** からのパスで指定します。
ワイルドカード（\*）も使えます。
この指定方法は **AWS Console** での指定方法と一緒です。

#### 注意点
`CallerReference` は毎回ユニークな値を入れておかなければいけません。
これが意外と面倒なのでこの部分の書き換え込みでシェルスクリプト化しました。

> Note:
> 削除対象が変われば `Items` も `Quantity` も変えなきゃです、、

このファイルは削除対象の変更がなければ、1回設定しちゃえばあとはいじらなくてOKです！

### キャッシュ削除用シェルスクリプト設定
シェルスクリプトに実行権限`$ chmod a+x ***`を与えておいて、実行します。
中身は↓こんな感じです。

```bash:clear_cache.sh
#!/bin/bash

# 設定用変数
dist_id="*******************"   # AWS CloudFrontのDistribution ID
batch_json_base="invbatch_base.json"      # invalidation-batchベースファイル名
batch_json="invbatch.json"      # invalidation-batchファイル名
profile="hogehoge"              # プロファイル名

# 実行部分
time_stamp=`date +%Y%m%d%k%M%S`
echo "Move directory ..."
cd `dirname $0`
echo "Invbalidation-batch json update"
# invalidation-batchベースファイルの
# CallerReferenceにバッチ実行時間を設定して
# invalidation-batchファイルに上書き保存
echo `less $batch_json_base | jq '.CallerReference |= "'$profile'_'$time_stamp'"'` > $batch_json
echo "CloudFront cache clear ..."
# AWS Cli でCloudFrontキャッシュ削除実行
res=`aws cloudfront create-invalidation --distribution-id $dist_id --invalidation-batch "file://$batch_json" --profile $profile`
echo -e "$res"
id=`echo $res | jq -r '{ id: .Invalidation.Id }'`
# 発行された Invalidation ID を表示
echo "$id"
```

※ jq使ってjsonの書き換えを行なっているのでjqのインストールが必要です。

> jqのインストール方法
> https://stedolan.github.io/jq/download/


コード内のコメントにありますが、

* **AWSのCloudFront**の**Distribution ID**
* **nvalidation-batch ベースファイル名**
* **nvalidation-batch ファイル名**
* **プロファイル名**

が必要です。

このファイルは1回設定しちゃえばあとはいじらなくてOKです！

## キャッシュ削除シェルスクリプト実行

```bash
$ ./clear_cache_shupure.sh
Move directory ...
Invbalidation-batch json update
CloudFront cache clear ...
{ "Invalidation": { "Status": "InProgress", "InvalidationBatch": { "Paths": { "Items": [ "/images/girls/*.png", "/", "/images/sakabar/*.png", "/images/events/*.jpg", "/sp/gekijo/", "/sp/sakabar/", "/gekijo/", "/sp/", "/images/girls/0924.png", "/css/main.css", "/sakabar/" ], "Quantity": 11 }, "CallerReference": "shupure_1506515279" }, "Id": "I2N11BY0PH6UI9", "CreateTime": "2017-09-27T12:28:03.125Z" }, "Location": "https://cloudfront.amazonaws.com/2017-03-25/distribution/E1JZGHRP8PFLBD/invalidation/I2N11BY0PH6UI9" }
CURL check ...
 % Total  % Received % Xferd Average Speed  Time  Time   Time Current
                 Dload Upload  Total  Spent  Left Speed
 0 50672  0   0  0   0   0   0 --:--:-- --:--:-- --:--:--   0
 X-Amz-Cf-Id: eHRIZxCp2k5-aecSw1ABCI-OB7aPtK_EEs4y0elK8bucqB6e1B-zrA==
```

CloudFront キャッシュ削除のレスポンスjsonが改行されてないのが気持ち悪いですが、
**InProgress**が表示されていればキャッシュ削除スタートしてます。

キャッシュ削除されてるかは`curl`などでレスポンスヘッダを確認してください。

```bash
$ curl -I http://hogehoge.jp
```