[JAWS-UG CLI] EC2:#2 インスタンスの作成 (Public + UserData)

前提条件
========


EC2への権限
-----------

EC2に対してフル権限があること。


AWS CLIのバージョン
-------------------

以下のバージョンで動作確認済

- AWS CLI 1.11.14

```bash:コマンド:
aws --version
```

結果(例):

      aws-cli/1.11.19 Python/2.7.10 Darwin/15.6.0 botocore/1.4.76

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


AWSアカウントの属性
-------------------

AWSアカウントがEC2-Classicに対応していないこと。

```bash:コマンド:
AWS_SUPPORT_PLATFORMS=$( \
         aws ec2 describe-account-attributes \
           --query 'AccountAttributes[?AttributeName == `supported-platforms`].AttributeValues[].AttributeValue' \
           --output text \
) && echo ${AWS_SUPPORT_PLATFORMS}
```

結果:

      VPC

注釈: 'VPC'の他に'EC2'が表示される場合、別のアカウントを作成もしくは
  利用し てください。


0. 準備
=======


0.1. リージョンの決定
---------------------

```bash:変数の設定:
export AWS_DEFAULT_REGION='ap-northeast-1'
```


0.2. 変数の確認:
----------------

プロファイルが想定のものになっていることを確認します。

```bash:変数の確認:
aws configure list
```

結果(例):

            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile       ec2full-prjZ-mbp13        env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region        ap-northeast-1        env    AWS_DEFAULT_REGION


0.3. VPCの指定
--------------

既存のVPCに割り当てられているCIDRブロックを確認します。

```bash:コマンド:
aws ec2 describe-vpcs \
        --query 'Vpcs[].CidrBlock'
```

結果(例):

      [
        "172.31.0.0/16",
        "10.192.0.0/16"
      ]

ここでは、10.192.0.0/16を範囲とするVPCを選択します。

```bash:変数の設定:
VPC_CIDR='10.192.0.0/16'
```

VPC IDを取得します。

```bash:コマンド:
VPC_ID=$( \
        aws ec2 describe-vpcs \
          --filters Name=cidr,Values=${VPC_CIDR} \
          --query 'Vpcs[].VpcId' \
          --output text \
) \
        && echo ${VPC_ID}
```

結果(例):

      vpc-xxxxxxxx


0.4. サブネットの指定
---------------------

```bash:変数の設定:
VPC_SUBNET_CIDR='10.192.0.0/24'
```

```bash:コマンド:
VPC_SUBNET_ID=$( \
        aws ec2 describe-subnets \
          --filters Name=cidrBlock,Values=${VPC_SUBNET_CIDR} \
          --query 'Subnets[].SubnetId' \
          --output text \
) \
        && echo ${VPC_SUBNET_ID}
```

結果(例):

      subnet-xxxxxxxx


0.5. UserDataの指定
-------------------

```bash:変数の設定:
FILE_EC2_USERDATA='userdata.bash'
```


1. 事前作業
===========


1.1. プライベートアドレスの決定
-------------------------------

選択したサブネットのアドレス範囲内で、起動するインスタンスのプライベー
トIPアドレスを指定します。

```bash:変数の設定:
EC2_PRIVATE_ADDR='10.192.0.8'
```


1.2. セキュリティグループの決定
-------------------------------

セキュリティグループの一覧を確認します。

```bash:コマンド:
aws ec2 describe-security-groups \
        --query "SecurityGroups[?VpcId == \` ${VPC_ID}\`].GroupName"
```

結果(例):

      [
        "default",
        "ec2-ssh-global-inbound"
      ]

利用するセキュリティグループ名を指定します。

```bash:変数の設定:
VPC_SG_NAME='ec2-ssh-global-inbound'
```

```bash:コマンド:
VPC_SG_ID=$( \
        aws ec2 describe-security-groups \
          --filter Name=group-name,Values=${VPC_SG_NAME} \
          --query "SecurityGroups[?VpcId == \` ${VPC_ID}\`].GroupId" \
          --output text \
) \
        && echo ${VPC_SG_ID}
```

結果(例):

      sg-xxxxxxxx

セキュリティグループを配列に入れておきます。

```bash:変数の設定
ARRAY_VPC_SG_ID="${VPC_SG_ID} ${ARRAY_VPC_SG_ID}" \
        && echo ${ARRAY_VPC_SG_ID}
```


1.3. キーペアの指定
-------------------

まず、キーペアの一覧を確認します。

