本記事には広告(アフィリエイトリンク)が含まれます。

OpenTofu と Ansible を Cowork で育成

広告

第 1 回: Cowork 機能マップ 2026年5月版 — 個人インフラエンジニアの活用 5 パターンではパターン 3「IaC コードの育成」として、Cowork がプロビジョニングコードと構成管理コードのレビュー伴走役になれることを概説しました。

第 2 回: Hyper-V ホームラボに Cowork を組み込むでは HomeLab\iac\{opentofu, ansible}\ というフォルダ構造を確立しました。

本記事は OpenTofu(プロビジョニング)と Ansible(OS 構成管理)の役割分担を整理したうえで、Cowork をレビュー伴走役として IaC コードを継続的に改善するループの作り方を整理します。

広告

「プロビジョニング」と「OS 構成管理」を Cowork の前で先に分ける

IaC を Cowork に見せてレビューを依頼する前に、どのツールが何を担うかを明確にしておきます。OpenTofu と Ansible は守備範囲が異なり、役割が交錯すると Cowork への依頼粒度が曖昧になります。

OpenTofu はインフラ層を担います。VM・VPC・IAM・GKE クラスタ・Kubernetes リソースといった「どのリソースが存在すべきか」を HCL で宣言し、tofu apply で現実の状態に近づけます。

Ansible は OS 内部層を担います。Linux VM が起動した後の「その VM に何が入っているべきか」—パッケージ・サービス起動状態・ユーザ・SSHd 設定・ファイアウォール・ミドルウェア配置—を YAML の Playbook で記述して冪等に適用します。

Cowork はこの 2 層のコードを読み、改善点を提案するレビュー伴走役として機能します。

ポイント: OpenTofu と Ansible の役割分担
OpenTofu = インフラ層(VM・VPC・GKE・K8s リソース・IAM のプロビジョニング)、Ansible = OS 内部層(パッケージ・サービス・ユーザ・FW・ミドルウェアの構成管理)、Cowork = レビュー伴走役(HCL・YAML・plan 出力・実行ログの解析)という三者の守備範囲を先に確立することで、Cowork への依頼粒度が明確になります。

ツール担う層主な対象ホームラボでの代表例
OpenTofuインフラ層(プロビジョニング)VM・VPC・GKE・K8s リソース・IAMGCP Compute Engine 作成、Kubernetes manifest を IaC 化
AnsibleOS 内部層(構成管理)パッケージ・サービス・ユーザ・FW・ミドルウェアHyper-V 上 Linux VM への k3s インストール、Payara デプロイ
Coworkレビュー伴走役HCL・YAML・plan 出力・実行ログ冪等性の確認、変数化の提案、未使用 output の指摘

HomeLab フォルダ構造(第 2 回で確立)はこの分担をそのまま反映しています。

HomeLab\iac\opentofu\{gcp, vsphere, kubernetes}\ が OpenTofu の作業領域で、HomeLab\iac\ansible\{inventory, playbooks, roles}\ が Ansible の作業領域です。

Cowork のフォルダスコープ(Folder Scope)に HomeLab\iac\ 以下を含めることで、両方のコードを同一プロジェクト内から参照・編集できます。

Hyper-V 上の Linux VM については補足が必要です。OpenTofu は Hyper-V provider をコミュニティ製(taliesins/hyperv 等)でしか提供しておらず、OpenTofu 公式・HashiCorp 公式のどちらも Hyper-V 向け provider を提供していません(OpenTofu Registry、2026-05-03 確認)。

そのため個人ホームラボの Hyper-V VM は PowerShell または Hyper-V マネージャで手動作成し、OS が起動した後の内部構成を Ansible で管理するという分担が現実的な選択になります。

OpenTofu の現在地と最小ワークフロー(2026-05-03 時点)

OpenTofu は HashiCorp が 2023 年 8 月に Terraform を BSL(Business Source License)に変更したことを受け、Linux Foundation 配下で立ち上がった OSS フォークです。

CLI・HCL・provider プロトコルは Terraform 1.5 までほぼ互換のため、Terraform 公式チュートリアルの多くは terraform コマンドを tofu に読み替えることで流用できます。本シリーズではすべてのコード例を tofu コマンドで記述します。

2026-05-03 時点の現行安定版は OpenTofu 1.11 系(v1.11.0 は 2025-12-09 公開、最新パッチ v1.11.6 が利用可能)。1.12.0 は 2026-04-07 公開の beta1 段階であり GA 待ちです。

