awscliを使ったEC2でInstanceのAMIを取得するスクリプト(bash)

2020-12-31 - 読み終える時間: 5 分

また不格好なスクリプトを書いてしまった・・・

だいたいの説明

  • awscli V2利用(aws-cli/2.1.15 Python/3.7.3 Linux/4.4.0-19041-Microsoft exe/x86_64.ubuntu.20 prompt/off)
  • awscliのプロファイルとアクセスキーは設定済みとする
  • <インスタンスのNameタグの値>-system-v<N>という名前の付いたAMIを作成する ※<N>は数字
  • <インスタンスのNameタグの値>の中に"-v"という文字列があると失敗するはず
  • 世代管理する(個人的には1世代しか残さないので割と適当な造作)
  • ルートブロックデバイスしかSnapshotを作らない(xvdbとxvdcを決め打ちで除外)
  • Snapshotにもタグ付けする
  • AMI作成時に再起動しない
  • tempファイル作るのが嫌いな向きは使わない方が良いです

大変お世話になりました :https://gist.github.com/magnetikonline/6a382a4c4412bbb68e33e137b9a74168

コード全文

#!/bin/bash

# CREATE zin@alterworks.tokyo
# DATE   2020-12-30

## get date
val_NOW_=`date +%Y%m%d_%H`

## set Generation
declare -i val_GEN_=1

## set profile $val_PROF_
if [ "${1}"=="" ]; then
    val_PROF_=profile1
else
    val_PROF_=${1}
fi

## set $val_APPTAG_
if [ "${2}"=="" ]; then
    val_APPTAG_=application.url
else
    val_PROF_=${2}
fi

## get instance id ${arr_IIDS_[]}
declare -a arr_INAME_=("NameTAG1" "NameTAG2" "NameTAG3")
declare -a arr_IIDS_
for i in ${arr_INAME_[@]}
do
    arr_IIDS_=(${arr_IIDS_[@]} `aws --profile ${val_PROF_} ec2 describe-instances \
    --filters Name="tag:Name",Values=${i} \
    --query "Reservations[*].Instances[0].InstanceId" --output text`)
done

## create AMIs
val_IIDCOUNT_=`expr ${#arr_IIDS_[@]} - 1`
for x in `seq 0 ${val_IIDCOUNT_}`
do
    ### get previous AMI version
    val_PREAMINAME_=`aws --profile ${val_PROF_} ec2 describe-images \
    --owners self \
    --filters Name="tag:Name",Values="${arr_INAME_[${x}]}-*" \
    --query "sort_by(Images,&CreationDate)[*].Tags[?Key=='Name'].[Value]" --output text | tail -n 1`
    if [ "${val_PREAMINAME_}" == "" ]; then
        declare -i val_PREAMIVER_=100
    else
        declare -i val_PREAMIVER_=`echo ${val_PREAMINAME_} | sed 's/.*-v//g'`
    fi
    declare -i val_AMIVER_=`expr ${val_PREAMIVER_} + 1`

    ## Name suffix
    val_SUFF_=system-v${val_AMIVER_}

    ### create AMI
    val_AMINAME_=${arr_INAME_[${x}]}-${val_SUFF_}
    aws --profile ${val_PROF_} ec2 create-image \
    --no-reboot \
    --name "${val_AMINAME_}" \
    --instance-id ${arr_IIDS_[${x}]} \
    --description "${val_AMINAME_} --- ${arr_INAME_[${x}]}" \
    --block-device-mappings DeviceName=/dev/xvdb,NoDevice="" DeviceName=/dev/xvdc,NoDevice="" \
    --tag-specifications "ResourceType=image,Tags=[{Key=Name,Value=${val_AMINAME_}},{Key=APP,Value=${val_APPTAG_}}]" \
    --output text >> /tmp/${0}-${val_NOW_}.log
    if [ "$?" -ne "0" ]; then
        echo Error appeared "${val_AMINAME_}"
        val_GOSIGN_=NG
        exit 1
    else
        val_GOSIGN_=OK
    fi
    sleep 3
    if [ "${val_GOSIGN_}" == "OK" ]; then
        ### set TAG for AMIs Snapshot
        val_AMIID_=`tail -n 1 /tmp/${0}-${val_NOW_}.log`
        val_SNAPID_=`aws --profile ${val_PROF_} ec2 describe-snapshots \
        --owner-ids self \
        --filters Name="description",Values="*${val_AMIID_}*" --query "Snapshots[*].[SnapshotId]" --output text`
        aws --profile ${val_PROF_} ec2 create-tags \
        --resources ${val_SNAPID_} \
        --tags Key=Name,Value="${val_AMINAME_}" Key=APP,Value="${val_APPTAG_}"
    else
        echo Cant to setting TAG
    fi
done

## rotate Generatation
declare -i val_AMICOUNT_
declare -i val_BORDER_
for c in `seq 0 ${val_IIDCOUNT_}`
do
    val_AMICOUNT_=`aws --profile ${val_PROF_} ec2 describe-images \
    --owners self \
    --filters Name="name",Values="${arr_INAME_[${c}]}-*" \
    --query "Images[*].[ImageId]" --output text | wc -l`
    if [ "${val_AMICOUNT_}" -le "${val_GEN_}" ]; then
        echo No deregisterd AMIs.
        exit 0
    else
        val_BORDER_=`expr ${val_AMICOUNT_} - ${val_GEN_}`
        declare -a arr_DELAMIIDS_=(`aws --profile ${val_PROF_} ec2 describe-images \
        --owners self \
        --filters Name="tag:Name",Values="${arr_INAME_[${c}]}-*" \
        --query "reverse(sort_by(Images,&CreationDate))[*].[ImageId]" --output text | tail -n ${val_BORDER_}`)
        for n in ${arr_DELAMIIDS_[*]}
        do
            ### list delete snapshots ID
            aws --profile ${val_PROF_} ec2 describe-images \
            --owners self \
            --image-ids ${n} \
            --query "Images[].BlockDeviceMappings[].Ebs[].[SnapshotId]" --output text >> /tmp/${0}-deleting-snapshots.list

            ### deregister AMI
            aws --profile ${val_PROF_} ec2 deregister-image --image-id ${n}
            if [ "$?" -eq "0" ]; then
                echo "deregisterd ${n} --- ${val_NOW_}" >> /tmp/${0}-${val_NOW_}.log
            else
                echo "failed ${n} deregistering --- ${val_NOW_}" >> /tmp/${0}-${val_NOW_}.log
            fi
            sleep 2
        done
        ### delete snapshots
        for s in `cat /tmp/${0}-deleting-snapshots.list`
        do
            aws --profile ${val_PROF_} ec2 delete-snapshot --snapshot-id ${s}
            sleep 2
        done
        ### clear temp file
        rm -rf /tmp/${0}-deleting-snapshots.list
    fi
done

雑な解説

  1. declare -i val_GEN_=1 ここの数字で世代数管理
  2. declare -a arr_INAME_=("NameTAG1" "NameTAG2" "NameTAG3") ここのかっこの中にインスタンスのNameタグの値を列記する

今日はここまで