
【Google Cloud】terraformで書いたコードをCheckovでセキュリティチェックしよう
前回は、Google Cloudの自分のアカウントをterraformに連携する方法を解説してきましたが、今回の第2章では、terraformにコードを書いて、Checkovでセキュリティチェックする手順を解説します。
Terraformを使ったインフラ構築は、コードとしての管理と自動化が進む一方で、セキュリティの懸念も増しています。Google Cloud環境に最適な構成を維持しつつ、リスクを未然に防ぐ方法を学び、堅牢なインフラを構築しましょう。
ハンズオンの流れを解説
今回は、上の構成図のGoogle Cloudリソースをterraformで構築し、そのコードをCheckovでセキュリティチェックします。具体的に作成する主なリソースはVPCと2台のEC2とELBです。
- terraformでコードを記述しGoogle Cloudリソースの構築
- Checkovでセキュリティチェック
- チェック結果を確認する
この3ステップでセキュリティチェックを行います。
terraformでGoogle Cloudインフラを構築
最初のステップでは、terraformでコードを記述し、リソースを構築します。terraformとローカルPCの連携方法や基本的な使い方については、第1章をご確認ください。
まずは、今回作成するGoogle Cloudリソースは大きく分けてvpcとインスタンスとロードバランサーであるため、backend.tfファイルがあるフォルダと同フォルダ内に下記3つのファイルを作成します。(第1章で作成したファイルは削除してください。)
- network.tf
- instance.tf
- lb.tf
そして、network.tfをVSCodeで開き、下記コードを記述します。
# VPCネットワーク作成 resource “google_compute_network” “vpc_network” { name = “opstoday-vpc-network” } # サブネット1 resource “google_compute_subnetwork” “subnet1” { name = “opstoday-subnet-1” ip_cidr_range = “10.0.1.0/24” network = google_compute_network.vpc_network.self_link } # サブネット2 resource “google_compute_subnetwork” “subnet2” { name = “opstoday-subnet-2” ip_cidr_range = “10.0.2.0/24” network = google_compute_network.vpc_network.self_link } # サーバー用のファイアウォールルール resource “google_compute_firewall” “allow-http” { name = “opstoday-allow-http” network = google_compute_network.vpc_network.name allow { protocol = “tcp” ports = [“80”] } source_ranges = [“0.0.0.0/0”] } |
同様に、instance.tfファイルをVSCodeで開き下記のコードを入力します。
# インスタンステンプレート作成 (負荷分散に利用) resource “google_compute_instance_template” “template” { name = “opstoday-instance-template” machine_type = “e2-medium” disk { boot = true auto_delete = true source_image = “projects/debian-cloud/global/images/family/debian-11” } network_interface { subnetwork = google_compute_subnetwork.subnet1.self_link access_config {} } metadata = { startup-script = <<-EOT #!/bin/bash apt-get update apt-get install -y apache2 echo “Hello from $(hostname)” > /var/www/html/index.html EOT } } # サーバー1 resource “google_compute_instance” “instance1” { name = “opstoday-instance-1” machine_type = “e2-medium” zone = “asia-northeast1-a” boot_disk { initialize_params { image = “projects/debian-cloud/global/images/family/debian-11” } } network_interface { subnetwork = google_compute_subnetwork.subnet1.self_link access_config {} } } # サーバー2 resource “google_compute_instance” “instance2” { name = “opstoday-instance-2” machine_type = “e2-medium” zone = “asia-northeast1-b” boot_disk { initialize_params { image = “projects/debian-cloud/global/images/family/debian-11” } } network_interface { subnetwork = google_compute_subnetwork.subnet2.self_link access_config {} } } |
最後に、lb.tfファイルもVSCodeで開いて下記コードを入力します。
# HTTP ヘルスチェック resource “google_compute_http_health_check” “http-health-check” { name = “opstoday-http-health-check” request_path = “/” port = 80 check_interval_sec = 10 timeout_sec = 5 } # ターゲット プール resource “google_compute_target_pool” “target-pool” { name = “opstoday-target-pool” health_checks = [google_compute_http_health_check.http-health-check.self_link] instances = [ google_compute_instance.instance1.self_link, google_compute_instance.instance2.self_link, ] } # ロードバランサー用のグローバルIP resource “google_compute_global_address” “lb_ip” { name = “opstoday-lb-ip” } # バックエンドサービス resource “google_compute_backend_service” “backend-service” { name = “opstoday-backend-service” health_checks = [google_compute_http_health_check.http-health-check.self_link] connection_draining_timeout_sec = 30 load_balancing_scheme = “EXTERNAL” } # URLマップ resource “google_compute_url_map” “url-map” { name = “opstoday-url-map” default_service = google_compute_backend_service.backend-service.self_link } # HTTP プロキシ resource “google_compute_target_http_proxy” “http-proxy” { name = “opstoday-http-proxy” url_map = google_compute_url_map.url-map.self_link } # フロントエンド (グローバル フォワーディングルール) resource “google_compute_global_forwarding_rule” “http” { name = “http-forwarding-rule” target = google_compute_target_http_proxy.http-proxy.self_link port_range = “80” ip_address = google_compute_global_address.lb_ip.address } |
ここまで入力できたら、ターミナルで下記コマンドを入力します。
terarfrom plan |
planを入力し、エラーが出なければ、
terarfrom apply |
を実行することでリソースを構築できます。
Checkovでセキュリティチェック
リソースの構築ができたら、Checkovで作成した環境のセキュリティチェックを行います。
セキュリティチェックのためには、ターミナルで下記コマンドを実行します。
checkov -d . |
このコマンドは、セキュリティツール「Checkov」を使って、Terraform コードのセキュリティチェックを実行するためのコマンドです。「-d .」の部分はオプションで、チェックするディレクトリを指定します。ドットは、カレントディレクトリを意味しています。
下記の画像のような出力がされていればチェック成功です。

