この記事は、Ansible Advent Calendar 2023 の3日目のエントリです。
はじめに
気になっていた Terraform Provider for Ansible をこの機に触ってみました。
- Terraform Registry
- GitHub - ansible/terraform-provider-ansible: community terraform provider for ansible
Terraform Provider for Ansible のまとめ
- Terrafromの定義ファイルに
resource "ansible_host"
を追加する- 上記の結果がtfstateに記載される
- Ansibleのインベントリファイルに
cloud.terraformプラグイン
を指定する- インベントリファイルがtfstateの該当箇所を読み込む
環境
Ubuntu 22.04.3に構築しています。
- Ansible環境
- Ansible core : 2.15.6
- Python : 3.10.12
- cloud.terraform : 2.0.0
- Terraform環境
- Terraform : 1.6.5
環境の準備
Ansibleコレクションにて、cloud.terraform をインストールします。
$ ansible-galaxy collection install cloud.terraform Starting galaxy collection install process Process install dependency map Starting collection install process Downloading https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/cloud-terraform-2.0.0.tar.gz to /home/ubuntu/.ansible/tmp/ansible-local-12661qsgjsrrt/tmpzhqh3nnq/cloud-terraform-2.0.0-a_5loo9d Installing 'cloud.terraform:2.0.0' to '/home/ubuntu/.ansible/collections/ansible_collections/cloud/terraform' cloud.terraform:2.0.0 was installed successfully $ $ $ ansible-galaxy collection list # /home/ubuntu/.ansible/collections/ansible_collections Collection Version ----------------------------- ------- cloud.terraform 2.0.0 (略) $
次に、terraformのansibleプラグインをインストールします。 ただしterrafrom initでインストールされるため、準備では割愛します。
TerraformでEC2インスタンスを構築する
3台のEC2インスタンスを構築します。
定義ファイルの作成
鍵はあらかじめ作成してあるものを流用、セキュリティグループはSSHのみ開けています。
- インスタンス名
- mito
- mito-ec2
- mito-ec22
terraform { required_providers { ansible = { version = "~> 1.1.0" source = "ansible/ansible" } } } ### ansible host details 今回のメイン。後述のtfstateに記載される。 resource "ansible_host" "inventory" { for_each = var.instance name = aws_instance.server[each.value.name].public_dns groups = ["test_group"] variables = { ansible_user = "ec2-user", ansible_ssh_private_key_file = "~/.ssh/xxx.pem", # Terraformのkey指定と違い、ファイル名なので拡張子も必要。 } } provider "aws" { region = "ap-northeast-1" } variable instance { type = map default = { mito = { name = "mito" }, mito-ec2 = { name = "mito-ec2" }, mito-ec22 = { name = "mito-ec22" }, } } resource "aws_instance" "server" { for_each = var.instance ami = "ami-012261b9035f8f938" instance_type = "t2.micro" key_name = "xxx" associate_public_ip_address = "true" vpc_security_group_ids = [aws_security_group.blog_sg.id] tags = { Name = each.value.name } } resource "aws_security_group" "blog_sg" { name = "blog_sg" description = "blog_sg" dynamic "ingress" { for_each = [22] content { from_port = ingress.value to_port = ingress.value protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } }
terraform applyの実行結果
EC2インスタンス作成のほか、tfstateには以下のように resource "ansible_host"
の結果が記載されます。
"resources": [ { "mode": "managed", "type": "ansible_host", "name": "inventory", "provider": "provider[\"registry.terraform.io/ansible/ansible\"]", "instances": [ { "index_key": "mito", "schema_version": 0, "attributes": { "groups": [ "test_group" ], "id": "ec2-13-114-117-20.ap-northeast-1.compute.amazonaws.com", "name": "ec2-13-114-117-20.ap-northeast-1.compute.amazonaws.com", "variables": { "ansible_ssh_private_key_file": "~/.ssh/xxx.pem", "ansible_user": "ec2-user" } },
Ansibleのansible-inventoryコマンドを実行する
まずは、resource "ansible_host"
の結果がどう反映されるか確認するため、ansible-inventoryコマンドを実行します。
インベントリファイルの作成
cloud.terraformプラグインを指定します。
--- plugin: cloud.terraform.terraform_provider
ansible-inventoryコマンドの実行結果
無事に、ホスト情報が出力されました。
$ ansible-inventory -i inventory.yml --graph --vars @all: |--@ungrouped: |--@test_group: | |--ec2-13-114-117-20.ap-northeast-1.compute.amazonaws.com | | |--{ansible_ssh_private_key_file = ~/.ssh/xxx.pem} | | |--{ansible_user = ec2-user} | |--ec2-35-78-213-104.ap-northeast-1.compute.amazonaws.com | | |--{ansible_ssh_private_key_file = ~/.ssh/xxx.pem} | | |--{ansible_user = ec2-user} | |--ec2-13-231-192-241.ap-northeast-1.compute.amazonaws.com | | |--{ansible_ssh_private_key_file = ~/.ssh/xxx.pem} | | |--{ansible_user = ec2-user} $
Ansibleのplaybookを実行する
インベントリファイルを指定して、簡単なPlaybookを実行し、動作を確認してみます。
playbookの作成
gitのみインストールします。
--- - hosts: all gather_facts: no become: yes tasks: - name: install git ansible.builtin.yum: name: git state: present
ansible.cfgの作成
Fingerprintのチェックを無効にしておきます。
[defaults] host_key_checking = False
playbookの実行結果
Terraform Provider for Ansibleを指定したインベントリファイルで、正常にPlaybookが実行できました。
$ ansible-playbook -i inventory.yml playbook.yml PLAY [all] ************************************************************************************************* TASK [install git] ***************************************************************************************** changed: [ec2-13-114-117-20.ap-northeast-1.compute.amazonaws.com] changed: [ec2-35-78-213-104.ap-northeast-1.compute.amazonaws.com] changed: [ec2-13-231-192-241.ap-northeast-1.compute.amazonaws.com] PLAY RECAP ************************************************************************************************ ec2-13-114-117-20.ap-northeast-1.compute.amazonaws.com : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 ec2-13-231-192-241.ap-northeast-1.compute.amazonaws.com : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 ec2-35-78-213-104.ap-northeast-1.compute.amazonaws.com : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 $
終わりに
インベントリーファイルに、フィルターを組み合わせて使う感じで良さそう。