GCP上でPacker×Terraformを使ってWindows Serverイメージを作成・展開する方法

はじめに

クラウド環境でWindows Serverを運用する際、毎回手動で環境を構築していては時間がかかり、再現性も低くなってしまいます。特にGCP(Google Cloud Platform)上で企業のセキュリティポリシーに準拠したWindows Server環境を構築する場合、以下のような課題に直面することが多いです:

  • 毎回GUIで環境を作ると設定ミスが発生しやすい
  • 標準イメージでは必要なツールやセキュリティ設定が不足している
  • 複数環境(開発、検証、本番)で一貫性を保つのが困難
  • セキュリティパッチや企業ポリシーの適用が煩雑

本記事では、PackerTerraformを組み合わせて、これらの課題を解決する自動化ソリューションを詳細に解説します。

環境構成とアーキテクチャ

全体構成図

1
2
3
4
5
6
7
8
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   Developer     │    │   CI/CD         │    │   GCP Project   │
│   Local         │    │   Pipeline      │    │                 │
├─────────────────┤    ├─────────────────┤    ├─────────────────┤
│ • Packer HCL    │───▶│ • GitHub Actions│───▶│ • Custom Images │
│ • Terraform     │    │ • Cloud Build   │    │ • VM Instances  │
│ • gcloud CLI    │    │ • Auto Deploy   │    │ • IAM/Network   │
└─────────────────┘    └─────────────────┘    └─────────────────┘

技術スタック

  • Packer 1.9+: Windows Serverのカスタムイメージビルド
  • Terraform 1.5+: インフラストラクチャのコード管理
  • GCP Compute Engine: 実行基盤
  • PowerShell/cmd: Windows環境のプロビジョニング
  • WinRM: Packerとの通信プロトコル

事前準備

1. GCPプロジェクトの設定

1
2
3
4
5
6
7
8
# プロジェクト設定
export PROJECT_ID="your-project-id"
gcloud config set project $PROJECT_ID

# 必要なAPIの有効化
gcloud services enable compute.googleapis.com
gcloud services enable cloudresourcemanager.googleapis.com
gcloud services enable iam.googleapis.com

2. サービスアカウントの作成

1
2
3
4
5
6
7
8
9
# Packer用サービスアカウント作成
gcloud iam service-accounts create packer-builder \
    --description="Packer image builder" \
    --display-name="Packer Builder"

# 必要な権限の付与
gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member="serviceAccount:packer-builder@$PROJECT_ID.iam.gserviceaccount.com" \
    --role="roles/compute.instanceAdmin.v1"

Packerの詳細設定

メインのPacker設定ファイル

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# windows-2022.pkr.hcl
packer {
  required_plugins {
    googlecompute = {
      version = ">= 1.1.1"
      source  = "github.com/hashicorp/googlecompute"
    }
  }
}

variable "project_id" {
  type        = string
  description = "GCP Project ID"
}

variable "zone" {
  type        = string
  default     = "asia-northeast1-b"
  description = "GCP Zone for building"
}

source "googlecompute" "windows-2022" {
  project_id              = var.project_id
  source_image_family     = "windows-2022"
  zone                   = var.zone
  machine_type           = "e2-standard-4"
  disk_size              = 50
  
  # Windows固有の設定
  communicator           = "winrm"
  winrm_username         = "packer_user"
  winrm_password         = "SecurePassword123!"
  winrm_timeout          = "30m"
  winrm_use_ssl          = true
  winrm_insecure         = true
  
  # イメージ設定
  image_name             = "custom-windows-2022-{{timestamp}}"
  image_description      = "Custom Windows Server 2022 with security baseline"
  image_family          = "custom-windows-2022"
  
  # タグとラベル
  tags = ["packer", "windows", "base-image"]
}

