【AWS】TerraformでVPC構築からEC2を動作させてみた#1(VPC作成編)
何をやるか
- 今まで手探りで動作させていたAWSを基礎から勉強しているのでそのメモ(Udemyで定番のあの教材です)
- ただコンソールを触っていても少しつまらないので同じく勉強中の
Terraform
を使う - 今回はVPCとサブネット作成までやります。
事前の予備知識
Terraformって?
- Vagrantを開発しているHashiCorp社が提供する
インフラ構成管理ツール
.tf
拡張子のファイルにインフラ構成を記述することで、構成通りのインフラが作成される(いわゆるIaC)何が嬉しい?
インフラをコードとして管理できるので下記のようなメリットがあるのかなって思います。
- Gitなどと連携させて、バージョン管理やコードレビュー
- 既存のインフラ構成の再利用
- 人為的なミスを防ぐ
VPC(Virtual Private Cloud)
- AWSのクラウド内に論理的に分離された自分の仮想NW
- 仮想NWをさらにサブネットで分けたり、ルートテーブルを作成してトラフィックを制御できる
- AWSのサービスによっては、VPC内に作成できないものがあるため注意しておく
- インターネットからアクセスを受けたいノード群とインターネットからアクセスを受けたくないノード群を分けたりする
- インターネットからアクセスを受ける方を
パブリックサブネット
、反対にアクセスを受けない方をプライベートサブネット
パブリックサブネット
にはIGW(インターネットGW)へルーティングできるようにしてあげる必要がある
- インターネットからアクセスを受ける方を
- VPC内のサブネットは/16 ~ /28から作成することができる
- VPCを構築すると仮想的なSWが同時に構築される
- ルートテーブルをサブネットと関連付けさせてサブネット間やインターネットへパケットを伝搬させる
VPC内のセキュリティ
- VPC内のリソースへのアクセス制限には
セキュリティグループ
とネットワークACL
がある セキュリティグループ
はEC2などのインスタンスレベルでルールの作成ができる。- ステートフルのためアウトバウンドについてはルールが不要
ネットワークACL
はサブネット単位でルールの作成をする- こちらはステートレスのため戻りの通信を含めてルールが必要
- クラスメソッドさんのブログが参考になりました
実装
作成するインフラ構成
- 単一AZにパブリックサブネットとプライベートサブネットを構築
- プライベートサブネットのEC2にはMYSQLをインストールして、パブリックサブネットのEC2からのみアクセスできるようにする
- RDSは別機会で
- NAT GWをパブリックサブネットに配置して開発者がSSH接続できるようにする
VPC作成
cidr_block
: VPC内利用するIPアドレスの範囲enable_dns_support
: DNSによる名前解決を有効化するかどうかenable_dns_hostnames
: パブリックIPアドレスをもつインスタンスの名前解決を有効にする
resource "aws_vpc" "example_vpc" { cidr_block = "10.0.0.0/16" enable_dns_support = true # DNS名前解決をサポート enable_dns_hostnames = true # パブリックIPアドレスをもつインスタンスの名前解決を有効化 tags = { Name = "Example" } }
ネットワーク周り
パブリックサブネット
サブネット作成
vpc_id
: 作成されたVPCのID(先ほど作成したVPCの出力値を利用する)map_public_ip_on_launch
: サブネット内で起動したインスタンスにパブリックIPアドレスを割り当てるかどうかaveilability_zone
: 作成するAZ
resource "aws_subnet" "example_public" { vpc_id = "${aws_vpc.example_vpc.id}" cidr_block = "10.0.1.0/24" map_public_ip_on_launch = true availability_zone = "ap-notrheast-1a" tags = { Name = "Example_Public_Subnet_northeast-1a" } }
インターネットGW
vpc_id
に作成したVPCのID
resource "aws_internet_gateway" "example_igw" { vpc_id = "${aws_vpc.example_vpc.id}" }
ルートテーブル
aws_route_table
でルートテーブルを作成vpc_id
に作成したVPCのID
aws_route
で実際のルートを定義する- インターネットGWとのルートを作成する
aws_route_table_association
でルートテーブルをサブネットにアタッチする
resource "aws_route_table" "example_public" { vpc_id = "${aws_vpc.example_vpc.id}" } resource "aws_route" "example_public" { route_table_id = "${aws_route_table.public.id}" gateway_id = "${aws_internet_gateway.example_igw.id}" destination_cidr_block = "0.0.0.0/0" } resource "aws_route_table_association" "example_public" { subnet_id = "${aws_subnet.example_public.id}" route_table_id = "${aws_route_table.example_public.id}" }
プライベートサブネット
サブネット作成
- パブリックIPの付与は必要ないため
map_public_ip_on_launch
はfalse
にする
resource "aws_subnet" "example_private" { vpc_id = "${aws_vpc.example_vpc.id}" cidr_block = "10.0.2.0./24" map_public_ip_on_launch = false availability_zone = "ap-northeast-1a" tags = { Name = "Exsample_Private_Subnet_ap-northeast-1a" } }
Elastic IPを作成
- NAT Gatewayに必要なElastic IPを作成する
aws_eip
で作成が可能- IGW作成後にリソースの作成がされるように
depends_on
に指定する- 依存関係がある場合には
depends_on
を指定しておく
- 依存関係がある場合には
NAT Gateway作成
allocation_id
に作成したElastic IPのIDを指定する- Elastic IP同様にIGWと依存関係があるため
depends_on
に指定する
resource "aws_nat_gateway" "example_nat_gateway" { allocation_id = "${aws_eip.example_nat_gateway.id}" subnet_id = "${aws_subnet.example_public.id}" depends_on = ["${aws_internet_gateway.example_igw}"] }
ルートテーブル
nat_gateway_id
で作成したNATGWをアタッチしておく
resource "aws_route_table" "example_private" { vpc_id = "${aws_vpc.example_vpc.id}" } resource "aws_route" "example_private" { route_table_id = "${aws_route.example_private.id}" nat_gateway_id = "${aws_nat_gateway.example_nat_gateway.id}" destination_cidr_block = "0.0.0.0/0" } resource "aws_route_table_association" "example_private" { subnet_id = "${aws_subnet.example_private.id}" route_table_id = "${aws_route_table.example_private.id}" }