概要 #
Google CloudでVMやGKEなどを利用するには、まずVPCネットワークが必要です。自動モードVPCで済ませると、意図しないRegionにSubnetができていても把握できません。Firewallの範囲が広すぎることにも気づきにくくなります。
Terraformなら、Subnet範囲やFirewallの許可範囲をコードとして明示できます。ここでは自動Subnetを持たないカスタムモードVPCと、東京RegionのSubnetを作成します。内部通信用とIAP SSH用のFirewall Ruleも用意します。
Terraformの基本操作は前提としています。VPCの基本用語(Subnet、Firewall)に触れたことがある方向けです。
VMやCloud NAT、外部IPは作成しません。基本的なネットワークリソースだけを扱います。
VMやCloud NAT、外部IPは作成せず、基本的なネットワークリソースだけを検証します。
検証すること #
- カスタムモードVPCを作成できること
- Regionを指定したSubnetを作成できること
- VPC内部通信用のFirewall Ruleを作成できること
- IAP経由のSSHだけを許可するFirewall Ruleを作成できること
- 作成したネットワークを
gcloudで確認できること
今回の構成 #
カスタムモードのVPCを作り、その中にSubnetを1つ置きます。Firewallはネットワーク単位の設定なのでVPC直下です。
flowchart TB
subgraph GCP["Google Cloud"]
IAP["Identity-Aware Proxy
(VPC外・Google管理)"]
subgraph Project["Project"]
subgraph Region["asia-northeast1"]
subgraph VPC["VPC(カスタムモード)"]
FWIAP["Firewall: allow-iap-ssh
src 35.235.240.0/20 / TCP:22"]
FWInt["Firewall: allow-internal
src 10.10.0.0/24 / tcp,udp,icmp"]
subgraph Subnet["Subnet 10.10.0.0/24"]
VM["VM など
(本記事では作らない)"]
end
end
end
end
end
IAP -->|"TCP:22"| FWIAP
FWIAP --> VM
VM <-->|"内部通信"| FWInt
自動モードのVPCだと全Regionにサブネットが作られます。カスタムモードでは、必要なRegionだけを自分で決めます。
VPCはGlobalリソース、SubnetはRegionリソースです。Firewall RuleはVPCへ関連付けます。
前提環境 #
- Google Cloud CLI
- Terraform 1.10.0以上、2.0.0未満
- ADCで認証済み
- 検証用Google Cloud Project
- Compute Network Admin相当の権限
- Service Usageを操作できる権限
- 検証時のバージョン:Terraform 1.14.3、google 7.43.0
Compute Engine APIはTerraformコード内で有効化します。
使用するTerraformコード #
前回はAPIの有効化を確認しました。
ファイル構成 #
02-network/
├── README.md
├── versions.tf
├── provider.tf
├── variables.tf
├── network.tf
├── outputs.tf
└── terraform.tfvars.example
ネットワーク自体が今回の検証対象なので、リソースはmain.tfではなくnetwork.tfへまとめています。
今回重要なTerraformコード #
Compute Engine API #
VPCなどを操作するため、Compute Engine APIを有効化します。
resource "google_project_service" "compute" {
project = var.project_id
service = "compute.googleapis.com"
disable_on_destroy = false
}
destroy後も他のシステムへ影響させないよう、APIは有効なまま残します。
カスタムモードVPC #
resource "google_compute_network" "vpc" {
name = var.network_name
auto_create_subnetworks = false
routing_mode = "REGIONAL"
depends_on = [google_project_service.compute]
}
auto_create_subnetworks = falseにすることで、自動モードではなくカスタムモードVPCを作成します。必要なSubnetだけを明示的に管理できる構成です。
depends_onにより、Compute Engine APIの有効化後にVPCを作成します。
Subnet #
resource "google_compute_subnetwork" "primary" {
name = var.subnet_name
ip_cidr_range = var.subnet_cidr
region = var.region
network = google_compute_network.vpc.id
private_ip_google_access = true
}
デフォルトではasia-northeast1に10.10.0.0/24のSubnetを作成します。
private_ip_google_access = trueにより、外部IPを持たないVMからGoogle APIやサービスへ到達できるようにします。ただし、一般のインターネット宛て通信を提供する設定ではありません。
VPC内部通信用Firewall Rule #
resource "google_compute_firewall" "allow_internal" {
name = "${var.network_name}-allow-internal"
network = google_compute_network.vpc.name
allow {
protocol = "tcp"
}
allow {
protocol = "udp"
}
allow {
protocol = "icmp"
}
source_ranges = [var.subnet_cidr]
priority = 1000
}
送信元をSubnetのCIDRに限定し、TCP、UDP、ICMPを許可します。0.0.0.0/0からの内部通信許可にはしていません。
IAP SSH用Firewall Rule #
resource "google_compute_firewall" "allow_iap_ssh" {
name = "${var.network_name}-allow-iap-ssh"
network = google_compute_network.vpc.name
allow {
protocol = "tcp"
ports = ["22"]
}
source_ranges = ["35.235.240.0/20"]
priority = 1000
}
SSHをインターネット全体へ公開せず、IAP TCP forwardingで使用される送信元範囲からのTCP 22番だけを許可します。
Firewall RuleだけでIAP SSHの認可が完了するわけではありません。実際に接続するユーザーにはIAPやVMログインに必要なIAM権限も必要です。
入力値を設定する #
cd Basic-Examples/02-network
cp terraform.tfvars.example terraform.tfvars
project_id = "your-project-id"
region = "asia-northeast1"
デフォルト値を変更する場合は、次の値も設定できます。
network_name = "tf-example-vpc"
subnet_name = "tf-example-subnet"
subnet_cidr = "10.10.0.0/24"
既存ネットワークとCIDRが重複しないように確認します。
Terraformを実行する #
terraform init
terraform fmt -check
terraform validate
terraform plan
terraform apply
デフォルト構成では、API設定、VPC、Subnet、2つのFirewall RuleがPlanへ表示されます。
applyが完了すると、5つのResourceが作成されOutputが表示されます。
google_compute_firewall.allow_iap_ssh: Creation complete after 11s [id=projects/YOUR_PROJECT_ID/global/firewalls/tf-example-vpc-allow-iap-ssh]
google_compute_subnetwork.primary: Creation complete after 25s [id=projects/YOUR_PROJECT_ID/regions/asia-northeast1/subnetworks/tf-example-subnet]
Apply complete! Resources: 5 added, 0 changed, 0 destroyed.
Outputs:
firewall_names = [
"tf-example-vpc-allow-internal",
"tf-example-vpc-allow-iap-ssh",
]
network_id = "projects/YOUR_PROJECT_ID/global/networks/tf-example-vpc"
network_name = "tf-example-vpc"
subnet_cidr = "10.10.0.0/24"
subnet_name = "tf-example-subnet"
GCP側で確認する #
VPCを確認します。
gcloud compute networks describe \
"$(terraform output -raw network_name)" \
--project=YOUR_PROJECT_ID
autoCreateSubnetworks: false
name: tf-example-vpc
routingConfig:
bgpBestPathSelectionMode: LEGACY
routingMode: REGIONAL
autoCreateSubnetworks: falseがカスタムモードであることを示します。自動モードだと全Regionにサブネットが作られるため、意図した範囲だけを持つ構成になっているかがここで分かります。
Subnetを確認します。
gcloud compute networks subnets list \
--network="$(terraform output -raw network_name)" \
--project=YOUR_PROJECT_ID
NAME REGION NETWORK RANGE STACK_TYPE
tf-example-subnet asia-northeast1 tf-example-vpc 10.10.0.0/24 IPV4_ONLY
Firewall Ruleを確認します。
gcloud compute firewall-rules list \
--filter="network~$(terraform output -raw network_name)" \
--project=YOUR_PROJECT_ID
NAME NETWORK DIRECTION PRIORITY ALLOW
tf-example-vpc-allow-iap-ssh tf-example-vpc INGRESS 1000 tcp:22
tf-example-vpc-allow-internal tf-example-vpc INGRESS 1000 icmp,udp,tcp
送信元範囲はdescribeで確認できます。
gcloud compute firewall-rules describe tf-example-vpc-allow-iap-ssh \
--project=YOUR_PROJECT_ID \
--format="yaml(name,sourceRanges,allowed)"
allowed:
- IPProtocol: tcp
ports:
- '22'
name: tf-example-vpc-allow-iap-ssh
sourceRanges:
- 35.235.240.0/20
35.235.240.0/20はIAPのForwarding元レンジです。この範囲だけを許可しているため、外部IPを持たないVMにもIAP経由でSSHできます。
エラー・注意点 #
CIDRが重複している #
同じVPC内で既存SubnetとCIDRが重複するとSubnetを作成できません。subnet_cidrを重複しない範囲へ変更します。
Firewall Ruleは通信を発生させない #
Firewall Ruleは許可条件を定義するだけです。このサンプルではVMを作成しないため、実際のSSHや内部通信は次回以降のサンプルで確認します。
料金 #
VPC、Subnet、Firewall Rule自体には通常追加料金は発生しません。このサンプルではCloud NAT、外部IP、VMなどの課金対象リソースを作成しません。
後片付け #
terraform destroy
Firewall Rule、Subnet、VPCの依存関係をTerraformが判断し、作成時と逆の順序で削除します。Compute Engine APIはdisable_on_destroy = falseのため有効なまま残ります。
まとめ #
- 自動Subnetを作らないカスタムモードVPCを作成できる
- RegionとCIDRを指定してSubnetを作成できる
- 内部通信の送信元をSubnet CIDRへ限定できる
- SSHの送信元をIAP用範囲へ限定できる
- Terraformの参照からリソース間の依存関係を構成できる
参考資料 #
- Terraform Google Provider: google_compute_network
- Terraform Google Provider: google_compute_subnetwork
- Terraform Google Provider: google_compute_firewall
- Google Cloud: VPCネットワーク
- Google Cloud: IAP TCP forwarding用Firewall Rule
次回 #
次は、TerraformでCloud Storage Bucketを作成し、Uniform bucket-level accessやPublic access preventionを確認します。