[JAWS-UG CLI] VPC:#1 VPC作成

http://jawsug-cli.doorkeeper.jp/events/15122 でのハンズオン資料です。

AWS CLIを利用して、VPCを構築します。

今回は、VPCマネジメントコンソールを眺めながら作業すると、CLIでの作業の意味がわかりやすいと思います。


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

* EC2についてフル権限がある。
* AWS CLI 1.6.2

0. 事前作業
===========


0.1. リージョンを決める
-----------------------

まず、VPCを作成するリージョンを決めます。

```bash:コマンド(例):
   export AWS_DEFAULT_REGION='ap-northeast-1'
```

このハンズオンでは、AWS標準のリージョン変数を利用していますが、regionオプションでコマンド毎に指定しても同様の結果になります。
(「オペミスを回避するために明示的に実行する」という意味ではregionオプションの方が良いです。)


0.2. アドレスブロックを決める
-----------------------------

作成するVPCに割り当てるアドレスブロック(プライベート)を決めます。

* プライベートIPアドレスの範囲

  * 10.0.0.0/8 (10.0.0.0 - 10.255.255.255)
  * 172.16.0.0/12 (172.16.0.0 - 172.31.255.255)
  * 192.168.0.0/16 (192.168.0.0 - 192.168.255.255)

今回は、10.192.0.0/16をVPCに割り当てます。

```bash:コマンド:

   $ VPC_ADDR='10.192.0.0/16'
```


0.3. AZの確認
-------------

VPCを作成するリージョンに存在するAZ(Available Zone)を確認します。

```bash:コマンド:

   $ ARRAY_EC2_AZ=`aws ec2 describe-availability-zones --filters Name=state,Values=available --query 'AvailabilityZones[].ZoneName' --output text` && echo ${ARRAY_EC2_AZ}
```

```text:結果:
   ap-northeast-1a ap-northeast-1c
```

このハンズオンでは、2つのAZに下記の4つのSubnetを作成します。

* Private Subnet

  * Subnet01: ap-northeast-1a
  * Subnet03: ap-northeast-1c

* Public Subnet

  * Subnet11: ap-northeast-1a
  * Subnet13: ap-northeast-1c


以下のファイルを作成します。

```text:vpc.env:
   VPC_NET01_AZ='ap-northeast-1a'
   VPC_NET03_AZ='ap-northeast-1c'
   VPC_NET11_AZ='ap-northeast-1a'
   VPC_NET13_AZ='ap-northeast-1c'
   VPC_NET01_ADDR='10.192.1.0/24'
   VPC_NET03_ADDR='10.192.3.0/24'
   VPC_NET11_ADDR='10.192.129.0/24'
   VPC_NET13_ADDR='10.192.131.0/24'
```

bashのプロンプトからシェル変数として読み込みます。

```bash:コマンド:
   $ . vpc.env
```


0.4. デフォルトVPCの確認
------------------------

まっさらの状態であれば、デフォルトVPCのみが見えます。

```bash:コマンド:
   $ aws ec2 describe-vpcs
```

```json:結果:
   {
       "Vpcs": [
           {
               "VpcId": "vpc-XXXXXXXX", 
               "InstanceTenancy": "default", 
               "State": "available", 
               "DhcpOptionsId": "dopt-XXXXXXXX", 
               "CidrBlock": "172.31.0.0/16", 
               "IsDefault": true
           }
       ]
   }
```

* デフォルトVPCとは?

  * http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/default-vpc.html

  * デフォルト以外のVPCを作成してインスタンスの起動時にそれを指定しない限り、インスタンスはデフォルトVPC内で起動します。


1. VPCの作成
============


1.1. VPCの作成
--------------

VPCを作成します。

```bash:コマンド:
   $ aws ec2 create-vpc --cidr-block ${VPC_ADDR}
```

```json:結果:
   {
       "Vpc": {
           "InstanceTenancy": "default", 
           "State": "pending", 
           "VpcId": "vpc-XXXXXXXX", 
           "CidrBlock": "10.192.0.0/16", 
           "DhcpOptionsId": "dopt-XXXXXXXX"
       }
   }
```


1.2. VPC IDの取得
-----------------

作成したVPCのVPC IDを取得します。

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

```text:結果:
   vpc-XXXXXXXX
```


1.3. VPCの内容確認
------------------

作成したVPCの内容を確認しましょう。

```bash:コマンド:
   $ aws ec2 describe-vpcs --vpc-id ${VPC_ID}
```

```json:結果:
   {
     "Vpc": {
         "InstanceTenancy": "default",
         "State": "pending",
         "VpcId": "vpc-XXXXXXXX",
         "CidrBlock": "10.192.0.0/16",
         "DhcpOptionsId": "dopt-XXXXXXXX"
     }
   }
```


1.4. DHCPオプションの確認
-------------------------

### -[ DHCP Options IDの取得 ]-


VPCに関連付けられているDHCPオプションのIDを取得します。

```bash:コマンド:
   $ VPC_DHCP_ID=`aws ec2 describe-vpcs --vpc-id ${VPC_ID} --query 'Vpcs[].DhcpOptionsId' --output text`; echo ${VPC_DHCP_ID}
```

```text:結果:
   dopt-XXXXXXXX
```

### -[ DHCPオプションの確認 ]-