```bash:コマンド:
aws ec2 describe-key-pairs \
        --query 'KeyPairs[].KeyName'
```

結果(例):

      [
          "<キーペアー名>"
      ]

利用するキーペア名を指定します。

```bash:変数の設定:
EC2_KEY_PAIR_NAME='<キーペアー名>'
```

利用するキーペアの秘密鍵ファイルを指定します。

```bash:変数の設定:
FILE_SSH_KEY="${HOME}/.ssh/<キーペア秘密鍵のファイル名>" \
        && echo ${FILE_SSH_KEY}
```

秘密鍵が存在することを確認しましょう。

```bash:コマンド:
ls ${FILE_SSH_KEY}
```


1.4. イメージIDの決定
---------------------

AMIを選択します。

```bash:変数の設定:
AMZLINUX_VERSION='2016.03.3'
EC2_IMAGE_NAME="amzn-ami-hvm-${AMZLINUX_VERSION}.x86_64-gp2"
```

```bash:コマンド:
EC2_IMAGE_ID=$( \
        aws ec2 describe-images \
          --filters Name=name,Values="${EC2_IMAGE_NAME}" \
          --query 'Images[].ImageId' --output text \
) \
        && echo ${EC2_IMAGE_ID}
```

結果(例):

      ami-XXXXXXXX


1.5. インスタンスタイプの決定
-----------------------------

```bash:変数の設定:
EC2_INSTANCE_TYPE='t2.micro'
```


1.6. 稼動インスタンスを確認
---------------------------

同一リージョンでインスタンスが起動していないことを確認します。

```bash:コマンド:
EC2_INSTANCE_STATUS='running'
```

```bash:コマンド:
aws ec2 describe-instances \
        --filters Name=instance-state-name,Values=${EC2_INSTANCE_STATUS}
```

結果:

      {
          "Reservations": []
      }


2. インスタンス起動
===================


2.1. インスタンス起動
---------------------

```bash:変数の確認:
cat << ETX

        EC2_IMAGE_ID:              ${EC2_IMAGE_ID}
        EC2_INSTANCE_TYPE:         ${EC2_INSTANCE_TYPE}
        EC2_KEY_PAIR_NAME:         ${EC2_KEY_PAIR_NAME}
        EC2_PRIVATE_ADDR:          ${EC2_PRIVATE_ADDR}
        ARRAY_VPC_SG_ID:           ${ARRAY_VPC_SG_ID}
        VPC_SUBNET_ID              ${VPC_SUBNET_ID}
        FILE_EC2_USERDATA:         ${FILE_EC2_USERDATA}

ETX
```

```bash:コマンド
aws ec2 run-instances \
        --image-id ${EC2_IMAGE_ID} \
        --instance-type ${EC2_INSTANCE_TYPE} \
        --security-group-ids ${ARRAY_VPC_SG_ID} \
        --key-name ${EC2_KEY_PAIR_NAME} \
        --subnet-id ${VPC_SUBNET_ID} \
        --private-ip-address ${EC2_PRIVATE_ADDR} \
        --associate-public-ip-address  \
        --user-data file://${FILE_EC2_USERDATA}
```

