概要 #
検証用のVMを1台立てるだけのつもりでも、VPC、Subnet、Firewall、SSHの経路まで揃える必要があります。コンソールで作ると既定のVPCに外部IP付きのVMができてしまい、あとから閉じるのに手間がかかります。
Terraformなら、この一式をまとめて作り、まとめて消せます。ここでは外部IPを持たないSpot VMを、専用VPCとIAP経由のSSH経路ごと作成します。
Terraformの基本操作は前提としています。Google Cloudのネットワークまわりに不慣れな方向けです。
短時間の学習・検証向けに、コストを抑えた構成にしています。Spot VMはいつでも回収されうるため本番用途には使えず、SLAの対象外です。
Managed Instance Groupによる冗長化やAuto Healingも扱いません。
検証すること #
- Debian 12の最新ImageをData Sourceで取得する
- Spot VMを作成する
- 外部IPを付けず、IAP経由のSSH経路だけを用意する
- OS Loginを有効化する
- VMとネットワークをまとめてdestroyする
今回の構成 #
まず、何がどこに置かれるかです。VMはProject内の専用VPCにあり、外部IPを持ちません。IAPはVPCの外側にある、Google管理のサービスです。
flowchart TB
User["手元の端末"]
subgraph GCP["Google Cloud"]
IAP["Identity-Aware Proxy
VPC外・Google管理"]
subgraph Project["Project"]
subgraph Region["asia-northeast1"]
subgraph VPC["VPC"]
FW["Firewall: allow-iap-ssh
src 35.235.240.0/20 / TCP:22"]
subgraph Subnet["Subnet 10.20.0.0/24"]
VM["Spot VM: tf-example-gce-01
zone asia-northeast1-a
10.20.0.2(外部IPなし)"]
end
end
end
end
end
User -->|"SSH over HTTPS"| IAP
IAP -->|"TCP:22"| FW
FW --> VM
外部IPがないため、インターネットからVMへ直接届く経路はありません。到達できるのはIAPを通る経路だけです。
その手順を時系列で見ると、次のようになります。
sequenceDiagram
actor User as 手元の端末
participant IAP as Identity-Aware Proxy
participant FW as Firewall
participant VM as Spot VM (外部IPなし)
User->>IAP: gcloud compute ssh --tunnel-through-iap
Note over User,IAP: IAMで接続可否を判定
IAP->>FW: TCP:22 (送信元 35.235.240.0/20)
FW->>VM: 許可して転送
VM-->>User: SSHセッション確立
前提環境 #
- ADCで認証済み
- 課金が有効な検証用Project
- Compute Admin相当の権限
- IAP SSHを試す場合はIAP-secured Tunnel Userなどの権限
- 検証時のバージョン:Terraform 1.14.3、google 7.43.0
使用するTerraformコード #
ファイル構成 #
04-compute-engine/
├── network.tf # VPC / Subnet / Firewall
├── main.tf # API / Image / VM
├── variables.tf
├── outputs.tf
└── terraform.tfvars.example
今回重要なTerraformコード #
Debian 12ファミリーの最新Imageを参照します。
data "google_compute_image" "debian" {
family = "debian-12"
project = "debian-cloud"
}
VMは外部IPなしでSubnetへ接続します。access_configブロックを置かないことがポイントです。
resource "google_compute_instance" "vm" {
name = var.instance_name
machine_type = var.machine_type
zone = var.zone
tags = ["iap-ssh"]
boot_disk {
initialize_params {
image = data.google_compute_image.debian.self_link
size = 20
type = "pd-balanced"
}
}
network_interface {
subnetwork = google_compute_subnetwork.primary.id
}
scheduling {
provisioning_model = "SPOT"
preemptible = true
automatic_restart = false
}
metadata = {
enable-oslogin = "TRUE"
}
}
Spot VMは回収後の自動再起動を前提にしないため、automatic_restart = falseとします。永続的な処理や重要データの保存先には向きません。
IAPからのSSHだけをVMのNetwork Tagへ許可します。
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"]
target_tags = ["iap-ssh"]
}
設定と実行 #
cd Basic-Examples/04-compute-engine
cp terraform.tfvars.example terraform.tfvars
project_id = "your-project-id"
region = "asia-northeast1"
zone = "asia-northeast1-a"
terraform init
terraform fmt -check
terraform validate
terraform plan
terraform apply
VPC、Subnet、Firewall、VMの5つが作成されます。
Apply complete! Resources: 5 added, 0 changed, 0 destroyed.
Outputs:
instance_name = "tf-example-gce-01"
internal_ip = "10.20.0.2"
network_name = "tf-example-gce-vpc"
ssh_via_iap_example = "gcloud compute ssh tf-example-gce-01 --zone=asia-northeast1-a --tunnel-through-iap --project=YOUR_PROJECT_ID"
zone = "asia-northeast1-a"
GCP側で確認する #
gcloud compute instances describe \
"$(terraform output -raw instance_name)" \
--zone="$(terraform output -raw zone)" \
--project=YOUR_PROJECT_ID
machineType: e2-medium
name: tf-example-gce-01
networkInterfaces:
- networkIP: 10.20.0.2
scheduling:
automaticRestart: false
instanceTerminationAction: STOP
onHostMaintenance: TERMINATE
preemptible: true
provisioningModel: SPOT
status: RUNNING
provisioningModelがSPOTになっています。networkInterfacesにはnetworkIPだけがあり、accessConfigs(外部IP)は出力されません。一覧でも外部IPの列は空になります。
gcloud compute instances list --project=YOUR_PROJECT_ID
NAME ZONE MACHINE_TYPE PROVISIONING_MODEL STATUS NETWORK_IP EXTERNAL_IP
tf-example-gce-01 asia-northeast1-a e2-medium SPOT RUNNING 10.20.0.2
IAP SSHを試す場合:
gcloud compute ssh "$(terraform output -raw instance_name)" \
--zone="$(terraform output -raw zone)" \
--tunnel-through-iap \
--project=YOUR_PROJECT_ID
外部IPがなくても接続できます。
Warning: Permanently added 'compute.INSTANCE_ID' (ED25519) to the list of known hosts.
tf-example-gce-01
6.1.0-52-cloud-amd64
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
外部IPやCloud NATがないため、VMから一般のインターネットへの通信は制限されます。
後片付けと注意点 #
terraform destroy
VMとPersistent Diskは利用中に料金が発生します。検証後は必ずdestroyします。Spot VMは安価ですが可用性保証がなく、本番の常時稼働用途には適しません。
まとめ #
- Image Familyから最新Debian Imageを参照できる
- Spot VMで短時間検証向けの構成を作成できる
- 外部IPなしでIAP SSH経路を用意できる
- OS LoginでSSH鍵管理をGoogle Cloud側へ寄せられる
参考資料 #
次回 #
次はService Accountを作成し、Project IAM Roleを最小権限で付与します。