デフォルトのDHCPオプション設定を確認してみましょう。

```bash:コマンド:
   $ aws ec2 describe-dhcp-options --dhcp-options-ids ${VPC_DHCP_ID}
```

```json:結果:
   {
     "DhcpOptions": [
         {
             "DhcpConfigurations": [
                 {
                     "Values": [
                         {
                             "Value": "ap-northeast-1.compute.internal"
                         }
                     ],
                     "Key": "domain-name"
                 },
                 {
                     "Values": [
                         {
                             "Value": "AmazonProvidedDNS"
                         }
                     ],
                     "Key": "domain-name-servers"
                 }
             ],
             "DhcpOptionsId": "dopt-b00810d2"
         }
     ]
   }
```


1.5. VPCの設定確認 (DNSサポート)
--------------------------------

VPC内で用意されたDNSを使用する設定になっていることを確認します。

```bash:コマンド:
   $ aws ec2 describe-vpc-attribute --vpc-id ${VPC_ID} --attribute enableDnsSupport
```

```json:結果:
   {
       "VpcId": "vpc-9010b5f5", 
       "EnableDnsHostnames": {}, 
       "EnableDnsSupport": {
           "Value": true
       }
   }
```

* "この属性がtrueの場合、Amazonが提供するDNSサーバー(IPアドレス169.254.169.253)へのクエリ、またはリザーブドIPアドレス(VPCネットワークの範囲に"2"をプラスしたアドレス)へのクエリは成功します。"

  * http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/vpc-dns.html


1.6. VPCの設定確認 (DNSホスト名)
--------------------------------

VPC内に起動されるインスタンスがDNSホスト名を取得するかどうかを示します。

この属性がtrueの場合、VPC内のインスタンスはDNSホスト名を取得します。

```bash:コマンド:
   $ aws ec2 describe-vpc-attribute --vpc-id ${VPC_ID} --attribute enableDnsHostnames
```

```json:結果:
   {
       "VpcId": "vpc-9010b5f5", 
       "EnableDnsHostnames": {
           "Value": false
       }, 
       "EnableDnsSupport": {}
   }
```

デフォルトでは無効になっています。


2. VPC作成と同時に自動作成されるリソースの確認
==============================================



2.1. RouteTableの確認
---------------------

VPCに割り当てられているルートテーブルを確認してみましょう。

(最初はローカルネットワークのエントリしかありません。)

```bash:コマンド:
   $ aws ec2 describe-route-tables --filters Name=vpc-id,Values=${VPC_ID}
```

```json:結果:
   {
     "RouteTables": [
         {
             "Associations": [
                 {
                     "RouteTableAssociationId": "rtbassoc-XXXXXXXX",
                     "Main": true,
                     "RouteTableId": "rtb-XXXXXXXX"
                 }
             ],
             "RouteTableId": "rtb-XXXXXXXX",
             "VpcId": "vpc-XXXXXXXX",
             "PropagatingVgws": [],
             "Tags": [],
             "Routes": [
                 {
                     "GatewayId": "local",
                     "DestinationCidrBlock": "10.192.0.0/16",
                     "State": "active",
                     "Origin": "CreateRouteTable"
                 }
             ]
         }
     ]
   }
```


2.2. NACLの確認
---------------

デフォルトのNACL(Network Access Control List)を確認します。

```bash:コマンド:
   $ aws ec2 describe-network-acls --filters Name=vpc-id,Values=${VPC_ID}
```

```json:結果:
   {
     "NetworkAcls": [
         {
             "Associations": [],
             "NetworkAclId": "acl-XXXXXXXX",
             "VpcId": "vpc-XXXXXXXX",
             "Tags": [],
             "Entries": [
                 {
                     "CidrBlock": "0.0.0.0/0",
                     "RuleNumber": 100,
                     "Protocol": "-1",
                     "Egress": true,
                     "RuleAction": "allow"
                 },
                 {
                     "CidrBlock": "0.0.0.0/0",
                     "RuleNumber": 32767,
                     "Protocol": "-1",
                     "Egress": true,
                     "RuleAction": "deny"
                 },
                 {
                     "CidrBlock": "0.0.0.0/0",
                     "RuleNumber": 100,
                     "Protocol": "-1",
                     "Egress": false,
                     "RuleAction": "allow"
                 },
                 {
                     "CidrBlock": "0.0.0.0/0",
                     "RuleNumber": 32767,
                     "Protocol": "-1",
                     "Egress": false,
                     "RuleAction": "deny"
                 }
             ],
             "IsDefault": true
         }
     ]
   }
```


2.3. セキュリティグループの確認
-------------------------------

デフォルトのセキュリティグループを確認します。 

(2つのセキュリティグループが存在します。)

```bash:コマンド:
   $ aws ec2 describe-security-groups --filters Name=vpc-id,Values=${VPC_ID}
```

```json:結果:
   {
     "SecurityGroups": [
         {
             "IpPermissionsEgress": [
                 {
                     "IpProtocol": "-1",
                     "IpRanges": [
                         {
                             "CidrIp": "0.0.0.0/0"
                         }
                     ],
                     "UserIdGroupPairs": []
                 }
             ],
             "Description": "default VPC security group",
             "IpPermissions": [
                 {
                     "IpProtocol": "-1",
                     "IpRanges": [],
                     "UserIdGroupPairs": [
                         {
                             "UserId": "XXXXXXXXXXXX",
                             "GroupId": "sg-XXXXXXXX"
                         }
                     ]
                 }
             ],
             "GroupName": "default",
             "VpcId": "vpc-XXXXXXXX",
             "OwnerId": "XXXXXXXXXXXX",
             "GroupId": "sg-XXXXXXXX"
         }
     ]
   }
```