結果(例):

      {
        "OwnerId": "XXXXXXXXXXXX",
        "ReservationId": "r-xxxxxxxxxxxxxxxxx",
        "Groups": [],
        "Instances": [
          {
              "Monitoring": {
                  "State": "disabled"
              },
              "PublicDnsName": "",
              "RootDeviceType": "ebs",
              "State": {
                  "Code": 0,
                  "Name": "pending"
              },
              "EbsOptimized": false,
              "LaunchTime": "2016-12-05T01:23:45.000Z",
              "PrivateIpAddress": "10.192.0.8",
              "ProductCodes": [],
              "VpcId": "vpc-xxxxxxxx",
              "StateTransitionReason": "",
              "InstanceId": "i-xxxxxxxxxxxxxxxxx",
              "ImageId": "ami-xxxxxxxx",
              "PrivateDnsName": "ip-xxx-xxx-xxx-xxx.ap-northeast-1ap-northeast-1.compute.internal",
              "KeyName": "<キーペアー名>",
              "SecurityGroups": [
                  {
                      "GroupName": "ec2-ssh-global-inbound",
                      "GroupId": "sg-xxxxxxxx"
                  }
              ],
              "ClientToken": "",
              "SubnetId": "subnet-xxxxxxxx",
              "InstanceType": "t2.micro",
              "NetworkInterfaces": [
                  {
                      "Status": "in-use",
                      "MacAddress": "xx:xx:xx:xx:xx:xx",
                      "SourceDestCheck": true,
                      "VpcId": "vpc-xxxxxxxx",
                      "Description": "",
                      "NetworkInterfaceId": "eni-xxxxxxxx",
                      "PrivateIpAddresses": [
                          {
                              "Primary": true,
                              "PrivateIpAddress": "10.192.0.8"
                          }
                      ],
                      "Attachment": {
                          "Status": "attaching",
                          "DeviceIndex": 0,
                          "DeleteOnTermination": true,
                          "AttachmentId": "eni-attach-xxxxxxxx",
                          "AttachTime": "2016-12-05T01:23:45.000Z"
                      },
                      "Groups": [
                          {
                              "GroupName": "<キーペアー名>",
                              "GroupId": "sg-xxxxxxxx"
                          }
                      ],
                      "SubnetId": "subnet-xxxxxxxx",
                      "OwnerId": "XXXXXXXXXXXX",
                      "PrivateIpAddress": "10.192.0.8"
                  }
              ],
              "SourceDestCheck": true,
              "Placement": {
                  "Tenancy": "default",
                  "GroupName": "",
                  "AvailabilityZone": "ap-northeast-1a"
              },
              "Hypervisor": "xen",
              "BlockDeviceMappings": [],
              "Architecture": "x86_64",
              "StateReason": {
                  "Message": "pending",
                  "Code": "pending"
              },
              "RootDeviceName": "/dev/xvda",
              "VirtualizationType": "hvm",
              "AmiLaunchIndex": 0
          }
        ]
      }


2.2. インスタンスIDの取得
-------------------------

起動中のインスタンスからインスタンスIDを取得します。

```bash:コマンド:
EC2_INSTANCE_ID=$( \
        aws ec2 describe-instances \
          --filters Name=private-ip-address,Values=${EC2_PRIVATE_ADDR} \
          --query 'Reservations[].Instances[].InstanceId' \
          --output text \
) \
        && echo ${EC2_INSTANCE_ID}
```

結果(例):

      i-xxxxxxxxxxxxxxxxx


3. 事後作業
===========


3.1 インスタンスのステータス確認
--------------------------------

```bash:コマンド:
EC2_INSTANCE_STATE=$( \
        aws ec2 describe-instances \
        --instance-ids ${EC2_INSTANCE_ID} \
        --query 'Reservations[].Instances[].State.Name' \
        --output text \
) \
        && echo ${EC2_INSTANCE_STATE}
```

結果(例):

      running


3.2. パブリックIPアドレスの取得
-------------------------------

```bash:コマンド:
EC2_PUBLIC_IP=$( \
        aws ec2 describe-instances \
          --instance-id ${EC2_INSTANCE_ID} \
          --query "Reservations[].Instances[].PublicIpAddress" \
          --output text \
) \
        && echo ${EC2_PUBLIC_IP}
```

結果(例):

      xxx.xxx.xxx.xxx


4. インスタンスへのログイン
===========================


4.1. SSHログイン
----------------

```bash:変数の確認
cat << ETX

        FILE_SSH_KEY:  ${FILE_SSH_KEY}
        EC2_PUBLIC_IP: ${EC2_PUBLIC_IP}

ETX
```

```bash:コマンド:
ssh -i ${FILE_SSH_KEY} ec2-user@${EC2_PUBLIC_IP}
```

結果(例):

      The authenticity of host '54.xxx.xxx.xxx (54.xxx.xxx.xxx)' can't be established.
      RSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx.
      Are you sure you want to continue connecting (yes/no)?

入力:

      yes

結果(例):

      Warning: Permanently added '54.xxx.xxx.xxx' (RSA) to the list of known hosts.

             __|  __|_  )
             _|  (     /   Amazon Linux AMI
            ___|\___|___|

      https://aws.amazon.com/amazon-linux-ami/2015.03-release-notes/
      24 package(s) needed for security, out of 53 available
      Run "sudo yum update" to apply all updates.


4.2. パッケージ更新
-------------------

```bash:コマンド:
sudo yum update -y
```


4.3. EC2メタ情報の確認
----------------------

```bash:コマンド(EC2インスタンス)
echo -e "\n"   && curl http://169.254.169.254/latest/meta-data/public-ipv4   && echo -e "\n"
```

結果(例):

      xxx.xxx.xxx.xxx


4.4. EC2インスタンスからログアウト

```bash:コマンド(EC2インスタンス)
exit
```


完了
====