AWS のコストをサクッと削減  ~  EBS 編 ~



AWS のコストをサクッと削減する方法を何回かに渡って書いて行きます。
まずは、EBS編です。

# 最初に結論
- EBSボリュームは gp3 を使おう。gp2よりの上位互換、コストも削減できることがほとんど。
- でも、gp3 誕生前から gp2 を使っていたり、EC2 インスタンス作成時のデフォルト設定が gp2 なせいで、あまり gp3 使われていないよね
- チェックスクリプトを使って、gp3 へ変更した場合のコスト削減効果をサクッとだそう
- 一気に変換できるなら、変換スクリプトを使って、一気に変換しちゃおう。サービス影響まったくないよ。一気にできない場合でも、1つずつ手作業で変換していこう。
- コスト削減効果は、塵も積もれば山となる！

# やっていること
- ボリュームタイプ gp2 と gp3 について知る
- gp2 の EBS を全部 gp3 に変換した場合のコスト削減幅を知る
- gp2 を一気に gp3 に変更する


# ボリュームタイプ gp2 と gp3 について知る
これは他の記事を見ていただいたほうが早いです
- https://dev.classmethod.jp/articles/ebs-gp3/
- https://dev.classmethod.jp/articles/ebs-volume-covert-gp2-to-gp3/

要は、誤解を恐れずに言うと、gp2 の上位互換が gp3 です。コスト的にも、パフォーマンス的にもほとんどの場合 gp3に軍配があがります。
しかも、gp2 から gp3 への変換は、オンラインで行うことができます。