3. IGWの割り当て
================


3.1. 未アタッチのIGWの検索
--------------------------

まず、どのVPCにもアタッチされていないIGWをさがします。 

(通常は、未割当てのIGWは存在しないはずです。)

```bash:コマンド:
   $ aws ec2 describe-internet-gateways | jq -r '.InternetGateways[] | select(.Attachments == []).InternetGatewayId'
```

```text:結果:
   (戻り値なし)
```


3.2. IGWの作成 (未アタッチIGWが存在しない場合)
----------------------------------------------

未アタッチのIGWが存在しない場合は、IGWを作成します。

```bash:コマンド:
   $ aws ec2 create-internet-gateway
```

```json:結果:
   {
       "InternetGateway": {
           "Tags": [],
           "InternetGatewayId": "igw-XXXXXXXX",
           "Attachments": []
       }
   }
```


3.3. IGW IDの取得
-----------------

作成した(未アタッチの)IGWのInternet Gateway IDを取得します。

```bash:コマンド:
   $ VPC_IGW_ID=`aws ec2 describe-internet-gateways | jq -r '.InternetGateways[] | select(.Attachments == []).InternetGatewayId'` && echo ${VPC_IGW_ID}
```

ノート: このコマンドラインは、未アタッチのIGW IDが複数存在する場合、全てのID を取り込んでしまうので、適宜処理してください。

```text:結果:
   igw-XXXXXXXX
```


3.4. IGWのVPCへのアタッチ
-------------------------

IGWをVPCにアタッチします。

```bash:コマンド:
   $ aws ec2 attach-internet-gateway --internet-gateway-id ${VPC_IGW_ID} --vpc-id ${VPC_ID}
```

```text:結果:
   (戻り値なし)
```


3.5. IGWの確認
--------------

IGWがVPCにアタッチされて、有効になっていることを確認します。

```bash:コマンド:
   $ aws ec2 describe-internet-gateways --internet-gateway-ids ${VPC_IGW_ID}
```

```json:結果:
   {
       "InternetGateways": [
           {
               "Tags": [], 
               "InternetGatewayId": "igw-XXXXXXXX", 
               "Attachments": [
                   {
                       "State": "available", 
                       "VpcId": "vpc-XXXXXXXX"
                   }
               ]
           }
       ]
   }
```

ステータスだけ取りたい場合

```bash:コマンド:
   $ aws ec2 describe-internet-gateways --internet-gateway-ids ${VPC_IGW_ID} --query 'InternetGateways[].Attachments[].State' --output text
```

```text:結果:
   available
```


4. Private Subnetの作成
=======================


4.1. 未割当てルートテーブルの確認
---------------------------------

未割当てのルートテーブルが存在しないか確認します。 

(通常は、未割当てのルートテーブルは存在しないはずです。)

```bash:コマンド:
   $ aws ec2 describe-route-tables | jq -r '.RouteTables[] | select(.Associations == []) | .RouteTableId'
```

```text:結果:
   (戻り値なし)
```


4.2. ルートテーブル作成 (Private Subnet用)
------------------------------------------

### -[ ルートテーブル作成 (Private Subnet用) ]-

Private Subnet用のルートテーブルを作成します。

```bash:コマンド:
   $ aws ec2 create-route-table --vpc-id ${VPC_ID}
```

```json:結果:
   {
       "RouteTable": {
           "Associations": [],
           "RouteTableId": "rtb-XXXXXXXX",
           "VpcId": "vpc-XXXXXXXX",
           "PropagatingVgws": [],
           "Tags": [],
           "Routes": [
               {
                   "GatewayId": "local",
                   "DestinationCidrBlock": "10.192.0.0/16",
                   "State": "active",
                   "Origin": "CreateRouteTable"
               }
           ]
       }
   }
```

### -[ ルートテーブルIDの取得 (Private Subnet用) ]-

作成したルートテーブルのRoute Table IDを取得します。

```bash:コマンド:
   $ VPC_ROUTE_TABLE_ID=`aws ec2 describe-route-tables | jq -r '.RouteTables[] | select(.Associations == []) | .RouteTableId'` && echo ${VPC_ROUTE_TABLE_ID}
```

```text:結果:
   rtb-XXXXXXXX
```

```bash:コマンド:
   $ VPC_RT_ID_PRIVATE=${VPC_ROUTE_TABLE_ID}
```

ノート: このコマンドラインは、未割当てのルートテーブルが複数存在する場合、全 てのIDを取り込んでしまうので、適宜処理してください。

### -[ ルートテーブルの確認 (Private Subnet用) ]-

作成したルートテーブルの内容を確認します。

(localへのルーティングだけが存在します。)

```bash:コマンド:
   $ aws ec2 describe-route-tables --route-table-ids ${VPC_RT_ID_PRIVATE}
```

