今日を知り、明日を変えるシステム運用メディア

【Google Cloud】terraformで書いたコードをCheckovでセキュリティチェックしよう

【Google Cloud】terraformで書いたコードをCheckovでセキュリティチェックしよう

前回は、Google Cloudの自分のアカウントをterraformに連携する方法を解説してきましたが、今回の第2章では、terraformにコードを書いて、Checkovでセキュリティチェックする手順を解説します。

Terraformを使ったインフラ構築は、コードとしての管理と自動化が進む一方で、セキュリティの懸念も増しています。Google Cloud環境に最適な構成を維持しつつ、リスクを未然に防ぐ方法を学び、堅牢なインフラを構築しましょう。

ハンズオンの流れを解説

今回は、上の構成図のGoogle Cloudリソースをterraformで構築し、そのコードをCheckovでセキュリティチェックします。具体的に作成する主なリソースはVPCと2台のEC2とELBです。

  1. terraformでコードを記述しGoogle Cloudリソースの構築
  2. Checkovでセキュリティチェック
  3. チェック結果を確認する

この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を開きエラーの詳細を確認してみましょう。

network.tfの21-31行に記載している「allow-http」に課題がある

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

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のインフラ管理担当者は、本記事の内容はしっかりと抑えておきましょう。

現在クラウドエンジニアとして勤務。AWS(SAP、DOP)とAzure(AZ-305)の資格を保有しており、ネットワークやセキュリティに関する業務を主に行っています。

この記事を含む特集

terraformで書いたコードをCheckovでセキュリティチェックしてみよう!

terraformで書いたコードをCheckovでセキュリティチェックしてみよう!

人気の記事

最新情報をお届けします!

最新のITトレンドやセキュリティ対策の情報を、メルマガでいち早く受け取りませんか?ぜひご登録ください

メルマガ登録