CLIでのVPC作成手順

# 目的
AWSは『他のお客様とは論理的に異るデータセンターをコマンドラインから作る』ことができます
コマンドラインから作れる、というのは凄い。 物理的なデータセンターの構築をする場合、
データセンター選定、データセンター業者との契約、ラックの設置、ロードバランサー/ファイアーウォール設置と設定、サーバ搬入/設定
など最低でも2ヵ月程度はかかります( 実際には3ヵ月程度かかりませんか... いやまぁどうでもいい話ですが )

VPCだと( AWSアカウントがセットアップ済み、aws-cliでスクリプトを書けば )数分程度でVPCが立ち上がってきます。
既存インフラエンジニア観点だと、この点は驚異的です。こちらの方が良い。例えば
「AWSなら限界まで負荷テストしていいですよ」「壊れるまで検証していいですよ。困るのは貴方だけです」って言えます( オンプレだと言えないと思います...  もし開発者単位でVPCを用意する環境が可能な運用であればですが )

# 用語
* VPC(Virtual Private Cloud)
 ほかのお客様とは論理的に異る仮想的なデータセンター

* Availability Zone( 以下 AZ)
 コンクリートで囲まれたデータセンター
 一つのVPCの中に複数のAZ, データセンターを持つことができる

* サブネット
 一つのデータセンター内のネットワーク、VPCは複数のサブネットを含むような広さを持つ必要がある

 ネットワークの大きさ、サブネットというと習慣的に192.168.10.0/24( あるいは大きいセグメントが必要な環境であれば 10.10.1.0/16 など )とか切りたくなるとは思うのですが、
 AWSの場合、複数のAZを持ちたくなります。だって複数のデータセンターを持てるって凄いですし。
 ( データセンターまるごと落ちても冗長可能な構成ってオンプレだと非常にコストがかかる )
 あとAWSの推奨として、DC障害対応するように、ということなので。

 そういう背景もあって、サブネットは『複数のサブネットを内包できる位の小ささにする必要』があります。

# 事前に決めておくこと
* VPCのセグメント
  ( 複数VPCを接続するような要件がある場合、例えば『監視サーバは中央VPCに置いて、複数VPCの要素を監視したい。複数VPCをスター型で構成する』といった要件を除いて )複数サブネットを内包できる大きさである必要があると思います。

* サブネット
  上記VPCに最低2個は含めることができる位の小ささである必要があります。
  ( 複数DCを持てるように )
  
# 前提条件
* [AWSアカウントのセットアップ済みであること](http://qiita.com/tin-machine/items/3db108ceffa24acc76fd)

* aws-cliのセットアップ済みであること

# 参考
http://qiita.com/tcsh/items/41e1aa3c77c469c92e84
( aws-cli部会には行かねば... )

# 作成手順
## VPCの作成

```bash:既存の設定とかぶらないかチェック
 $ VPC_ADDR='10.10.0.0/16'
 $ aws ec2 describe-vpcs --filters "Name=cidr,Values=${VPC_ADDR}" --query 'Vpcs[].VpcId' --output text
```
空であることを確認

## VPC作成

```bash:VPC作成
 $ aws ec2 create-vpc --cidr-block ${VPC_ADDR}
```

```bash:VPCが作成されたことを確認
$ VPC_ID=$( aws ec2 describe-vpcs --filters "Name=cidr,Values=${VPC_ADDR}" --query 'Vpcs[].VpcId' --output text )
$ echo ${VPC_ID} 
```

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

『どこにも紐づいていないインターネットゲートウェイ』が存在しないかの確認
通常考えにくいが、どこにも紐づいていないインターネットゲートウェイも存在し得る。
( なにか他の人との共同作業の結果か、あるいは前回作業の失敗か )
存在していた場合は、消すか、あるいは、そのインターネットゲートウェイを用いるか判断する
まずは、そういったインターネットゲートウェイが存在しないか確認する

```bash:インターネットゲートウェイの確認
 $ aws ec2 describe-internet-gateways | jq -r '.InternetGateways[] | select(.Attachments == []).InternetGatewayId'
```

空であることを確認する

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

```bash
 $ VPC_IGW_ID=$( aws ec2 create-internet-gateway | jq -r '.InternetGateway.InternetGatewayId' )
```

```bash:作成したインターネットゲートウェイをアタッチ
 $ VPC_IGW_ID="igw-3d228959"
 $ aws ec2 attach-internet-gateway --internet-gateway-id ${VPC_IGW_ID} --vpc-id ${VPC_ID}
```

# サブネット作成
```bash:既に目的のサブネットが無いか確認する
 $ CIDR="10.10.0.0/20"
 $ aws ec2 describe-subnets --filters Name=cidrBlock,Values="${CIDR}" | jq -r '.Subnets[].SubnetId'
```

出力が無い事を確認

```bash:サブネットを作成
 $ AZ="ap-northeast-1a"
 $ aws ec2 create-subnet --vpc-id ${VPC_ID} --cidr-block "${CIDR}" --availability-zone "${AZ}"
```

# サブネットにルートテーブルを紐づける
```bash:ルートテーブル作成
 $ VPC_RT_ID_PUBLIC=$( aws ec2 create-route-table --vpc-id ${VPC_ID} | jq -r '.RouteTable.RouteTableId' )
```

```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}
```

# ルートをルートテーブルに紐づける
```bash:目的のサブネットIDを調べ、紐づける
 $ SUBNETID=$( aws ec2 describe-subnets --filters Name=cidrBlock,Values="${CIDR}" | jq -r '.Subnets[].SubnetId' )
 $ aws ec2 associate-route-table --route-table-id ${VPC_RT_ID_PUBLIC} --subnet-id ${SUBNETID}
```