build {
  name = "windows-2022-custom"
  sources = ["source.googlecompute.windows-2022"]

  # Windows Updateの実行
  provisioner "powershell" {
    script = "scripts/windows-update.ps1"
  }

  # 必要なツールのインストール
  provisioner "powershell" {
    script = "scripts/install-tools.ps1"
  }

  # セキュリティベースラインの適用
  provisioner "powershell" {
    script = "scripts/security-baseline.ps1"
  }

  # クリーンアップ
  provisioner "powershell" {
    script = "scripts/cleanup.ps1"
  }
}

Terraformによる自動展開

メインのTerraform設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# main.tf
terraform {
  required_version = ">= 1.5"
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 4.84"
    }
  }
}

provider "google" {
  project = var.project_id
  region  = var.region
  zone    = var.zone
}

# データソース: 最新のカスタムイメージを取得
data "google_compute_image" "windows_image" {
  family  = "custom-windows-2022"
  project = var.project_id
}

# Windows VM インスタンス
resource "google_compute_instance" "windows_vm" {
  name         = var.instance_name
  machine_type = var.machine_type
  zone         = var.zone

  # ブートディスク
  boot_disk {
    initialize_params {
      image = data.google_compute_image.windows_image.self_link
      size  = var.disk_size
      type  = "pd-standard"
    }
  }

  # ネットワーク設定
  network_interface {
    network    = var.network
    subnetwork = var.subnetwork
    access_config {}
  }

  # メタデータ(ユーザー作成等)
  metadata = {
    windows-startup-script-ps1 = templatefile("${path.module}/scripts/startup.ps1", {
      admin_username = var.admin_username
      admin_password = var.admin_password
    })
  }

  # タグ
  tags = ["windows-server", "rdp-server"]
}

実行手順

1. Packerでイメージビルド

1
2
3
4
5
6
7
# 変数ファイルの作成
cat > variables.pkrvars.hcl << EOF
project_id = "your-project-id"
EOF

# イメージのビルド実行
packer build -var-file="variables.pkrvars.hcl" windows-2022.pkr.hcl

2. Terraformで展開

1
2
3
4
5
6
7
8
9
# 作業ディレクトリの初期化
cd terraform
terraform init

# 実行プランの確認
terraform plan -var-file="terraform.tfvars"

# リソースの作成
terraform apply -var-file="terraform.tfvars"

トラブルシューティング

よくある問題と解決方法

1. WinRM接続エラー

問題: Packerビルド中にWinRMでの接続が失敗する

解決方法:

1
2
3
4
# メタデータでWinRMを確実に有効化
winrm quickconfig -quiet
winrm set winrm/config/service @{AllowUnencrypted="true"}
winrm set winrm/config/service/auth @{Basic="true"}

2. ファイアウォールブロック

問題: RDPやWinRMポートがブロックされる

解決方法:

1
2
3
4
5
6
7
8
# GCPファイアウォールルールの確認
gcloud compute firewall-rules list --filter="name~allow-rdp"

# 必要に応じてルールを作成
gcloud compute firewall-rules create allow-rdp-custom \
    --allow tcp:3389 \
    --source-ranges 0.0.0.0/0 \
    --target-tags rdp-server

セキュリティ考慮事項

認証情報の管理

1
2
3
4
5
6
7
# Secret Manager にパスワードを保存
gcloud secrets create windows-admin-password --data-file=-

# Terraform で Secret Manager から取得
data "google_secret_manager_secret_version" "admin_password" {
  secret = "windows-admin-password"
}

まとめ

本記事では、GCP上でPackerとTerraformを組み合わせてWindows Serverの自動化ソリューションを構築する方法を詳細に解説しました。

主な利点

  1. 再現性: 毎回同一の環境を構築可能
  2. 効率性: 手動作業を大幅に削減
  3. セキュリティ: セキュリティベースラインを自動適用
  4. スケーラビリティ: 複数環境への横展開が容易
  5. 監査性: インフラの変更履歴をコードで管理

この自動化基盤により、Windows Server環境の構築・運用が劇的に効率化されることを実感していただけるでしょう。

次回は、セキュリティベースライン適用時の注意点について詳しく解説します。

技術ネタ、趣味や備忘録などを書いているブログです
Hugo で構築されています。
テーマ StackJimmy によって設計されています。