本記事は 1.11 系を前提に書きます(OpenTofu Blog「OpenTofu v1.11.0」「OpenTofu 1.12.0-beta1 is now available」, 2026-05-03 確認)。

4 コマンドとプランファイルの扱い

OpenTofu の基本ワークフローは Write / Plan / Apply の 3 段階です。ホームラボでの最小操作は次の 4 コマンドになります。

# プロバイダのダウンロードとモジュール初期化
tofu init

# 変更内容の確認(破壊的操作は行わない)
tofu plan

# プランをファイルに保存(Cowork への入力として使う)
tofu plan -out=plan.tfplan

# プランファイルを JSON で出力して Cowork に読ませる
tofu show -json plan.tfplan > plan.json

# 承認後に適用
tofu apply

# リソースの削除(学習後のクリーンアップ)
tofu destroy

tofu plan -out で保存されるプランファイルはバイナリ形式で可読性が低いです。tofu show -json plan.tfplan で JSON に変換したものを Cowork に読ませると、変更差分の解析依頼が通りやすくなります。

plan / apply の最終承認は人間が行う設計を維持する点を確認しておきます—Cowork はコードレビューを担いますが、tofu apply 実行はローカルターミナルで手動で行うのが基本形です。

GCP Compute Engine の最小 HCL 例

GCP Compute Engine VM を作成する最小構成の HCL を示します。provider ブロックと resource ブロックのみの構成で、まず動かすことを優先した形です。

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 6.0"
    }
  }
  required_version = ">= 1.11"
}

provider "google" {
  project = var.project_id
  region  = "asia-northeast1"
}

variable "project_id" {
  type        = string
  description = "GCP プロジェクト ID"
}

resource "google_compute_instance" "lab_vm" {
  name         = "lab-vm-01"
  machine_type = "e2-micro"
  zone         = "asia-northeast1-a"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-12"
    }
  }

  network_interface {
    network = "default"
    access_config {}
  }
}

output "lab_vm_ip" {
  value = google_compute_instance.lab_vm.network_interface[0].access_config[0].nat_ip
}

output ブロックで VM の IP アドレスを出力しておくと、tofu output -json で取得した値を Ansible inventory に渡す連携が後工程で使えるようになります。認証情報(サービスアカウントキーや Application Default Credentials のパス)はこの HCL に直書きしません。

GOOGLE_APPLICATION_CREDENTIALS 環境変数か gcloud auth application-default login 済みのセッションを前提に運用します。

Ansible の現在地と最小ワークフロー(2026-05-03 時点)

Ansible のコミュニティパッケージ最新版は Ansible 13.6.0(2026-04-19 頃公開、ansible-core 2.20.5 依存)で、ansible-core 2.20.x を前提とします(Ansible Forum リリース告知・COLLECTIONS_13 ロードマップ、2026-05-03 確認)。

Ansible 12 は 2025-12-09 に EOL となっており、現行サポートは 13 系です(endoflife.date/ansible、2026-05-03 確認)。

インストールとコレクション取得

# pip での Ansible インストール(仮想環境推奨)
pip install ansible==13.6.0

# バージョン確認
ansible --version

# ホームラボで頻出するコレクションを事前取得
ansible-galaxy collection install community.general ansible.posix

# requirements.yml を使った一括インストール(チームでの共有に向く)
ansible-galaxy collection install -r requirements.yml

inventory と Playbook の最小構成

Hyper-V 上の Linux VM 群(手動または PowerShell で作成済み)を対象にした inventory と Playbook の最小構成を示します。

# HomeLab\iac\ansible\inventory\hosts.yml
all:
  children:
    lab_vms:
      hosts:
        k3s-node-01:
          ansible_host: 192.168.1.101
          ansible_user: labuser
          ansible_ssh_private_key_file: "~/.ssh/lab_rsa"
        payara-app-01:
          ansible_host: 192.168.1.102
          ansible_user: labuser
          ansible_ssh_private_key_file: "~/.ssh/lab_rsa"
# HomeLab\iac\ansible\playbooks\common\sshd-hardening.yml
---
- name: SSHd 強化 — パスワード認証無効化と MaxAuthTries 制限
  hosts: lab_vms
  become: true
  tasks:
    - name: パスワード認証を無効化
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        regexp: "^#?PasswordAuthentication"
        line: "PasswordAuthentication no"
        validate: "/usr/sbin/sshd -t -f %s"
      notify: restart sshd

    - name: MaxAuthTries を 3 に設定
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        regexp: "^#?MaxAuthTries"
        line: "MaxAuthTries 3"
        validate: "/usr/sbin/sshd -t -f %s"
      notify: restart sshd

    - name: sshd の起動と自動起動を保証
      ansible.builtin.service:
        name: sshd
        state: started
        enabled: true

  handlers:
    - name: restart sshd
      ansible.builtin.service:
        name: sshd
        state: restarted