```json:結果:
   {
       "RouteTables": [
           {
               "Associations": [], 
               "RouteTableId": "rtb-XXXXXXXX", 
               "VpcId": "vpc-XXXXXXXX", 
               "PropagatingVgws": [], 
               "Tags": [], 
               "Routes": [
                   {
                       "GatewayId": "local", 
                       "DestinationCidrBlock": "10.192.0.0/16", 
                       "State": "active", 
                       "Origin": "CreateRouteTable"
                   }
               ]
           }
       ]
   }
```


4.3. Subnet01の作成 (Private/ap-northeast-1a)
---------------------------------------------

### -[ Subnetの作成 ]-

Subnet01を作成します。

```bash:コマンド:
   $ aws ec2 create-subnet --vpc-id ${VPC_ID} --cidr-block ${VPC_NET01_ADDR} --availability-zone ${VPC_NET01_AZ}
```

```json:結果:
   {
     "Subnet": {
         "VpcId": "vpc-XXXXXXXX",
         "CidrBlock": "10.192.1.0/24",
         "State": "pending",
         "AvailabilityZone": "ap-northeast-1a",
         "SubnetId": "subnet-XXXXXXXX",
         "AvailableIpAddressCount": 251
     }
   }
```

### -[ Subnet Idの取得 ]-

Subnet01のSubnet Idを取得します。

```bash:コマンド:
   $ VPC_NET01_ID=`aws ec2 describe-subnets --filters Name=cidrBlock,Values=${VPC_NET01_ADDR} --query Subnets[].SubnetId --output text`;echo ${VPC_NET01_ID}
```

```text:結果:
   subnet-XXXXXXXX
```

### -[ Subnet01の確認 ]-

```bash:コマンド:
   $ aws ec2 describe-subnets --filters Name=cidrBlock,Values=${VPC_NET01_ADDR}
```

```json:結果:
   {
     "Subnets": [
         {
             "VpcId": "vpc-XXXXXXXX",
             "CidrBlock": "10.192.1.0/24",
             "MapPublicIpOnLaunch": false,
             "DefaultForAz": false,
             "State": "available",
             "AvailabilityZone": "ap-northeast-1a",
             "SubnetId": "subnet-XXXXXXXX",
             "AvailableIpAddressCount": 251
         }
     ]
   }
```

### -[ ルートテーブルのアサイン ]-

Private Subnet用ルートテーブルをSubnet01にアサインします。

```bash:コマンド:
   $ aws ec2 associate-route-table --route-table-id ${VPC_RT_ID_PRIVATE} --subnet-id ${VPC_NET01_ID}
```

```json:結果:
   {
     "AssociationId": "rtbassoc-XXXXXXXX"
   }
```

### -[ ルートテーブルの確認 ]-

Private Subnet用ルートテーブルのアサイン状況を確認します。

```bash:コマンド:
   $ aws ec2 describe-route-tables --route-table-ids ${VPC_RT_ID_PRIVATE}
```

```json:結果:
   {
     "RouteTables": [
         {
             "Associations": [
                 {
                     "SubnetId": "subnet-XXXXXXXX",
                     "RouteTableAssociationId": "rtbassoc-XXXXXXXX",
                     "Main": false,
                     "RouteTableId": "rtb-XXXXXXXX"
                 }
             ],
             "RouteTableId": "rtb-XXXXXXXX",
             "VpcId": "vpc-XXXXXXXX",
             "PropagatingVgws": [],
             "Tags": [],
             "Routes": [
                 {
                     "GatewayId": "local",
                     "DestinationCidrBlock": "10.192.0.0/16",
                     "State": "active",
                     "Origin": "CreateRouteTable"
                 }
             ]
         }
     ]
   }
```


4.4. Subnet03の作成 (Private/ap-northeast-1c)
---------------------------------------------

### -[ Subnetの作成 ]-

Subnet03を作成します。

```bash:コマンド:
   $ aws ec2 create-subnet --vpc-id ${VPC_ID} --cidr-block ${VPC_NET03_ADDR} --availability-zone ${VPC_NET03_AZ}
```

```json:結果:
   {
     "Subnet": {
         "VpcId": "vpc-XXXXXXXX",
         "CidrBlock": "10.192.3.0/24",
         "State": "pending",
         "AvailabilityZone": "ap-northeast-1c",
         "SubnetId": "subnet-XXXXXXXX",
         "AvailableIpAddressCount": 251
     }
   }
```

### -[ Subnet Idの取得 ]-

Subnet03のSubnet Idを取得します。

```bash:コマンド:
   $ VPC_NET03_ID=`aws ec2 describe-subnets --filters Name=cidrBlock,Values=${VPC_NET03_ADDR} --query Subnets[].SubnetId --output text`;echo ${VPC_NET03_ID}
```

```text:結果:
   subnet-XXXXXXXX
```

### -[ Subnet03の確認 ]-

```bash:コマンド:
   $ aws ec2 describe-subnets --filters Name=cidrBlock,Values=${VPC_NET03_ADDR}
```

```json:結果:
   {
     "Subnets": [
         {
             "VpcId": "vpc-XXXXXXXX",
             "CidrBlock": "10.192.3.0/24",
             "MapPublicIpOnLaunch": false,
             "DefaultForAz": false,
             "State": "available",
             "AvailabilityZone": "ap-northeast-1c",
             "SubnetId": "subnet-XXXXXXXX",
             "AvailableIpAddressCount": 251
         }
     ]
   }
```