### じゃあ、なんでみんな gp2 を使っているのか？
gp3 が上位互換にも関わらず、実態としては gp3 はあまり使われてはいないです。(統計は知らないので、個人の感覚です）
これは、別に裏があるのでなく、単純に **EC2 インスタンスを作成する際の、EBSストレージのデフォルトが gp2** だからです。

じゃあ、全部 gp3 に変えるとどうなるのーっというのがこの記事の趣旨です。



# gp2 の EBS を全部 gp3 に変換した場合のコスト削減幅を知るスクリプト

携わっている案件で調べる必要があったため、雑にスクリプト作ってみました。
使っているコマンドは、 ```aws ec2 describe-volumes``` だけです。


```shell:check_ebs_optimization.sh
#!/bin/sh

echo "Region,VolumeId,VolumeType,Size,State,ModifiedVolumeType,ModifiedIOPS,ModifiedThroughput,gp2Cost(Month),gp3Cost(Month),SaveCost(Month)"

regions=("ap-northeast-1" "ap-northeast-3")

for region in ${regions[@]}
do
    for vol in $(aws ec2 describe-volumes --filter "Name=volume-type,Values=gp2" --query "Volumes[*].VolumeId" --output text --region $region)
    do
        size=`aws ec2 describe-volumes --volume-ids  $vol --query "Volumes[*].Size" --output text --region $region`
        state=`aws ec2 describe-volumes --volume-ids  $vol --query "Volumes[*].State" --output text --region $region`

        if [ $size -gt 170 ]; then
            throughput=250 
        else
            throughput=125
        fi

        gp2cost=`echo "scale=5; 0.12 * $size" | bc`
        gp3cost=`echo "scale=5; 0.096 * $size + ($throughput - 125) * 0.048" | bc`
        savecost=`echo "scale=5; $gp2cost - $gp3cost" | bc`

        echo $region,$vol,gp2,$size,$state,gp3,3000,$throughput,$gp2cost,$gp3cost,$savecost

    done
done
```

### このスクリプトがやってくれること
- 東京リージョンと大阪リージョンの全EBSを抽出する
- gp2になっているストレージをgp3に変換した場合の月間削減コスト一覧をCSV出力してくれる


### スクリプトの実行例
以下のような CSVフォーマットが出力されます。(実行環境は Mac と Linux です)
Windows な方は、Cloud9 か CloudShell環境で実行してください。

```bash
% sh check_ebs_optimization.sh 

Region,VolumeId,VolumeType,Size,State,ModifiedVolumeType,ModifiedIOPS,ModifiedThroughput,gp2Cost(Month),gp3Cost(Month),SaveCost(Month)
ap-northeast-1,vol-0d4761e87d5084xxxx,gp2,100,in-use,gp3,3000,125,12.00,9.600,2.400
ap-northeast-1,vol-02bdb193ebf44cxxxx,gp2,200,in-use,gp3,3000,250,24.00,25.200,-1.200
ap-northeast-1,vol-0e5544c6323dfxxxxx,gp2,50,in-use,gp3,3000,125,6.00,4.800,1.200
ap-northeast-1,vol-0d43de367b45bxxxxx,gp2,30,in-use,gp3,3000,125,3.60,2.880,.720
ap-northeast-1,vol-07c12f7ecfacxxxxxx,gp2,8,in-use,gp3,3000,125,.96,.768,.192
ap-northeast-1,vol-04e18fef7c4a6xxxxx,gp2,10,available,gp3,3000,125,1.20,.960,.240
```

### 項目の説明
- **Region**
    - EBS ボリュームのリージョン
- **VolumeID**
    - EBS ボリュームの volume id
- **VolumeIDType**
    - EBS ボリューム の volume type (gp2のみ出力されます)
- **Size**
    - EBS ボリュームのサイズ
- **State**
    - EBS ボリュームのState
        - in-use:  EC2 インスタンスにアタッチされている
        - available: EC2 インスタンスにアタッチされていない
- **ModifiedVolumeType**
    - EBS ボリュームの変更先 ( 常に gp3 と出力されます）
- **ModifiedIOPS**
    - gp3 に変更した場合の IOPS (常に 3000　と指定します）
- **ModifiedThroughput**
    - gp3 に変更した場合のスループット
        - ボリュームサイズが 170GB以下の場合は 125 MB/s、170GBを超える場合は 250 MB/s を指定します
        - gp2 は 170GBを超えるか超えないかで、最大スループットが変化するため、それを反映しています。https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/ebs-volume-types.html#solid-state-drives
- **gp2Cost(Month)**
    - gp2 のままだった場合の月額費用(USD)
- **gp3Cost(Month)**
    - gp3 に変換した場合の月額費用(USD)
- **SaveCost(Month)**
    - gp3 に変換した場合に削減できる月額費用(USD)
    - スクリプトの仕様上、0.2 といった、小数点の場合は、0 が省略される（ .2 と表示される）
    - 値がマイナスの場合は、gp3 で費用が増える


まあ、細かく書いていますが、 **SaveCost(Month)** だけ見ればOKです


## Excelで確認
### csv ファイル作成
出力を csv ファイル(ここでは`gp2-to-gp3.csv`)として保存します。（スクリプトでファイル作成もしてくれるとカッコいいのですが、やっていません。温かみのある手作業です）
```csv:gp2-to-gp3.csv
Region,VolumeId,VolumeType,Size,State,ModifiedVolumeType,ModifiedIOPS,ModifiedThroughput,gp2Cost(Month),gp3Cost(Month),SaveCost(Month)
ap-northeast-1,vol-0d4761e87d5084xxxx,gp2,100,in-use,gp3,3000,125,12.00,9.600,2.400
ap-northeast-1,vol-02bdb193ebf44cxxxx,gp2,200,in-use,gp3,3000,250,24.00,25.200,-1.200
ap-northeast-1,vol-0e5544c6323dfxxxxx,gp2,50,in-use,gp3,3000,125,6.00,4.800,1.200
ap-northeast-1,vol-0d43de367b45bxxxxx,gp2,30,in-use,gp3,3000,125,3.60,2.880,.720
ap-northeast-1,vol-07c12f7ecfacxxxxxx,gp2,8,in-use,gp3,3000,125,.96,.768,.192
ap-northeast-1,vol-04e18fef7c4xxxxx,gp2,10,available,gp3,3000,125,1.20,.960,.240
```

### Excelで開く
Excelで開いて、gp3 変換でのコスト削減合計を計算します。。（赤文字の部分）
私の環境だと、gp3 に変換するだけで、**月額 3.552 ドル** の削減になります。
使っていないリソースを削除するでもなく、全体構成を変えるわけでもなく、EC2 インスタンスを停止するわけでもなく、月額 3.552 ドル削減できるのは凄い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/0a98772a-c1b4-e20f-8693-7d696b96c169.png)


# 一括で gp2 から gp3 に変換するスクリプト

サービス影響なく、オンラインで変換できるなら、一気にやってしまえ！ということで、こちらもスクリプトを作りました。
使っているコマンドは、 `aws ec2 describe-volumes` と `modify-volume` と （変換前にスナップショットを取るなら)`aws ec2 create-snapshot` だけです。

```shell:run_ebs_optimization.sh
#!/bin/sh

read -p "チェックスクリプト check_ebs_optimization.sh を実行済みですか?  (y/n) :" YN
if [ "${YN}" = "y" ]; then
    
read -p "東京リージョンと大阪リージョンの gp2 EBS を全て gp3 に変更していいですか？  (y/n) :" YN
if [ "${YN}" = "y" ]; then

read -p "変更前にスナップショットを取得しますか？  (y/n) :" YN

regions=("ap-northeast-1" "ap-northeast-3")

for region in ${regions[@]}
do
    for vol in $(aws ec2 describe-volumes --filter "Name=volume-type,Values=gp2" --query "Volumes[*].VolumeId" --output text --region $region)
    do
        size=`aws ec2 describe-volumes --volume-ids  $vol --query "Volumes[*].Size" --output text --region $region`

        if [ $size -gt 170 ]; then
            throughput=250
        else
            throughput=125
        fi

        if [ "${YN}" = "y" ]; then
            aws ec2 create-snapshot --volume-id ${vol} --tag-specification 'ResourceType="snapshot",Tags=[{Key="Name",Value="before-gp3-modification"}]' --region $region
            aws ec2 modify-volume --volume-type gp3 --volume-id ${vol} --iops 3000 --throughput ${throughput} --region $region
        elif [ "${YN}" = "n" ]; then
            aws ec2 modify-volume --volume-type gp3 --volume-id ${vol} --iops 3000 --throughput ${throughput} --region $region
        else
            exit 1
        fi

    done
done


else
echo "処理を停止しました"
exit 1
fi

else
echo "チェックスクリプト check_ebs_optimization.sh を実行してください"
exit 1
fi
```


### このスクリプトがやってくれること
- 東京リージョンと大阪リージョンの全ての gp2 なEBSストレージを gp3 に変換する
    - オプションで変換前に対象ストレージのスナップショットを取ることも可能


### スクリプトの実行例
実行しても、いきなり処理が始まらないように、**y/n** の確認を設けています。
私自身、今まで千回近く gp2 から gp3 の変換を行っていますが、一度も問題が発生したことはありません。が、念には念を入れて、変換前にスナップショットを取得するか **y/n** で選択できるようになっています。
(gp3の変更は非同期で行われるため、コマンドの実行自体ははボリューム数によりますが、数十秒で終わります）
(スナップショットを作成する場合は、`before-gp3-modification` という名前でスナップショットを取得します）

```bash
$ sh run_ebs_optimization.sh 

チェックスクリプト check_ebs_optimization.sh を実行済みですか?  (y/n) :y
東京リージョンと大阪リージョンの gp2 EBS を全て gp3 に変更していいですか？  (y/n) :y
変更前にスナップショットを取得しますか？  (y/n) :y

{
    "Description": "",
    "Encrypted": false,
    ~~~ 省略 ~~~
```

### よくある質問
Q: 変換にどれくらい時間がかかるか？
A: 私の環境だと、100GBのgp2でも5分かかりませんでした。
(公式) パフォーマンス (IOPS) の変更は、設定の変更内容に応じて、完了するまでに数分から数時間かかる場合があります。


Q: 変換中はEBS自体のパフォーマンスが低下するか？
A: いいえ、しません。
(公式) ボリュームが optimizing 状態である場合、ボリュームのパフォーマンスはソースとターゲットの設定仕様の中間にあります。過渡的なボリュームのパフォーマンスは、ソースボリュームのパフォーマンスより劣ることはありません。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/monitoring-volume-modifications.html

### (オプション）スナップショットの削除
gp3 への変換が終わり、問題が発生していないようなら、事前に取得したスナップショットを削除します。
`before-gp3-modification` という名前でフィルタリングして、削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/77c0d7f0-199d-d799-c9c9-a076a6eba145.png)


# まとめ（再掲）
- EBSボリュームは gp3 を使おう。gp2よりの上位互換、コストも削減できることがほとんど。
- でも、gp3 誕生前から gp2 を使っていたり、EC2 インスタンス作成時のデフォルト設定が gp2 なせいで、あまり gp3 使われていないよね
-　チェックスクリプトを使って、gp3 へ変更した場合のコスト削減効果をサクッとだそう
-　一気に変換できるなら、変換スクリプトを使って、一気に変換しちゃおう。サービス影響まったくないよ。一気にできない場合でも、1つずつ手作業で変換していこう。
-　コスト削減効果は、塵も積もれば山となる！