awscli でゼロから VPC 作成→ EC2 インスタンス立ち上げまで

AWS、便利ですよね。
ここ数年はもうこれが無いと仕事にも差し支えが出るほどになりました。

AWS コンソールを使うと、色んな環境が手軽に構築できるのですが、今回は あえて awscli をつかって、コマンドラインベースでゼロから VPC + EC2 の環境を作ってみます。

とっかかりとなるチュートリアルはこちら。

Tutorial: Using Amazon EC2
-> Deploying a Development Environment in Amazon EC2 Using the AWS Command Line Interface

そして今回利用するコマンドのリファレンスガイドはこちら。

awscli ec2 reference

IAM ユーザーの作成やアクセスキーの設定(もしくは IAM ロールの設定)など、AWS へのアクセス準備は既に出来ているものとします。

VPC の作成

まずは一番外側の入れ物である VPC を作成します。

aws ec2 create-vpc \
 --cidr-block 192.168.0.0/23

–cider-block で、作成する VPC のネットワークアドレスを指定します。
コマンド実行結果はこんな感じ。作成された VPC の情報が帰ってきます。

{
    "Vpc": {
    "InstanceTenancy": "default",
    "State": "pending",
    "VpcId": "vpc-badae2dd",
    "CidrBlock": "192.168.0.0/23",
    "DhcpOptionsId": "dopt-7492bd10"
    }
}

作成した VPC の Name タグ設定を行います。

aws ec2 create-tags \
 --resources vpc-badae2dd \
 --tags Key=Name,Value=test-vpc

なお、以下のデフォルトリソースが存在しない場合、VPC 作成時に自動作成されます。
・ネットワークACL
・ルートテーブル
・セキュリティグループ
・DHCP オプションセット

それぞれ、情報をコマンドラインで見る場合はこちらのコマンド。

aws ec2 describe-network-acls
aws ec2 describe-route-tables
aws ec2 describe-security-groups
aws ec2 describe-dhcp-options

サブネットの作成

VPC の中にサブネットを作成します。
異なる az にそれぞれ 1 つずつ、計 2 つのサブネットを作成します。

aws ec2 create-subnet \
 --vpc-id vpc-badae2dd \
 --cidr-block 192.168.0.0/24 \
 --availability-zone us-east-1b
aws ec2 create-subnet \
 --vpc-id vpc-badae2dd \
 --cidr-block 192.168.1.0/24 \
 --availability-zone us-east-1c

–availability-zone は必須ではないですが、指定しないと同一の AZ にサブネットが作成されてしまう可能性が有る (下記引用参照) ので、明示的に指定しておいた方がベター。

–availability-zone (string)
The Availability Zone for the subnet.
Default: AWS selects one for you. If you create more than one subnet in your VPC, we may not necessarily select a different zone for each subnet.

問題無ければ、作成されたサブネットの情報が返ってきます。

{
    "Subnet": {
        "VpcId": "vpc-badae2dd",
        "CidrBlock": "192.168.0.0/24",
        "State": "pending",
        "AvailabilityZone": "us-east-1b",
        "SubnetId": "subnet-53d41b7e",
        "AvailableIpAddressCount": 251
    }
}
{
    "Subnet": {
        "VpcId": "vpc-badae2dd",
        "CidrBlock": "192.168.1.0/24",
        "State": "pending",
        "AvailabilityZone": "us-east-1c",
        "SubnetId": "subnet-2efd4367",
        "AvailableIpAddressCount": 251
    }
}

作成されたサブネットには VPC デフォルトの NACL が自動的に関連付けされます。
また、VPC のメインルートテーブルにも関連付けが自動で行われます。

サブネットに Name タグを設定します。

aws ec2 create-tags \
 --resources subnet-53d41b7e \
 --tags Key=Name,Value=test-subnet-b
aws ec2 create-tags \
 --resources subnet-2efd4367 \
 --tags Key=Name,Value=test-subnet-c

このサブネットにインスタンスが立ち上がった時、自動でパブリックな IP が割り当てられるよう、設定をしておきます。

aws ec2 modify-subnet-attribute \
 --subnet-id subnet-53d41b7e \
 --map-public-ip-on-launch
aws ec2 modify-subnet-attribute \
 --subnet-id subnet-2efd4367 \
 --map-public-ip-on-launch

インターネットゲートウェイの作成

作成した VPC / サブネットとインターネット間で通信出来るようにするため、インターネットゲートウェイを作成して、VPC に関連付けます。

まずはインターネットゲートウェイの作成。これはオプションいりません。

aws ec2 create-internet-gateway

作成されたインターネットゲートウェイの情報が返ってきます。

{
    "InternetGateway": {
        "Tags": [],
        "InternetGatewayId": "igw-b5ef20d2",
        "Attachments": []
    }
}

作成したインターネットゲートウェイを VPC に関連付けます。

aws ec2 attach-internet-gateway \
 --internet-gateway-id igw-b5ef20d2 \
 --vpc-id vpc-badae2dd

ルートテーブルにインターネットゲートウェイを設定

VPC 作成時に自動で作成されたルートテーブルを編集し、インターネット宛の通信はインターネットゲートウェイに向くようにします。デフォルトルートの設定、ですかね。

aws ec2 create-route \
 --route-table-id rtb-11335777 \
 --destination-cidr-block 0.0.0.0/0 \
 --gateway-id igw-b5ef20d2

ここまでで、ネットワーク (VPC) 周りの設定は一段落。

Security Group の作成

これから立ち上げるインスタンスに関連付ける Security Group (SG) をあらかじめ作成しておきます。