冪等性の確認手順

Playbook を本番環境相当の VM に適用する前に、冪等性を確認する手順を習慣化します。

# チェックモード(実際には変更しない)
ansible-playbook -i inventory/hosts.yml playbooks/common/sshd-hardening.yml --check

# 差分表示(変更前後を比較)
ansible-playbook -i inventory/hosts.yml playbooks/common/sshd-hardening.yml --check --diff

# 2 回目実行で changed=0 になるかを確認(冪等性の本質的な確認)
ansible-playbook -i inventory/hosts.yml playbooks/common/sshd-hardening.yml

2 回目の実行で changed=0 になれば冪等性が確保されています。

changed=1 以上が残る場合は、ansible.builtin.lineinfileregexp が既存行にマッチしていないか、ansible.builtin.service モジュール外の状態変更(command / shell モジュールの誤用)が原因であることが多いです。

Cowork への Playbook レビュー依頼では「2 回目実行で changed が残る理由を特定して」という問い方が有効です。

個人インフラエンジニア向け実例 3 本

OpenTofu と Ansible の連携パターンを、ホームラボで再現できる 3 つの実例で整理します。

実例 1: GCP VM を作成して Ansible で SSHd 強化 + nginx インストール

OpenTofu で GCP Compute Engine VM を作成し、出力した IP アドレスを Ansible inventory に渡してから構成管理を適用するフローです。

  1. tofu apply で Compute Engine VM を作成します
  2. tofu output -json | jq -r '.lab_vm_ip.value' で IP アドレスを取得します
  3. 取得した IP を inventory/hosts.ymlansible_host に記入します(または dynamic inventory スクリプトで自動化します)
  4. ansible-playbook sshd-hardening.yml nginx.yml を実行して構成を適用します
  5. 実行ログを HomeLab\logs\gcp\YYYY-MM-DD-vm-setup.md に保存します

手順 3 の inventory 書き換えを自動化したい場合、Ansible の add_host モジュールや tofu output の値を Shell スクリプトで渡す方法があります。ただし CI/CD パイプライン(GitHub Actions 等)の設計は本シリーズのスコープ外とし、ローカルターミナルからの手動手順を基本形として扱います。

実例 2: Hyper-V 上の Linux VM 群を Ansible で k3s クラスタ化

Hyper-V VM は PowerShell または Hyper-V マネージャで作成します(OpenTofu の公式 Hyper-V provider が存在しないため)。VM 起動後の内部構成は Ansible が全権を持ちます。

# HomeLab\iac\ansible\playbooks\kubernetes\k3s-install.yml(抜粋)
---
- name: k3s サーバーノードのインストール
  hosts: k3s_server
  become: true
  vars:
    k3s_version: "v1.31.4+k3s1"
  tasks:
    - name: containerd の前提パッケージをインストール
      ansible.builtin.apt:
        name:
          - curl
          - open-iscsi
        state: present
        update_cache: true

    - name: k3s インストールスクリプトを実行
      ansible.builtin.shell:
        cmd: "curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION={{ k3s_version }} sh -"
        creates: /usr/local/bin/k3s

    - name: k3s サービスの起動確認
      ansible.builtin.service:
        name: k3s
        state: started
        enabled: true

creates: /usr/local/bin/k3s を指定することで、k3s バイナリが既に存在する場合はインストールスクリプトをスキップします。これが冪等性を担保する記述です。

Cowork にこの Playbook を見せて「冪等性に問題がある箇所を指摘して」と依頼すれば、shell タスクで creates / changed_when が未指定の箇所などをレビューさせられます。

実例 3: OpenTofu の Kubernetes provider でリソースを IaC 化

k3s クラスタが Ansible で構築済みであれば、その上の Kubernetes リソース(Deployment・Service・ConfigMap など)を OpenTofu の Kubernetes provider で IaC 化できます。Ansible がノードを準備し、OpenTofu がワークロードを宣言するという二段階の分担になります。

terraform {
  required_providers {
    kubernetes = {
      source  = "opentofu/kubernetes"
      version = "~> 2.0"
    }
  }
  required_version = ">= 1.11"
}

provider "kubernetes" {
  config_path = "~/.kube/config"
}