### -[ ルートテーブルのアサイン ]-

Private Subnet用ルートテーブルをSubnet03にアサインします。

```bash:コマンド:
   $ aws ec2 associate-route-table --route-table-id ${VPC_RT_ID_PRIVATE} --subnet-id ${VPC_NET03_ID}
```

```json:結果:
   {
     "AssociationId": "rtbassoc-XXXXXXXX"
   }
```

### -[ ルートテーブルの確認 ]-

Private Subnet用ルートテーブルのアサイン状況を確認します。

```bash:コマンド:
   $ aws ec2 describe-route-tables --route-table-ids ${VPC_RT_ID_PRIVATE}
```

```json:結果:
   {
     "RouteTables": [
         {
             "Associations": [
                 {
                     "SubnetId": "subnet-XXXXXXXX",
                     "RouteTableAssociationId": "rtbassoc-XXXXXXXX",
                     "Main": false,
                     "RouteTableId": "rtb-XXXXXXXX"
                 },
                 {
                     "SubnetId": "subnet-XXXXXXXX",
                     "RouteTableAssociationId": "rtbassoc-XXXXXXXX",
                     "Main": false,
                     "RouteTableId": "rtb-XXXXXXXX"
                 }
             ],
             "RouteTableId": "rtb-XXXXXXXX",
             "VpcId": "vpc-XXXXXXXX",
             "PropagatingVgws": [],
             "Tags": [],
             "Routes": [
                 {
                     "GatewayId": "local",
                     "DestinationCidrBlock": "10.192.0.0/16",
                     "State": "active",
                     "Origin": "CreateRouteTable"
                 }
             ]
         }
     ]
   }
```

以上でPrivate Subnetの作成は完了です。


5. Public Subnetの作成
======================


5.1. ルートテーブル作成 (Public Subnet用)
-----------------------------------------

### -[ ルートテーブル作成 (Public Subnet用) ]-

Public Subnet用のルートテーブルを作成します。

```bash:コマンド:
   $ aws ec2 create-route-table --vpc-id ${VPC_ID}
```

```json:結果:
   {
       "RouteTable": {
           "Associations": [],
           "RouteTableId": "rtb-XXXXXXXX",
           "VpcId": "vpc-XXXXXXXX",
           "PropagatingVgws": [],
           "Tags": [],
           "Routes": [
               {
                   "GatewayId": "local",
                   "DestinationCidrBlock": "10.192.0.0/16",
                   "State": "active",
                   "Origin": "CreateRouteTable"
               }
           ]
       }
   }
```

### -[ ルートテーブルIDの取得 (Public Subnet用) ]-

作成したルートテーブルのRoute Table IDを取得します。

```bash:コマンド:
   $ VPC_ROUTE_TABLE_ID=`aws ec2 describe-route-tables | jq -r '.RouteTables[] | select(.Associations == []) | .RouteTableId'` && echo ${VPC_ROUTE_TABLE_ID}
```

```text:結果:
   rtb-XXXXXXXX
```

```bash:コマンド:
   $ VPC_RT_ID_PUBLIC=${VPC_ROUTE_TABLE_ID}
```

ノート: このコマンドラインは、未割当てのルートテーブルが複数存在する場合、全てのIDを取り込んでしまうので、適宜処理してください。

### -[ ルートテーブルの確認 (Public Subnet用) ]-

作成したルートテーブルの内容を確認します。

```bash:コマンド:
   $ aws ec2 describe-route-tables --route-table-ids ${VPC_RT_ID_PUBLIC}
```

```json:結果:
   {
       "RouteTables": [
           {
               "Associations": [], 
               "RouteTableId": "rtb-XXXXXXXX", 
               "VpcId": "vpc-XXXXXXXX", 
               "PropagatingVgws": [], 
               "Tags": [], 
               "Routes": [
                   {
                       "GatewayId": "local", 
                       "DestinationCidrBlock": "10.192.0.0/16", 
                       "State": "active", 
                       "Origin": "CreateRouteTable"
                   }
               ]
           }
       ]
   }
```

### -[ デフォルトルート作成 (Public Subnet用) ]-

Public Subnetでは、インターネットへの出口を指定する必要があります。

ここでは、0.0.0.0/0(デフォルトルート)をIGWに向けるルーティングを追加します。

```bash:コマンド:
   $ aws ec2 create-route --route-table-id ${VPC_RT_ID_PUBLIC} --destination-cidr-block 0.0.0.0/0 --gateway-id ${VPC_IGW_ID}
```

```text:結果:
   (戻り値なし)
```

### -[ ルートテーブルの確認 (Public Subnet用) ]-

作成したルートテーブルの内容を確認します。 

(localとIGWへのルーティングが存在します。)

```bash:コマンド:
   $ aws ec2 describe-route-tables --route-table-ids ${VPC_RT_ID_PUBLIC}
```

```json:結果:
   {
     "RouteTables": [
         {
             "Associations": [],
             "RouteTableId": "rtb-XXXXXXXX",
             "VpcId": "vpc-XXXXXXXX",
             "PropagatingVgws": [],
             "Tags": [],
             "Routes": [
                 {
                     "GatewayId": "local",
                     "DestinationCidrBlock": "10.192.0.0/16",
                     "State": "active",
                     "Origin": "CreateRouteTable"
                 },
                 {
                     "GatewayId": "igw-XXXXXXXX",
                     "DestinationCidrBlock": "0.0.0.0/0",
                     "State": "active",
                     "Origin": "CreateRoute"
                 }
             ]
         }
     ]
   }
```


