TerraformとAnsibleを組み合わせてGoogle Cloudのネットワークリソースを作成してみる

記事タイトルとURLをコピーする

G-gen の藤岡です。当記事では、Terraform と Ansible を組み合わせて、Google Cloud(旧称 GCP)のネットワークリソースの作成をします。

サービスの概要

Terraform とは

Terraform は、 Infrastructure as Code (IaC) を実現するオープンソースのツールです。使用方法については以下の記事をご参照ください。 blog.g-gen.co.jp

Ansible とは

Ansible は、Red Hat 社が開発するオープンソースの構成管理ツールです。サーバーの設定やソフトウェアのデプロイ、パッケージのインストール等のタスクを自動化できます。またサーバーだけでなく、Cisco や Juniper といったネットワーク機器の管理にも使うことができます。

代表的な構成管理ツールには、Ansible の他に Puppet や Chef がありますが、Ansible は管理対象の機器へエージェントのインストールが不要です。例えば管理対象機器が Linux の場合、Ansible サーバーから SSH できる環境であれば実行可能です。

Ansible では、ソフトウェアのインストールや設定といった特定のアクションを タスク といい、YAML 形式で記述します。タスクが書かれたファイルを Playbook と呼びます。
後述する ansible-playbook コマンドで Playbook を実行することで、記載されたタスクが処理されていきます。

Terraform と Ansible の違い

Terraform と Ansible は共に構成管理ツールですが、得意とする領域が異なります。

Terraform はインフラ層の構成管理を得意とするのに対し、Ansible は OS やミドルウェア層の構成管理を得意とします。

Red Hat 社が両者の違いに関する ドキュメント を公開していますので、そちらもご参照ください。

検証の背景

当記事で作成するリソースはネットワークリソースのため、本来であれば Terraform のみで完結します。

しかし、今後 Ansible でソフトウェアの設定ファイル管理についても検証したいため、その前段としてネットワークリソースのみを Terraform と Ansible を組み合わせて作成してみました。

前提

構成

構成は以下の通りです。構成図内の ansible-server の作成は当記事では触れません。今回は VPC リソースのみを作成しますが、Ansible の ダイナミックインベントリ を機能を使うことで、Terraform で作成したインスタンスの OS レイヤ以上のソフトウェアの設定等の管理をすることもできます。ダイナミックインベントリを Google Cloud 環境で使うには、google.cloud.gcp_compute inventory のプラグインが必要です。

構成図

インスタンス情報

GCE インスタンス(ansible-server)の OS 情報は以下の通りです。

fujioka@ansible-server:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.2 LTS
Release:        22.04
Codename:       jammy
fujioka@ansible-server:~$ 

ディレクトリ構成

ディレクトリ構成は以下の通りです。

fujioka@ansible-server:~$ tree
.
└── ansible-playbook
    ├── apply.yml
    ├── destroy.yml
    └── terraform
        └── main.tf

2 directories, 3 files
fujioka@ansible-server:~$

各ファイルの中身は以下の通りです。

  • apply.yml:Ansible リソース作成用 Playbook
- hosts: localhost
  tasks:
    - name: create and update resources by terraform
      community.general.terraform:
        project_path: 'terraform/'
        state: present
  • destroy.yml:Ansible リソース破棄用 Playbook
- hosts: localhost
  connection: local
  gather_facts: no

  tasks:
    - name: destroy resources by terraform
      terraform:
        project_path: 'terraform/'
        state: absent
  • main.tf:Terraform ファイル(${PROJECT_ID} は自身のプロジェクト ID に置き換えます)
# difine provider
provider "google" {
  project = "${PROJECT_ID}"
  region  = "asia-northeast1"
  zone    = "asia-northeast1-a"
}

terraform {
  required_version = "~> 1.2"
  required_providers {
    google = ">= 4.32.0"
  }
}

# create vpc
resource "google_compute_network" "vpc" {
  name                    = "vpc"
  auto_create_subnetworks = "false"
  routing_mode            = "GLOBAL"
}

# create subnet
resource "google_compute_subnetwork" "subnet" {
  name          = "subnet"
  ip_cidr_range = "10.0.10.0/24"
  network       = google_compute_network.vpc.name
}

Playbook の解説

当記事では apply.yml と destroy.yml の 2 つの Playbook を使用します。ここでは以下の Ansible リソース作成用 Playbook である apply.yml について簡単に解説します。

#  Ansible リソース作成用 Playbook
- hosts: localhost
  tasks:
    - name: create and update resources by terraform
      community.general.terraform:
        project_path: 'terraform/'
        state: present
  • hosts
    • 対象のホスト
      • Ansible サーバー自身の terraform/ 配下にあるファイルを実行するため localhost としています。
  • tasks
    • hosts に記載のホストが実行する処理
  • name
    • タスクの名前
      • ansible-playbook apply.yml で Playbook を実行すると TASK [create and update resources by terraform] のようにタスク名が表示されます。
  • community.general.terraform
    • モジュール名
  • project_path
    • Terraform ディレクトリのルートのパス
  • state

    • ターゲットの状態を定義
      • present は Terraform で定義されたリソースを作成します。absent の場合はリソースを削除します。community.general.terraform モジュールでは デフォルトpresent です。
  • 参考:Playbook の概要