resource "kubernetes_deployment" "nginx" {
  metadata {
    name      = "nginx-lab"
    namespace = "default"
  }
  spec {
    replicas = 1
    selector {
      match_labels = { app = "nginx-lab" }
    }
    template {
      metadata { labels = { app = "nginx-lab" } }
      spec {
        container {
          name  = "nginx"
          image = "nginx:1.27"
        }
      }
    }
  }
}

vSphere provider(opentofu/vsphere v2.9.2)も利用可能なため、VMware 環境を学習している場合は vSphere 上の VM を OpenTofu で管理する構成も書けます。ただし VCF9 のフルハンズオンはホームラボでのライセンス費用の問題から、本シリーズでは OpenTofu の vSphere provider の存在を紹介するにとどめます。

Cowork で IaC コードを「育てる」ループ

ここまでで OpenTofu と Ansible の基本フローが整いました。この節では Cowork をレビュー伴走役として使い、HCL・YAML・実行ログを反復的に改善するループの組み方を整理します。

フォルダスコープに iac/ を含める

Cowork の IaC プロジェクト(例: homelab-iac)を作成し、フォルダスコープに HomeLab\iac\HomeLab\logs\ を指定します。これにより Cowork はセッション内で HCL・YAML・実行ログの 3 種類のファイルを直接参照できる状態になります。

プロジェクトのインストラクションには次のような宣言を置きます。

私は個人インフラエンジニア。本プロジェクトは HomeLab の IaC(OpenTofu + Ansible)コードのレビューと改善に特化する。
共通前提は HomeLab\_memory\memory.md に記述している。毎セッション開始時に読むこと。

作業フォルダ:
- HomeLab\iac\opentofu\   : HCL(プロビジョニング)
- HomeLab\iac\ansible\    : YAML Playbook / inventory / roles(OS 構成管理)
- HomeLab\logs\           : tofu plan/apply 出力・Ansible 実行ログ
- HomeLab\docs\iac\_weekly\ : 週次 IaC レビュー記録

レビュー依頼時の出力形式:
- 問題箇所のファイル名と行番号
- 問題の種別(冪等性・変数化・セキュリティ・命名)
- 修正案(コードブロックで示す)

認証情報(API キー・SSH 秘密鍵・パスワード)はコードやログに直書きしない。
フォルダスコープ内に .env ファイルや鍵ファイルを置かない。

レビュー依頼の標準プロンプト 3 種

レビューを依頼するプロンプトはセッションごとに書き直さずに、次の 3 種類を状況に応じて使い分けます。

HCL の構造レビュー: 「iac/opentofu/gcp/main.tf を読んで、変数化されていない値・未使用の output・命名規約の不統一を指摘して」

Playbook の冪等性レビュー: 「iac/ansible/playbooks/common/sshd-hardening.yml を読んで、2 回目実行で changed が残る可能性があるタスクを特定して。creates / changed_when の未指定、shell / command モジュールの不適切な使用、モジュール選択の誤りを観点として見て」

tofu plan -json の差分解析: 「logs/gcp/plan.json を読んで、この plan で削除・再作成されるリソースを一覧表示して。予期しない破壊的変更があれば理由を説明して」

iac-review スキルで観点を定型化する

スキル(Skill)の使用は全プラン(Free 含む。スキルはコード実行環境で動くため、Claude の「code execution(コード実行)」機能が有効であることが前提)で可能ですが、カスタムスキルのインストールPro 以上が前提になります(Claude Help Center「Use Skills in Claude」「How to create custom Skills」, 2026-05-03 確認)。本シリーズは Pro / Max 主軸のため、以下のカスタムスキルが使える前提で進めます。

前述の 3 種のレビュー観点を 1 つの SKILL.md にまとめた iac-review スキルを作成することで、毎回プロンプトを書き直すコストをなくせます。

---
name: iac-review
description: |
  OpenTofu(HCL)または Ansible Playbook(YAML)のレビューを行う。
  指定ファイルまたはディレクトリを読み込み、問題箇所・種別・修正案を
  表形式で出力する。「iac-review を使って」または「このファイルをレビューして」
  と依頼されたときに呼び出す。
---

## レビュー観点

### OpenTofu(HCL)
- ハードコードされた値(IP アドレス・プロジェクト ID・リージョン)の変数化漏れ
- 未使用の output ブロック
- required_version / required_providers のバージョン制約が緩すぎる(`>= x.y` のみで上限なし)
- リソース名・変数名の命名規約の不統一(ハイフン vs アンダースコア)
- sensitive な値(パスワード・API キー)の直書き

