はじめに
第1回では、TerraformでVPCを作った。
今回のテーマは、
Subnet。
ただ、今回もいきなりコードを書くわけじゃない。
まずはAWSコンソールでSubnetを作ったときのことを思い出してみる。
Subnetを作るとき、何を選んだ?
- VPCを選択
- CIDRを入力
- AZを選択
だいたいこの3つだったよね。
だからTerraformでも、基本的には同じことを書く。
今回は、
「Subnetを作るコードを覚える」
ではなく、
「なぜこのコードになるのか」
を理解する。
まず質問①
Subnetって、
どこに作る?
もちろん、
VPCの中。
じゃあTerraformでは、
「このSubnetは、このVPCの中に作ります」
と、どうやって伝えると思う?
ヒント。
昨日作ったVPCの名前は、
aws_vpc.main
だった。
さらに質問②
Public Subnetを作るとして、
CIDRは何にする?
昨日作ったVPCが、
10.0.0.0/16
だったら、
Public SubnetにはどんなCIDRを書けばいい?
昨日理解したことを思い出してみよう。
今日の目標
今日はまだコードを完成させなくていい。
まずは自分で考える。
特に理解してほしいのが、
vpc_id = aws_vpc.main.id
これ。
一見すると、
「VPCのIDを指定してるだけじゃん」
と思うかもしれない。
でも、ここにはTerraformのかなり重要な考え方が入っている。
それが、
「リソース同士をつなぐ」
という考え方。
ちなみに一つだけ
さっき、
「難しくて泣きそうだった」
って言ってたよね。
でも、その直後に、
「CIDR理解した!」
になった。
これ、SAPの勉強中にも何回もあった。
最初は、
「意味不明。」
↓
少し考える。
↓
「あ、そういうことか。」
この瞬間が一番伸びる。
だから今は、
「難しい」が来たら成長の前兆
くらいに思っておこう。
では、先生からの質問
Q1
Terraformでは、
「このSubnetはVPCの中に作ります」
をどう表現すればいい?
Q2
VPCが、
10.0.0.0/16
の場合、Public SubnetのCIDRはどんな値にする?
理由も一緒に考えてみよう。
ねこさんの回答
Q1
Subnetを作るときに
aws_vpc.mainを参照元にする。
Q2
CIDRを
10.0.1.0/24にする。
VPCの中にSubnetがあることを示すのと同時に、パブリックサブネット以外のサブネットを作るスペースを確保するため。
Q1のレビュー
かなりいい。
95点。
ただ、Terraformではもう一歩具体的に書く。
実際には、
vpc_id = aws_vpc.main.id
になる。
ここで重要なのが、
aws_vpc.main
と、
aws_vpc.main.id
は少し違うということ。
aws_vpc.main は、Terraformの中で参照しているVPCリソース。
そして、
aws_vpc.main.id
は、そのVPCのIDを取得している。
AWSでは、
vpc-0123456789abcdef
みたいなIDがある。
Terraformでは、
aws_vpc.main.id
と書くことで、そのVPCのIDを参照できる。
つまり、
vpc_id = aws_vpc.main.id
は、
「このSubnetを、aws_vpc.mainで作成したVPCに所属させてください」
という意味になる。
ここは超重要。
Q2のレビュー
これは、
100点。
10.0.1.0/24
でOK。
そして、理由がかなり良い。
「パブリックサブネット以外のサブネットを作るスペースを確保するため」
これ。
単に、
「10.0.1.0/24にするものだから」
ではなく、
将来的にPrivate SubnetやDB用Subnetなどを作ることを考えている。
これは設計するときに大事な考え方。
例えば、
VPC
10.0.0.0/16
の中に、
10.0.1.0/24 Public Subnet
10.0.2.0/24 Private Subnet
10.0.3.0/24 DB Subnet
のように、用途ごとにSubnetを分けられる。
つまり、
VPCのCIDRを決める
↓
その中からSubnet用のCIDRを切り出す
という流れ。
じゃあ、いよいよコード
まず、
resource "aws_subnet" "public" {
これはどう読む?
そのまま、
「publicという名前のSubnetを作ります」
でOK。
次。
vpc_id = aws_vpc.main.id
これはさっき理解した。
「このSubnetを、aws_vpc.mainで作成したVPCに所属させます」
ということ。
次。
cidr_block = "10.0.1.0/24"
これは、
「このSubnetで使うIPアドレスの範囲を10.0.1.0/24にします」
という設定。
そして今日の新しい知識。
AZ(Availability Zone)
Subnetを作るとき、AWSコンソールでもAZを選んだよね。
Terraformでも同じ。
例えば、
availability_zone = "ap-northeast-1a"
と書く。
つまり、
Subnet
↓
VPC
↓
CIDR
↓
AZ
という関係。
今日のコード
ここまでをまとめると、
provider "aws" {
region = "ap-northeast-1"
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-1a"
}
AWSコンソールでやっていたことを、そのままTerraformで表現している。
ここで一度、コードを読んでみる
provider "aws" {
region = "ap-northeast-1"
}
これは、
AWSの東京リージョンを使います。
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
これは、
10.0.0.0/16の範囲を持つVPCを作ります。
resource "aws_subnet" "public" {
これは、
publicという名前のSubnetを作ります。
vpc_id = aws_vpc.main.id
これは、
このSubnetを、先ほど作ったVPCに所属させます。
cidr_block = "10.0.1.0/24"
これは、
このSubnetのCIDRを10.0.1.0/24にします。
availability_zone = "ap-northeast-1a"
これは、
このSubnetをap-northeast-1aに作ります。
ここで宿題
今回もコピペ禁止。
一文字ずつ自分で打ってみる。
そして、次の2つを考える。
Q1
なぜ、
vpc_id = aws_vpc.main.id
なの?
なぜ、
vpc_id = "vpc-123456"
と直接書かない?
Q2
もし、
availability_zone
を書かなかったら、どうなると思う?
ねこさんの回答
Q1
パブリックサブネットのIDとMain VPCのIDを一緒にしたいから。
なぜ直接
vpc-123456と書かないのか?
vpc_idと書くだけでvpc-123456を参照してくれるから。
Q2
どのAZに作ればいいのか分からなくなって、Subnetが作れない。
Q1のレビュー
ここは少し修正。
まず、
パブリックサブネットのIDとMain VPCのIDを一緒にしたい。
これは違う。
Subnetにも、
subnet-xxxx
というIDがある。
VPCには、
vpc-xxxx
というIDがある。
別々のID。
だから、
vpc_id = aws_vpc.main.id
は、
SubnetのIDとVPCのIDを同じにする
という意味ではない。
そうではなく、
「このSubnetは、このVPCに所属します」
という関係を指定している。
そして、もう一つ。
vpc_idと書くだけで参照してくれる。
これも少し違う。
Terraformが参照しているのは、
aws_vpc.main.id
の部分。
つまり、
vpc_id
は、
「VPCのIDを入れる場所」
であって、
aws_vpc.main.id
が、
「実際に参照するVPCのID」
になる。
ここは今後もめちゃくちゃ出てくる。
例えばEC2なら、
subnet_id = aws_subnet.public.id
と書ける。
これは、
「このEC2を、aws_subnet.publicで作ったSubnetに配置してください」
という意味。
つまり、
EC2
│
▼
Subnet
という関係をTerraformで表現している。
ALBでも同じ。
subnets = [
aws_subnet.public_a.id,
aws_subnet.public_c.id
]
なら、
ALB
/ \
↓ ↓
Public A Public C
という関係になる。
Q2のレビュー
これは、
100点。
Subnetは1つのAZに所属する。
だからAWSは、
「このSubnetをどのAZに作ればいい?」
という情報が必要になる。
そこで、
availability_zone = "ap-northeast-1a"
と指定する。
そして、ここで一つ疑問
ここまで勉強すると、
vpc_id = aws_vpc.main.id
って、ただの設定項目に見えなくなってくる。
実際、
VPC
│
▼
Subnet
というAWSの構成を、
Terraformのコードで表現している。
これがTerraformを理解する上でかなり重要。
Terraformは「値を書く」だけじゃない
Terraformでは、
vpc_id = aws_vpc.main.id
のように、リソース同士を参照できる。
だから、
VPC
│
▼
Subnet
│
▼
EC2
というAWSの構成を、
コードとして表現できる。
例えば、
subnet_id = aws_subnet.public.id
なら、
EC2
│
▼
Public Subnet
になる。
つまりTerraformを書いているときは、
「このコードはAWSの構成図のどの部分を表しているんだろう?」
と考えると分かりやすい。
今日、一番大事だったこと
今回やったことは、
- VPC
- CIDR
- Subnet
- AZ
vpc_id- Terraformのリソース参照
だけ。
でも、単純にコードを暗記したわけではない。
AWSコンソールで、
VPCを選択する
↓
CIDRを決める
↓
AZを選択する
という操作を、
Terraformでは、
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-1a"
と書いている。
コンソールでやっていたことをコードに変換しているだけ。
そう考えると、Terraformが少し分かりやすくなる。
そして、今日ちょっと嬉しかったこと
最初は、
「難しくて泣きそう」
だった。
でも、そのあと、
「CIDR理解した!」
になった。
今回も同じ。
最初は、
vpc_id = aws_vpc.main.idって何?
だった。
そこから、
「このSubnetを、さっき作ったVPCに所属させるってことか」
まで理解できた。
この、
「あ、そういうことか」
が積み重なっていくのが、今回のTerraform講座の目的。
資格の問題を解くために覚えるのではなく、
AWSの構成を理解して、それをTerraformに落とし込めるようにする。
ここを目指していく。
次回
次はいよいよ、
Internet Gateway
ここから、
Internet
│
▼
Internet Gateway
│
▼
VPC
という関係をTerraformで作っていく。
ただし、VPCにInternet Gatewayを付けただけでは、まだEC2はインターネットに出られない。
その理由を考えていくと、
Route Table
の必要性が見えてくる。
ここからAWSネットワークが一気につながってくる。