指定AMIの最新版を使ったWindowsEC2インスタンスを作成するスクリプト

アイキャッチ AWS EC2

Windowsインスタンスを作成する際、所定の日本語版OSのAMIを使って起動させるのですが、任意のエディションのAMIは任意の更新間隔で新しいAMIが出ており、『常に最新のAMIで』作成するとなるとそのAMI IDを探して指定する必要があり、若干面倒でした。

エントリを書く切っ掛けとなった理由としては、にしざわの書いた下記エントリと同じものになると思います。

上記エントリではCloudFormationでその課題を解決する形の内容となっておりますが、当エントリではスクリプト(内部的にはAWS CLI)を利用する形で同種の課題を解決する方法を採ってみました。

目次

 

スクリプト本体

という訳で、上記課題を解決する事が出来るシェルスクリプトが以下となります。

 

使い方など

当スクリプトの実行環境は以下環境で動作確認を行っております。スクリプト内部ではAWS CLI及びjqを利用していますので事前にインストールしておいてください。

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.12.4
BuildVersion:	16E195

$ aws --version
aws-cli/1.11.112 Python/2.7.10 Darwin/16.5.0 botocore/1.5.75

$ python --version
Python 2.7.10

$ jq --version
jq-1.5
  • AWS CLIについてはインストール後、aws conigureコマンドで利用設定を予め行っておいてください。ここではプロファイル=「cm-blog」という設定を行ったと仮定して進めます。
  • $ aws configure --profile cm-blog
    AWS Access Key ID [None]: XXXXXXXXXXXXXXXX
    AWS Secret Access Key [None]: XXXXXXXXXXXXXXXX
    Default region name [None]: us-east-1
    Default output format [None]: json
    

     

    事前準備

    スクリプトを利用するに当たっての手順は以下の通りです。

    1. 上記ファイルをダウンロード後、実行権限を付与。
    2. $ chmod +x ./run-windows-ec2-instance.sh
      
    3. 当スクリプトは、『既に出来上がっているAWS環境にEC2インスタンスをサクッと1つ追加したい』というようなケースを想定した形です。ですので、ご利用の際には以下要素を予め作成しておいてください。
      • VPC
      • サブネット
      • EC2インスタンスに割り当てるIAM Role

    ちなみに今回検証に使ったのは『Windows_Server-2012-R2_RTM-Japanese-64Bit-Base』というもの。この文言でAMIを検索すると幾つか該当します。執筆時点で一番新しいAMIは『2017.06.14』になるようです。

    ec2-ami-id-list

     

    実行方法

    ダウンロードしたファイル冒頭にも同様の記載がありますが、以下のようなオプション指定で実行が可能となります。

    オプション指定は最後の-pのみ任意であとは必須、

    また先頭3つのオプション指定(-i,-v,-n)と最後の-pについては事前に作成されたものを使い、残るオプションについては実行時に指定されたものを使う形となります。

    ## 実行例
    ## $ ./run-windows-ec2-instance.sh \
    ##    -i cm-blog-role \
    ##    -v vpc-xxxxxxxx \
    ##    -n subnet-xxxxxxxx \
    ##    -c 60 \
    ##    -d 120 \
    ##    -t c3.2xlarge \
    ##    -k xxxxxxxxxx-key \
    ##    -s sg_xxxxxxxxxx \
    ##    -x WindowsServerXXXXXXX \
    ##    -p xxxxxx
    ## ---------------------------------------------------------------------------
    ## 実行時の引数として以下の値を受け取る(※印の付いているものは事前に作成要).
    ## ---------------------------------------------------------------------------
    IAM_ROLE=""      ## 実行時にEC2インスタンスに割り当てるIAM Role (-i)(※事前に作成したものを指定)
    VPC_ID=""        ## 作成するインスタンスを配備するVPC ID (-v)(※事前に作成したものを指定)
    SUBNET_ID=""     ## 作成するインスタンスを配備するSUBNET ID (-n)(※事前に作成したものを指定))
    DRIVEC_SIZE=""   ## 作成するインスタンス(Windows Server 2012を想定)のCドライブストレージ容量 (-c)
    DRIVED_SIZE=""   ## 作成するインスタンス(Windows Server 2012を想定)のDドライブストレージ容量 (-d)
    INSTANCE_TYPE="" ## 作成するインスタンスのインスタンスタイプ (-t)
    KEY_PAIR_NAME="" ## 作成するインスタンスにログインする為に用いるKeyPairファイル名(-k)(この名前で作成します)
    SG_NAME=""       ## 作成するインスタンスに割り当てるセキュリティグループ名(-s)(この名前で作成します)
    INSTANCE_NAME="" ## 作成するインスタンスを識別する任意の名称(-x)(この名前を後続処理で利用します)
    PROFILE=""       ## 実行時のAWS CLIプロファイル(-p)(オプション)
    

    実行例。スクリプトでは実行結果を出力しながら処理を進めています。AMI IDについても、上記で確認したものをちゃんと指定出来ているようです。

    $ ./run-windows-ec2-instance.sh \
      -i cm-blog-role \
      -v vpc-b9axxxxx \
      -n subnet-923xxxxx \
      -c 60 \
      -d 100 \
      -t c3.2xlarge \
      -k cm-blog-server-key \
      -s sg_cmblog_server \
      -x WindowsServer2012_cmblog \
      -p cm-blog
    
    ######################################################
    EC2(Windows2012日本語版)インスタンス起動スクリプト.
    ######################################################
    run instance operation:START.
    -------------------------
    VPC ID: vpc-b9axxxxx
    Subnet ID: subnet-923xxxxx
    STORAGE SIZE of C drive: 60 (GB)
    STORAGE SIZE of D drive: 100 (GB)
    Instance Type: c3.2xlarge
    KeyPair Name: cm-blog-server-key
    Security Group Name: sg_cmblog_server
    Instance Name: WindowsServer2012_cmblog
    Profile: --profile cmblog
    
    ImageId:   ami-ec9bbdfa
    ImageName: Windows_Server-2012-R2_RTM-Japanese-64Bit-Base-2017.06.14
    
    EIP: 34.193.150.xxx
    SecurityGroup ID/Name: sg-b46xxxxx(sg_cmblog_server)
    KeyPairName: cm-blog-server-key.pem
    
    EC2 InstanceID: i-0e5bxxxxxxxxxxxxx
    ---------------
    waiting for instance-running.
    instance is running.
    instance eip association finished.
    run instance operation:END.
    

    作成時に指定したキーペアはシェルスクリプトと同じパスに生成されていますので、このファイルを使ってWindowsログインを行ってください。

    $ ls ./cm-blog-server-key.pem
    ./cm-blog-server-key.pem
    

    ec2-windows-desktop

     

    ソースコード解説

    以下、簡単ではありますがコードの解説を幾つか。

    プログラムでは幾つか任意の引数を受け取って処理を行わせる必要がありましたので、bashのgetoptsコマンドを活用しました。

    while getopts i:v:n:c:d:t:k:s:x:p: OPT
    do
        case $OPT in
            "i" ) IAM_ROLE="$OPTARG";;
            "v" ) VPC_ID="$OPTARG";;
            "n" ) SUBNET_ID="$OPTARG";;
              :
            "x" ) INSTANCE_NAME="$OPTARG";;
            "p" ) PROFILE="--profile ""$OPTARG";;
        esac
    done
    

    今回一番楽したかった(実現したかった)のがこの部分です。

    AWS CLIの--filtersオプションを用い、Amazon所有の(--owners amazon)所定の名称を持つ(ここではWindows_Server-2012-R2_RTM-Japanese-64Bit-Base-*という前方一致条件を使用)AMIの一覧を取得し、作成日の降順ソートした1件目のイメージIDを取得しています。

    ## ---------------------------------------------------------------------------
    ## インスタンス起動に用いるOS及びバージョンの最新AMIを取得.
    ## 対象:『Windows_Server-2012-R2_RTM-Japanese-64Bit-Base』
    ## ---------------------------------------------------------------------------
    IMAGE_ID=`aws ec2 describe-images $PROFILE \
      --owners amazon \
      --filters "Name=platform,Values=windows" \
                "Name=name,Values=Windows_Server-2012-R2_RTM-Japanese-64Bit-Base-*" \
      --query "Images[*].{Name:Name, CreationDate:CreationDate, ImageId:ImageId}" | \
      jq 'sort_by(.CreationDate) | reverse' | \
      jq -r '.[0].ImageId'`
    

    インスタンス生成(aws ec2 run-instance)部分。今回WindowsインスタンスCドライブとDドライブを分けた構成を取りたかったので--block-device-mappingsオプションを使ってそれぞれドライブの容量を指定させるようにしました。

    ## ---------------------------------------------------------------------------
    ## インスタンス起動
    ## ---------------------------------------------------------------------------
    EC2_INSTANCE_ID=`aws ec2 run-instances $PROFILE \
      --image-id $IMAGE_ID \
      --key-name $KEY_PAIR_NAME \
      --security-group-ids $SGID \
      --instance-type $INSTANCE_TYPE \
      --block-device-mappings DeviceName=/dev/sda1,Ebs={VolumeSize=$DRIVEC_SIZE} DeviceName=xvdb,Ebs={VolumeSize=$DRIVED_SIZE} \
      --subnet-id $SUBNET_ID \
      --enable-api-termination \
      --instance-initiated-shutdown-behavior stop \
      --iam-instance-profile Name="$IAM_ROLE" \
      --count 1 \
      --associate-public-ip-address | jq -r '.Instances[].InstanceId'`
    

     

    まとめ

    という訳で任意の最新版AMIを用いてインスタンスを作成するお手軽スクリプトを作成しました、という内容のご紹介でした。CloudFormationで一発!という素晴らしさは無いですが、任意の設定を切り替え可能な形でサクッとインスタンスが作成出来るのもまた便利なのではないかと思います。内容的には初歩的なものを組み合わせた形となりますが、何らかの折にご活用頂ければ幸いです。