### Ansible(YAML Playbook)
- 冪等性: shell / command モジュールで creates / changed_when が未指定
- モジュール選択: apt / yum でできることを command で書いている
- 認証情報の直書き(vars セクションへのパスワード記述)
- handlers の notify 先が存在しない
- become: true が不要なタスクに付与されている

### 共通
- フォルダ構造(HomeLab\iac\ 規約)に沿っているか
- 変数名・ファイル名の命名規約との整合

## 出力フォーマット
| ファイル | 行番号 | 種別 | 問題の概要 | 修正案 |
|---|---|---|---|---|

作成後は Claude Desktop の「Customize > Skills」でインストールして ON にします。name フィールドは 64 字以下・小文字英数字とハイフンのみという制約があります(Help Center「How to create custom Skills」)。

Cowork に認証情報を読ませない
フォルダスコープ内に .env ファイル・サービスアカウントキー(JSON)・SSH 秘密鍵を置きません。.gitignore と同様の除外リストを HomeLab\_memory\memory.md の「やってはいけないこと」セクションに記載し、プロジェクトのインストラクションにも「認証情報をコードやログに直書きしない」と明記します。Cowork はフォルダスコープ内のファイルを読み込めるため、鍵ファイルをスコープ内に置くとそのパスが Cowork のコンテキストに入ります(第 2 回「memory.md 初期テンプレート」より継承)。

logs/ 蓄積パターンとの接続

第 3 回: Cowork で 4 技術並行学習を回す — モダリティ別の記録術で確立した logs/ 蓄積パターンを、IaC レビューループにそのまま接続できます。

tofu plantofu apply の出力・Ansible Playbook の実行結果を第 3 回のログフォーマット(目的・実行コマンド・出力(抜粋)・エラーメッセージ・仮説・次にやること)で logs/gcp/ または logs/kubernetes/ に保存します。

蓄積されたログを Cowork が参照することで、過去の apply 差分との比較や、エラーパターンの再発確認を依頼できる状態になります。

スケジュールタスクで週次 IaC 点検を設定する

週次スケジュールタスク(Scheduled Task、weekly 頻度)で「今週 commit された HCL / YAML を iac-review スキルでレビューして残課題を docs/iac/_weekly/YYYY-WW.md に追記して」というタスクを設定すると、コードの劣化を週単位で検知できます。

スケジュールタスクの実行前提
スケジュールタスクは PC が起動かつ Claude Desktop が起動している状態でのみ実行されます。PC がスリープ中はタスクがスキップされ、復帰時に実行される設計です(Claude Help Center「Schedule recurring tasks in Claude Cowork」, 2026-05-03 確認)。週末に PC を起動しない習慣がある場合、weekly タスクが実行されないことがあります。その場合は weekdays(平日)や manual 頻度への変更を検討します。

まとめと次回予告

本記事で整理した内容を振り返ります。

  • OpenTofu はインフラ層(VM・VPC・GKE・K8s リソースの作成・破棄)、Ansible は OS 内部層(パッケージ・サービス・FW・ミドルウェアの構成管理)、Cowork はレビュー伴走役という三者の役割分担を最初に確立します
  • Hyper-V 上の Linux VM は公式 Hyper-V provider が存在しないため、VM 作成は PowerShell / 手動で行い、内部構成を Ansible が担います
  • OpenTofu 1.11 系(v1.11.0 は 2025-12-09 公開、現行安定版)と Ansible 13.6.0(現行コミュニティパッケージ最新、2026-04-19 頃公開)が 2026-05-03 時点の前提バージョンです
  • tofu show -json plan.tfplan でプランを JSON 化してから Cowork に渡すと、差分解析の依頼精度が上がります
  • Playbook の冪等性確認は --check --diff と 2 回目実行の changed=0 確認が基本です
  • iac-review カスタムスキルで HCL / YAML のレビュー観点を定型化すると、セッションごとにプロンプトを書き直すコストをなくせます(カスタムスキルのインストールは Pro 以上)
  • 週次スケジュールタスクと logs/ 蓄積の組み合わせで、コードの劣化を週単位で検知するループが完成します

第 4 回までで iac/ 配下の HCL・YAML と logs/ 配下の plan/apply・Playbook 実行ログをそろえる手法が出そろいました。第 6 回: ホームラボの検証ログを技術ブログ記事に変換するでは、こうして蓄積した素材を入力に Cowork が Gutenberg ブロック形式の技術ブログ記事を出力するフローを扱います。

試行錯誤のログと IaC コード変更履歴が、記事の根拠と実例として機能する設計になっています。