Terraform のインストール

ドキュメント に従い、Terraform をインストールします。

$ sudo apt-get update && sudo apt-get install -y gnupg software-properties-common
$ wget -O- https://apt.releases.hashicorp.com/gpg | \
gpg --dearmor | \
sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
$ gpg --no-default-keyring \
--keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg \
--fingerprint
$ echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/hashicorp.list
$ sudo apt update
$ sudo apt-get install terraform

インストール後のバージョンは以下の通りです。

fujioka@ansible-server:~$ terraform --version
Terraform v1.4.4
on linux_amd64
fujioka@ansible-server:~$ 

Ansible のインストール

ドキュメント に従い、Ansible をインストールします。

$ sudo apt update
$ sudo apt install software-properties-common
$ sudo add-apt-repository --yes --update ppa:ansible/ansible
$ sudo apt install ansible

インストール後のバージョンは以下の通りです。

fujioka@ansible-server:~$ ansible --version
ansible [core 2.14.4]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/fujioka/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/fujioka/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] (/usr/bin/python3)
  jinja version = 3.0.3
  libyaml = True
fujioka@ansible-server:~$ 

ADC の設定と Terraform の初期化

Google Cloud 環境に対して Terraform が実行できるよう、アプリケーションのデフォルト認証情報(ADC)を設定します。

fujioka@ansible-server:~/ansible-playbook$ gcloud auth application-default login

You are running on a Google Compute Engine virtual machine.
The service credentials associated with this virtual machine
will automatically be used by Application Default
Credentials, so it is not necessary to use this command.

If you decide to proceed anyway, your user credentials may be visible
to others with access to this virtual machine. Are you sure you want
to authenticate with your personal account?

Do you want to continue (Y/n)?  

Go to the following link in your browser:
~
Credentials saved to file: [/home/fujioka/.config/gcloud/application_default_credentials.json]

These credentials will be used by any library that requests Application Default Credentials (ADC).
~
fujioka@ansible-server:~/ansible-playbook$

~/ansible-playbook/terraform に移動をし、Terraform の初期化をします。

fujioka@ansible-server:~/ansible-playbook/terraform$ terraform init

Initializing the backend...
~
Terraform has been successfully initialized!
~
fujioka@ansible-server:~/ansible-playbook/terraform$ 

構文チェック

ansible-playbook コマンドに --syntax-check をつけることで Playbook の構文チェックができます。~/ansible-playbook に移動をし、実行します。

fujioka@ansible-server:~/ansible-playbook$ ansible-playbook apply.yml --syntax-check
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'

playbook: apply.yml
fujioka@ansible-server:~/ansible-playbook$

リソースの作成

ansible-playbook apply.yml コマンドで Playbook を実行します。

fujioka@ansible-server:~/ansible-playbook$ ansible-playbook apply.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'

PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [create and update resources by terraform] ********************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

fujioka@ansible-server:~/ansible-playbook$ 

Terraform で記述したリソースである、VPC とサブネットが作成されています。

作成リソース

terraform.tfstate にリソースの状態が記載されています。(一部省略 / 伏せ字)

fujioka@ansible-server:~/ansible-playbook$ cat terraform/terraform.tfstate
{
  "version": 4,
  "terraform_version": "1.4.4",
  "serial": 10,
  "lineage": "xxxx",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "google_compute_network",
      "name": "vpc",
      "provider": "provider[\"registry.terraform.io/hashicorp/google\"]",
~
    {
      "mode": "managed",
      "type": "google_compute_subnetwork",
      "name": "subnet",
      "provider": "provider[\"registry.terraform.io/hashicorp/google\"]",
~
fujioka@ansible-server:~/ansible-playbook$

リソースの削除

ansible-playbook destroy.yml コマンドで Playbook を実行します。これで作成したリソースが破棄されます。

fujioka@ansible-server:~/ansible-playbook$ ansible-playbook destroy.yml 
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'

PLAY [localhost] ***************************************************************

TASK [destroy resources by terraform] ******************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

fujioka@ansible-server:~/ansible-playbook$ 

terraform.tfstate 上も更新されています。(一部伏せ字)

fujioka@ansible-server:~/ansible-playbook$ cat terraform/terraform.tfstate
{
  "version": 4,
  "terraform_version": "1.4.4",
  "serial": 13,
  "lineage": "xxxx",
  "outputs": {},
  "resources": [],
  "check_results": null
}
fujioka@ansible-server:~/ansible-playbook$ 

藤岡 里美 (記事一覧)

クラウドソリューション部

数年前までチキン売ったりドレスショップで働いてました!2022年9月 G-gen にジョイン。ハイキューの映画を4回は見に行きたい。

Google Cloud All Certifications Engineer / Google Cloud Partner Top Engineer 2024