aws ec2 create-security-group \
 --group-name test-sg \
 --vpc-id vpc-badae2dd \
 --description "security group for VPC"

作成した SG の ID が返ってきます。

{
    "GroupId": "sg-f3f4fe89"
}

作成した SG に Name タグを設定します。

aws ec2 create-tags \
 --resources sg-f3f4fe89 \
 --tags Key=Name,Value=test-sg

ssh を許可するルールを SG のインバウンドルールに追加します。

aws ec2 authorize-security-group-ingress \
 --group-id sg-f3f4fe89 \
 --protocol tcp \
 --port 22 \
 --cidr 111.222.333.444/32

インバウンドルールの削除は revoke-security-group-ingress コマンドで、
アウトバウンドルールの追加 / 削除はそれぞれ authorize-security-group-egress と revoke-security-group-egress コマンドで実施できます。

キーペアの作成

SG と同様に、インスタンスに関連付けるキーペアを作成しておきます。

aws ec2 create-key-pair \
 --key-name test-key \
 --query 'KeyMaterial' \
 --output text > ~/.ssh/test-key.pem

生成された秘密鍵はパーミッションを 400 にしないと秘密鍵の利用時にエラーが出るので、変更しておきます。

chmod 400 ~/.ssh/test-key.pem

利用する AMI の id を確認する

ここだけは、AWS コンソールで EC2 インスタンス新規作成画面を出して、AMI のリストから ami-id を控えた方がずっと楽です。

もしコマンドラインで探すなら、一例としてこんな感じ。

aws ec2 describe-images \
 --owners amazon \
 --filters "Name=name,Values=amzn-ami-hvm-2016*" \
           "Name=architecture,Values=x86_64" \
           "Name=block-device-mapping.volume-type,Values=gp2" \
 --query 'Images[].Description'
[
    "Amazon Linux AMI 2016.03.0 x86_64 HVM GP2",
    "Amazon Linux AMI 2016.09.rc-0.20160910 x86_64 HVM GP2",
    "Amazon Linux AMI 2016.03.3 x86_64 HVM GP2",
    "Amazon Linux AMI 2016.03.2 x86_64 HVM GP2",
    "Amazon Linux AMI 2016.09.0.20160923 x86_64 HVM GP2",
    "Amazon Linux AMI 2016.03.1 x86_64 HVM GP2"
]

こうやって説明文を拾ってきて、その説明文で AMI を特定して id を引っ張ってくる。

aws ec2 describe-images \
 --owners amazon \
 --filters "Name=description,Values=Amazon Linux AMI 2016.09.0.20160923 x86_64 HVM GP2" \
 --query 'Images[0].ImageId'

Amazon Linux なら name 項目のフィルタで『 amzn-ami-hvm-(西暦) 』という感じで探すのがとっかかりとしては入りやすいかも。

インスタンスの起動

ここまでに作成した VPC / サブネット / SG / キーペア を使って、やっとインスタンスを立ち上げます。

aws ec2 run-instances \
 --image-id ami-c481fad3 \
 --security-group-ids sg-f3f4fe89 \
 --subnet-id subnet-53d41b7e \
 --count 1 \
 --instance-type t2.micro \
 --key-name test-key \
 --query 'Instances[0].InstanceId'

立ち上がったインスタンスの ID が返ってきます。

パブリックなIPアドレスの確認

立ち上がったインスタンスに割り当てられたパブリック IP を確認します。

aws ec2 describe-instances \
 --instance-ids i-2e27e51e \
 --query 'Reservations[0].Instances[0].PublicIpAddress'

ssh で接続を試す

立ち上がったインスタンスに ssh で接続します。

ssh -i ~/.ssh/test-key.pem ec2-user@555.666.777.888

これでインスタンスにログインできるはず。

作成したリソースの削除

ここまでに作成したリソースの削除を行っていきます。

インスタンスのstop
aws ec2 stop-instances \
 --instance-ids i-2e27e51e
インスタンスのterminate
aws ec2 terminate-instances \
 --instance-ids i-2e27e51e
キーペアの削除
aws ec2 delete-key-pair \
 --key-name test-key
SecurityGroup の削除
aws ec2 delete-security-group \
 --group-id sg-f3f4fe89
サブネットの削除
aws ec2 delete-subnet --subnet-id subnet-53d41b7e
 aws ec2 delete-subnet --subnet-id subnet-2efd4367
ルートテーブルからインターネットゲートウェイへのルートを削除
aws ec2 delete-route \
 --route-table-id rtb-11335777 \
 --destination-cidr-block 0.0.0.0/0
インターネットゲートウェイを VPC からデタッチ
aws ec2 detach-internet-gateway \
 --internet-gateway-id igw-b5ef20d2 \
 --vpc-id vpc-badae2dd
インターネットゲートウェイの削除
aws ec2 delete-internet-gateway --internet-gateway-id igw-b5ef20d2
VPC の削除
aws ec2 delete-vpc --vpc-id vpc-badae2dd

ルートテーブル / NACL / VPC default SecurityGroup は VPC と同時に削除されます。

DHCP オプションセットの削除

他に VPC が有る場合、この DHCP オプションセットは利用されている場合が有ります。

※ 利用されていた場合はエラーが出て削除できない…はず。

aws ec2 delete-dhcp-options --dhcp-options-id dopt-7492bd10

おまけ リージョン一覧と AZ 一覧の取得コマンド

aws ec2 describe-regions
aws ec2 describe-availability-zones \
 --region us-east-1