5.2. Subnet11の作成 (Public/ap-northeast-1a)
--------------------------------------------

### -[ Subnetの作成 ]-

Subnet11を作成します。

```bash:コマンド:
   $ aws ec2 create-subnet --vpc-id ${VPC_ID} --cidr-block ${VPC_NET11_ADDR} --availability-zone ${VPC_NET11_AZ}
```

```json:結果:
   {
     "Subnet": {
         "VpcId": "vpc-XXXXXXXX",
         "CidrBlock": "10.192.129.0/24",
         "State": "pending",
         "AvailabilityZone": "ap-northeast-1a",
         "SubnetId": "subnet-XXXXXXXX",
         "AvailableIpAddressCount": 251
     }
   }
```

### -[ Subnet Idの取得 ]-

Subnet11のSubnet Idを取得します。

```bash:コマンド:
   $ VPC_NET11_ID=`aws ec2 describe-subnets --filters Name=cidrBlock,Values=${VPC_NET11_ADDR} --query Subnets[].SubnetId --output text`;echo ${VPC_NET11_ID}
```

```text:結果:
   subnet-XXXXXXXX
```

### -[ Subnet11の確認 ]-

```bash:コマンド:
   $ aws ec2 describe-subnets --filters Name=cidrBlock,Values=${VPC_NET11_ADDR}
```

```json:結果:
   {
     "Subnets": [
         {
             "VpcId": "vpc-XXXXXXXX",
             "CidrBlock": "10.192.129.0/24",
             "MapPublicIpOnLaunch": false,
             "DefaultForAz": false,
             "State": "available",
             "AvailabilityZone": "ap-northeast-1a",
             "SubnetId": "subnet-XXXXXXXX",
             "AvailableIpAddressCount": 251
         }
     ]
   }
```

### -[ ルートテーブルのアサイン ]-

Public Subnet用ルートテーブルをSubnet11にアサインします。

```bash:コマンド:
   $ aws ec2 associate-route-table --route-table-id ${VPC_RT_ID_PUBLIC} --subnet-id ${VPC_NET11_ID}
```

```json:結果:
   {
     "AssociationId": "rtbassoc-XXXXXXXX"
   }
```

### -[ ルートテーブルの確認 ]-

Private Subnet用ルートテーブルのアサイン状況を確認します。

```bash:コマンド:
   $ aws ec2 describe-route-tables --route-table-ids ${VPC_RT_ID_PUBLIC}
```

```json:結果:
   {
     "RouteTables": [
         {
             "Associations": [
                 {
                     "SubnetId": "subnet-XXXXXXXX",
                     "RouteTableAssociationId": "rtbassoc-XXXXXXXX",
                     "Main": false,
                     "RouteTableId": "rtb-XXXXXXXX"
                 }
             ],
             "RouteTableId": "rtb-XXXXXXXX",
             "VpcId": "vpc-XXXXXXXX",
             "PropagatingVgws": [],
             "Tags": [],
             "Routes": [
                 {
                     "GatewayId": "local",
                     "DestinationCidrBlock": "10.192.0.0/16",
                     "State": "active",
                     "Origin": "CreateRouteTable"
                 },
                 {
                     "GatewayId": "igw-XXXXXXXX",
                     "DestinationCidrBlock": "0.0.0.0/0",
                     "State": "active",
                     "Origin": "CreateRoute"
                 }
             ]
         }
     ]
   }
```


5.3. Subnet13の作成 (Public/ap-northeast-1c)
--------------------------------------------

Subnet13を作成します。

### -[ Subnetの作成 ]-

```bash:コマンド:
   $ aws ec2 create-subnet --vpc-id ${VPC_ID} --cidr-block ${VPC_NET13_ADDR} --availability-zone ${VPC_NET13_AZ}
```

```json:結果:
   {
     "Subnet": {
         "VpcId": "vpc-XXXXXXXX",
         "CidrBlock": "10.192.131.0/24",
         "State": "pending",
         "AvailabilityZone": "ap-northeast-1c",
         "SubnetId": "subnet-XXXXXXXX",
         "AvailableIpAddressCount": 251
     }
   }
```

### -[ Subnet Idの取得 ]-

Subnet13のSubnet Idを取得します。

```bash:コマンド:
   $ VPC_NET13_ID=`aws ec2 describe-subnets --filters Name=cidrBlock,Values=${VPC_NET13_ADDR} --query Subnets[].SubnetId --output text`;echo ${VPC_NET13_ID}
```

```text:結果:
   subnet-XXXXXXXX
```

### -[ Subnet13の確認 ]-

```bash:コマンド:
   $ aws ec2 describe-subnets --filters Name=cidrBlock,Values=${VPC_NET13_ADDR}
```

```json:結果:
   {
     "Subnets": [
         {
             "VpcId": "vpc-XXXXXXXX",
             "CidrBlock": "10.192.131.0/24",
             "MapPublicIpOnLaunch": false,
             "DefaultForAz": false,
             "State": "available",
             "AvailabilityZone": "ap-northeast-1c",
             "SubnetId": "subnet-XXXXXXXX",
             "AvailableIpAddressCount": 251
         }
     ]
   }
```