上記画像内の赤枠部分について詳しく解説します。
「Passed checks」は、チェック対象のリソースがセキュリティポリシーに適合しており、問題がないことを示しています。
「Failed checks」は、セキュリティポリシーに違反している設定や構成が見つかったことを示します。19件のチェックが失敗しているため、Google Cloudリソースがセキュリティ基準を満たしていない状態です。
「Skipped checks」は、スキップされたチェック項目を意味します。checkovでは明示的にあるリソースのセキュリティチェックを実施しないという指定が可能です。今回は指定していないため0件となっています。
チェック結果を確認する
checkovのチェック結果は、Passed、Failed、Skippedの順に上から出力されています。今回は、Failedの一番最後に表示されている「CKV_GCP_106」のチェック項目を確認します。
下記、画像内の2行目と3行目を見るとnetwork.tfの21-31行に記載している「allow-http」に課題があると表示されています。Guideに表示されているURLを開きエラーの詳細を確認してみましょう。

URLを開くと「GCP ファイアウォール ルールは HTTP ポート (80) 上のすべてのトラフィックを許可します」のエラーが表示されました。ここで重要度やサブタイプ等も確認できます。

下にスクロールすると、エラーの説明や修正方法についても確認できます。今回は、説明を省きますが、自身でコードを修正してみましょう。修正後は、コードを再度セキュリティチェックし、「CKV_GCP_106」がPassedになるか確認してください。

Checkovのセキュリティチェックをスキップする方法
Checkovを使用する中で、誤検知や、一時的な例外など、様々な理由で特定のチェックをスキップしたいケースが発生します。そのような場合のスキップ方法を解説します。
今回解説するのは、チェック項目、「CKV_GCP_106」のチェックをスキップさせる方法です。
# サーバー用のファイアウォールルール resource “google_compute_firewall” “allow-http” { # checkov:skip=CKV_GCP_106:HTTP ポート (80) 上のすべてのトラフィックを許可 name = “opstoday-allow-http” network = google_compute_network.vpc_network.name allow { protocol = “tcp” ports = [“80”] } source_ranges = [“0.0.0.0/0”] } |
ec3.tfファイルの3行目にコメントを追加します。 「 # checkov:skip=CKV_GCP_106」と入力するだけで、スキップが可能です。「HTTP ポート (80) 上のすべてのトラフィックを許可」の部分は、スキップする理由を記述しています。スキップの内容を後から見返したり、チームメンバーがコードを見て分かりやすいように記載しておきましょう。
まとめ
今回の記事では、AWS編に引き続き、Google Cloud編として、2部にわたってterraformのコードをcheckovでセキュリティチェックする方法を解説しました。
terraformを使って、Google Cloudでインスタンスやvpc、サブネットを作成する方法からCheckovでのセキュリティチェック方法やスキップする手順などクラウドのリソースを管理するうえで重要な内容を解説しています。Google Cloudのインフラ管理担当者は、本記事の内容はしっかりと抑えておきましょう。