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
としています。
- Ansible サーバー自身の
- 対象のホスト
tasks
hosts
に記載のホストが実行する処理
name
- タスクの名前
ansible-playbook apply.yml
で Playbook を実行するとTASK [create and update resources by terraform]
のようにタスク名が表示されます。
- タスクの名前
community.general.terraform
- モジュール名
- Ansible で 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
Follow @fujioka57621469