### -[ ルートテーブルのアサイン ]-

Public Subnet用ルートテーブルをSubnet13にアサインします。

```bash:コマンド:
   $ aws ec2 associate-route-table --route-table-id ${VPC_RT_ID_PUBLIC} --subnet-id ${VPC_NET13_ID}
```

```json:結果:
   {
     "AssociationId": "rtbassoc-XXXXXXXX"
   }
```

### -[ ルートテーブルの確認 ]-

```bash:コマンド:
   $ aws ec2 describe-route-tables --route-table-ids ${VPC_RT_ID_PUBLIC}
```

```json:結果:
   {
     "RouteTables": [
         {
             "Associations": [
                 {
                     "SubnetId": "subnet-XXXXXXXX",
                     "RouteTableAssociationId": "rtbassoc-XXXXXXXX",
                     "Main": false,
                     "RouteTableId": "rtb-XXXXXXXX"
                 },
                 {
                     "SubnetId": "subnet-XXXXXXXX",
                     "RouteTableAssociationId": "rtbassoc-XXXXXXXX",
                     "Main": false,
                     "RouteTableId": "rtb-XXXXXXXX"
                 }
             ],
             "RouteTableId": "rtb-XXXXXXXX",
             "VpcId": "vpc-XXXXXXXX",
             "PropagatingVgws": [],
             "Tags": [],
             "Routes": [
                 {
                     "GatewayId": "local",
                     "DestinationCidrBlock": "10.192.0.0/16",
                     "State": "active",
                     "Origin": "CreateRouteTable"
                 },
                 {
                     "GatewayId": "igw-XXXXXXXX",
                     "DestinationCidrBlock": "0.0.0.0/0",
                     "State": "active",
                     "Origin": "CreateRoute"
                 }
             ]
         }
     ]
   }
```


5.4. MapPublicIpOnLaunchの有効化
--------------------------------

ここでは、Subnet13について、起動したインスタンスに自動的にPublic IPアドレスが付与されるように設定を変更します。

### -[ Subnet13の確認 ]-

Subnet13の内容(初期状態)を確認します。 

(MapPublicIpOnLaunchがfalseになっているはずです。)

```bash:コマンド:
   $ aws ec2 describe-subnets --filters Name=cidrBlock,Values=${VPC_NET13_ADDR}
```

```json:結果:
   {
     "Subnets": [
         {
             "VpcId": "vpc-XXXXXXXX",
             "CidrBlock": "10.192.131.0/24",
             "MapPublicIpOnLaunch": false,
             "DefaultForAz": false,
             "State": "available",
             "AvailabilityZone": "ap-northeast-1c",
             "SubnetId": "subnet-XXXXXXXX",
             "AvailableIpAddressCount": 251
         }
     ]
   }
```

### -[ Public IPの設定 (MapPublicIpOnLaunch) ]-

MapPublicIpOnLaunchを有効化します。

```bash:コマンド:
   $ aws ec2 modify-subnet-attribute --subnet-id ${VPC_NET13_ID} --map-public-ip-on-launch
```

```text:結果:
   (戻り値なし)
```

### -[ Subnet13の確認 ]-

Subnet13の内容を確認します。 

(MapPublicIpOnLaunchがtrueになっているはずです。)

```bash:コマンド:
   $ aws ec2 describe-subnets --filters Name=cidrBlock,Values=${VPC_NET13_ADDR}
```

```json:結果:
   {
     "Subnets": [
         {
             "VpcId": "vpc-XXXXXXXX",
             "CidrBlock": "10.192.131.0/24",
             "MapPublicIpOnLaunch": true,
             "DefaultForAz": false,
             "State": "available",
             "AvailabilityZone": "ap-northeast-1c",
             "SubnetId": "subnet-XXXXXXXX",
             "AvailableIpAddressCount": 251
         }
     ]
   }
```


6. セキュリティグループの作成
=============================

セキュリティグループを作成します。 ここでは、インターネット側からSSHデーモンへのアクセスを許可する設定をしてみます。


6.1. セキュリティグループの作成
-------------------------------

セキュリティグループを作成します。

```bash:コマンド:
   $ VPC_SG_NAME='SSHLoginSecurityGroup'
   $ VPC_SG_DESCRIPT='SSH Login security group'
   $ aws ec2 create-security-group --group-name ${VPC_SG_NAME} --description "${VPC_SG_DESCRIPT}" --vpc-id ${VPC_ID}
```

```json:結果:
   {
     "GroupId": "sg-XXXXXXXX"
   }
```


6.2. セキュリティグループIDの取得
---------------------------------

作成したセキュリティグループのセキュリティグループIDを取得します。

```bash:コマンド:
   $ VPC_SG_ID=`aws ec2 describe-security-groups --filters Name=group-name,Values=${VPC_SG_NAME} --query 'SecurityGroups[].GroupId' --output text`; echo ${VPC_SG_ID}
```

```text:結果:
   sg-XXXXXXXX
```


6.3. セキュリティグループの確認
-------------------------------

作成したセキュリティグループの内容を確認します。

(作成時点では、何も許可されていません。)

```bash:コマンド:
   $ aws ec2 describe-security-groups --group-ids ${VPC_SG_ID}
```

```json:結果:
   {
     "SecurityGroups": [
         {
             "IpPermissionsEgress": [
                 {
                     "IpProtocol": "-1",
                     "IpRanges": [
                         {
                             "CidrIp": "0.0.0.0/0"
                         }
                     ],
                     "UserIdGroupPairs": []
                 }
             ],
             "Description": "SSH Login security group",
             "IpPermissions": [],
             "GroupName": "SSHLoginSecurityGroup",
             "VpcId": "vpc-XXXXXXXX",
             "OwnerId": "XXXXXXXXXXXX",
             "GroupId": "sg-XXXXXXXX"
         }
     ]
   }
```


6.4. Inboundルールの追加
------------------------

インターネット全体(0.0.0.0/0)から22/TCPへのアクセス許可ルールを追加します。

```bash:コマンド:
   $ VPC_SG_PROTOCOL='tcp'
   $ VPC_SG_PORT='22'
   $ VPC_SG_CIDR='0.0.0.0/0'
   $ aws ec2 authorize-security-group-ingress --group-id ${VPC_SG_ID} \
     --protocol ${VPC_SG_PROTOCOL} --port ${VPC_SG_PORT} \
     --cidr ${VPC_SG_CIDR}
```

```text:結果:
   (戻り値なし)
```

ノート: SSHデーモンは不正目的でのアクセスが非常に多いサービスです。
  本ハンズオンでは、便宜上インターネットのどこから(0.0.0.0/0)でもアクセスできるように許可していますが、特に本番環境などでは特定IPアドレスからのみ許可するようにしてください。


6.5. セキュリティグループの確認
-------------------------------

ルール追加後のセキュリティグループの内容を確認します。

```bash:コマンド:
   $ aws ec2 describe-security-groups --group-ids ${VPC_SG_ID}
```

```json:結果:
   {
     "SecurityGroups": [
         {
             "IpPermissionsEgress": [
                 {
                     "IpProtocol": "-1",
                     "IpRanges": [
                         {
                             "CidrIp": "0.0.0.0/0"
                         }
                     ],
                     "UserIdGroupPairs": []
                 }
             ],
             "Description": "SSH Login security group",
             "IpPermissions": [
                 {
                     "ToPort": 22,
                     "IpProtocol": "tcp",
                     "IpRanges": [
                         {
                             "CidrIp": "0.0.0.0/0"
                         }
                     ],
                     "UserIdGroupPairs": [],
                     "FromPort": 22
                 }
             ],
             "GroupName": "SSHLoginSecurityGroup",
             "VpcId": "vpc-XXXXXXXX",
             "OwnerId": "XXXXXXXXXXXX",
             "GroupId": "sg-XXXXXXXX"
         }
     ]
   }
```



7. タグの追加
=============

タグを追加します。 ここでは、先程作成したセキュリティグループにタグを付けてみます。


7.1. タグの確認
---------------

現時点でのタグを確認してみます。

(過去にタグを追加していなければ、タグは何も表示されないはずです。)

```bash:コマンド:
   $ aws ec2 describe-tags
```

```json:結果:
   {
     "Tags": []
   }
```


7.2. タグの追加
---------------

タグを追加します。

この例では、先程作成したセキュリティグループに以下のタグを追加しています。

キー:   'PORT'
値:   'SSH'

```bash:コマンド:
   $ VPC_TAG_RESOURCE=${VPC_SG_ID}
   $ VPC_TAG_KEY='PORT'; VPC_TAG_VALUE='SSH'

   $ aws ec2 create-tags --resources ${VPC_TAG_RESOURCE} \
     --tags Key=${VPC_TAG_KEY},Value=${VPC_TAG_VALUE}
```

```text:結果:
   (戻り値なし)
```


7.3. タグの確認
---------------

タグを検索してみましょう。

### -[ リソースタイプで検索する例 (JSON形式) ]-

```bash:コマンド:
   $ VPC_RESOURCE_TYPE='security-group'
   $ aws ec2 describe-tags --filters Name=resource-type,Values=${VPC_RESOURCE_TYPE}
```

```json:結果:
   {
     "Tags": [
         {
             "ResourceType": "security-group",
             "ResourceId": "sg-XXXXXXXX",
             "Value": "SSH",
             "Key": "PORT"
         }
     ]
   }
```

### -[ キーで検索する例 (table形式) ]-

```bash:コマンド:
   $ VPC_TAG_KEY='PORT'
   $ aws ec2 describe-tags --filters Name=key,Values=${VPC_TAG_KEY} --output table
```

```text:結果:
   ------------------------------------------------------
   |                    DescribeTags                    |
   +----------------------------------------------------+
   ||                       Tags                       ||
   |+------+---------------+------------------+--------+|
   ||  Key |  ResourceId   |  ResourceType    | Value  ||
   |+------+---------------+------------------+--------+|
   ||  PORT|  sg-XXXXXXXX  |  security-group  |  SSH   ||
   |+------+---------------+------------------+--------+|
```


VPC利用例
=========

以上で、VPCの作成ハンズオンは完了です。

以下のAWSプロダクトでVPCを利用してみましょう。

* 利用例 (EC2): http://qiita.com/tcsh/items/b68ec66cf5de5a868ac7