概要
Terraform 用の Ansible 認定コンテンツ コレクション(v1.0.0)が利用可能になった様なので触ってみました。
情報リンク
Terraform 用の Ansible 認定コンテンツ コレクションが利用可能になったことを発表できることをうれしく思います。 Ansible Automation Platform サブスクリプションの一部として Automation Hub で利用できるようになりました
- redhat
- github
導入
$ ansible-galaxy collection install cloud.terraform
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Downloading https://galaxy.ansible.com/download/cloud-terraform-1.0.0.tar.gz to /home/vagrant/.ansible/tmp/ansible-local-29742d9psx0sz/tmpulp0lvx7/cloud-terraform-1.0.0-_hacx70x
Installing 'cloud.terraform:1.0.0' to '/home/vagrant/.ansible/collections/ansible_collections/cloud/terraform'
cloud.terraform:1.0.0 was installed successfully
導入されたファイルツリー
$ tree ~/.ansible/collections/ansible_collections/
/home/vagrant/.ansible/collections/ansible_collections/
|-- cloud
| `-- terraform
| |-- CHANGELOG.rst
| |-- FILES.json
| |-- LICENSE
| |-- MANIFEST.json
| |-- README.md
| |-- changelogs
| | |-- changelog.yaml
| | |-- config.yaml
| | `-- fragments
| | `-- 0001-initial.yml
| |-- docs
| | `-- docsite
| | `-- links.yml
| |-- meta
| | `-- runtime.yml
| |-- plugins
| | |-- module_utils
| | | `-- version.py
| | `-- modules
| | |-- terraform.py
| | `-- terraform_output.py
| |-- requirements.txt
| |-- requirements.yml
| |-- roles
| | |-- git_plan
| | | |-- README.md
| | | |-- meta
| | | | `-- argument_specs.yml
| | | `-- tasks
| | | `-- main.yml
| | `-- inventory_from_outputs
| | |-- README.md
| | |-- meta
| | | `-- argument_specs.yml
| | `-- tasks
| | `-- main.yml
| |-- test-requirements.txt
| `-- tests
| |-- integration
| | `-- targets
| | |-- action_groups
| | | |-- files
| | | | `-- nothing.tf
| | | `-- tasks
| | | `-- main.yml
| | |-- aws
| | | |-- files
| | | | `-- cloud.tf
| | | `-- tasks
| | | `-- main.yml
| | |-- azure
| | | |-- files
| | | | `-- cloud.tf
| | | `-- tasks
| | | `-- main.yml
| | |-- complex_variables
| | | |-- files
| | | | |-- main.tf
| | | | `-- variables.tf
| | | `-- tasks
| | | `-- main.yml
| | |-- gcp
| | | |-- files
| | | | `-- cloud.tf
| | | `-- tasks
| | | `-- main.yml
| | |-- list_vars_passthrough
| | | |-- files
| | | | `-- main.tf
| | | `-- tasks
| | | `-- main.yml
| | |-- local
| | | |-- files
| | | | `-- write_file.tf
| | | `-- tasks
| | | `-- main.yml
| | |-- provider_upgrade
| | | |-- tasks
| | | | |-- main.yml
| | | | `-- test_provider_upgrade.yml
| | | |-- templates
| | | | `-- main.tf.j2
| | | `-- vars
| | | `-- main.yml
| | |-- state_planned
| | | |-- files
| | | | `-- write_file.tf
| | | `-- tasks
| | | `-- main.yml
| | |-- terraform_output
| | | |-- files
| | | | `-- outputs.tf
| | | `-- tasks
| | | `-- main.yml
| | |-- test_git_plan
| | | |-- files
| | | | `-- write_file.tf
| | | `-- tasks
| | | `-- main.yml
| | `-- test_inventory_from_outputs
| | |-- files
| | | `-- create_inventory.tf
| | `-- tasks
| | `-- main.yml
| `-- unit
| |-- compat
| | |-- __init__.py
| | |-- builtins.py
| | |-- mock.py
| | `-- unittest.py
| `-- plugins
| `-- modules
| |-- cloud
| | `-- misc
| | `-- test_terraform.py
| `-- utils.py
`-- cloud.terraform-1.0.0.info
`-- GALAXY.yml
64 directories, 56 files
以下の環境で試す。
環境
- Red Hat Enterprise Linux 8.5 (Ootpa)
- ansible-6.3.0-1.el8.noarch
- ansible-core-2.13.3-1.el8.x86_64
- Terraform v1.3.6 on linux_amd64
Playbook例
---
- hosts: localhost
gather_facts: false
vars:
project_dir: terraform/ # 最後の/が必要
tasks:
- name: Basic deploy of a service
cloud.terraform.terraform:
project_path: "{{ project_dir }}"
state: present
force_init: true
output "test" {
value = "Hello Terraform!"
}
[defaults]
verbosity = 1
stdout_callback = ansible.posix.debug
ansible.posix.debug は、ansible-galaxy collection install ansible.posix にて追加導入
Playbook実行
初回
$ ansible-playbook site.yml
Using /home/vagrant/repo/terraform-collection-test/ansible.cfg as config file
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: An error occurred while calling ansible.utils.display.initialize_locale (unsupported locale setting). This may result in incorrectly calculated text widths that can cause Display
to print incorrect line lengths
PLAY [localhost] *****************************************************************************************************************************************************************************
TASK [Basic deploy of a service] *************************************************************************************************************************************************************
changed: [localhost] => {
"changed": true,
"command": "/usr/bin/terraform apply -no-color -input=false -auto-approve -lock=true /tmp/tmph6h9tryt.tfplan",
"outputs": {
"test": {
"sensitive": false,
"type": "string",
"value": "Hello Terraform!"
}
},
"state": "present",
"workspace": "default"
}
STDOUT:
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
test = "Hello Terraform!"
PLAY RECAP ***********************************************************************************************************************************************************************************
localhost : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
意図通り、outputsが得られた。
/tmp に /tmp/tmph6h9tryt.tfplan など tfplan ファイルが作成されていく。
```
$ tree -a .
.
├── ansible.cfg
├── site.yml
└── terraform
├── output.tf
└── terraform.tfstate
1 directory, 5 files
今回はバックエンドを構成していないので、terraform.tfstateファイルが作成されている。
```json:./terraform/terraform.tfstate
{
"version": 4,
"terraform_version": "1.3.6",
"serial": 1,
"lineage": "32d997f1-7e25-9783-9ce9-c7d753ee5086",
"outputs": {
"test": {
"value": "Hello Terraform!",
"type": "string"
}
},
"resources": [],
"check_results": null
}
2回目
$ ansible-playbook site.yml
Using /home/vagrant/repo/terraform-collection-test/ansible.cfg as config file
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: An error occurred while calling ansible.utils.display.initialize_locale (unsupported locale setting). This may result in incorrectly calculated text widths that can cause Display
to print incorrect line lengths
PLAY [localhost] *****************************************************************************************************************************************************************************
TASK [Basic deploy of a service] *************************************************************************************************************************************************************
ok: [localhost] => {
"changed": false,
"command": "/usr/bin/terraform apply -no-color -input=false -auto-approve -lock=true /tmp/tmpfnyqh4yc.tfplan",
"outputs": {
"test": {
"sensitive": false,
"type": "string",
"value": "Hello Terraform!"
}
},
"state": "present",
"workspace": "default"
}
STDOUT:
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.
PLAY RECAP ***********************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
レジストリー変数で取り出せる内容には outputs が含まれるが、変更がないためか、STDOUT には outputs が含まれなかった。
terraform.tfstateを削除して実行すると STDOUT に outputs が表示される。
参考: ansible-doc cloud.terraform.terraform
$ ansible-doc cloud.terraform.terraform
Using /home/hiro/repo/terraform-ansible/ansible.cfg as config file
> CLOUD.TERRAFORM.TERRAFORM (/home/hiro/.ansible/collections/ansible_collections/cloud/terraform/plugins/modules/terraform.py)
Provides support for deploying resources with Terraform and
pulling resource information back into Ansible.
OPTIONS (= is mandatory):
- backend_config
A group of key-values to provide at init stage to the
-backend-config parameter.
"default": !!null "null"
"type": "dict"
added in: version 1.0.0 of cloud.terraform
- backend_config_files
The path to a configuration file to provide at init state to
the -backend-config parameter. This can accept a list of paths
to multiple configuration files.
"default": !!null "null"
"elements": "path"
"type": "list"
added in: version 1.0.0 of cloud.terraform
- binary_path
The path of a terraform binary to use.
"default": !!null "null"
"type": "path"
added in: version 1.0.0 of cloud.terraform
- check_destroy
Apply only when no resources are destroyed. Note that this
only prevents "destroy" actions, but not "destroy and re-
create" actions. This option is ignored when `state=absent'.
"default": !!bool "false"
"type": "bool"
added in: version 1.0.0 of cloud.terraform
- complex_vars
Enable/disable capability to handle complex variable
structures for `terraform'.
If `true' the `variables' also accepts dictionaries, lists,
and booleans to be passed to `terraform'. Strings that are
passed are correctly quoted.
When disabled, supports only simple variables (strings,
integers, and floats), and passes them on unquoted.
"default": !!bool "false"
"type": "bool"
added in: version 1.0.0 of cloud.terraform
- force_init
To avoid duplicating infra, if a state file can't be found
this will force a `terraform init'. Generally, this should be
turned off unless you intend to provision an entirely new
Terraform deployment.
"default": !!bool "false"
"type": "bool"
added in: version 1.0.0 of cloud.terraform
- init_reconfigure
Forces backend reconfiguration during init.
"default": !!bool "false"
"type": "bool"
added in: version 1.0.0 of cloud.terraform
- lock
Enable statefile locking, if you use a service that accepts
locks (such as S3+DynamoDB) to store your statefile.
"default": !!bool "true"
"type": "bool"
added in: version 1.0.0 of cloud.terraform
- lock_timeout
How long to maintain the lock on the statefile, if you use a
service that accepts locks (such as S3+DynamoDB).
"default": !!null "null"
"type": "int"
added in: version 1.0.0 of cloud.terraform
- overwrite_init
Run init even if `.terraform/terraform.tfstate' already exists
in `project_path'.
"default": !!bool "true"
"type": "bool"
added in: version 1.0.0 of cloud.terraform
- parallelism
Restrict concurrent operations when Terraform applies the
plan.
"default": !!null "null"
"type": "int"
added in: version 1.0.0 of cloud.terraform
- plan_file
The path to an existing Terraform plan file to apply. If this
is not specified, Ansible will build a new TF plan and execute
it.
Note that this option is required if 'state' has the 'planned'
value. In this case, the plan file is only generated, but not
applied.
"default": !!null "null"
"type": "path"
added in: version 1.0.0 of cloud.terraform
- plugin_paths
List of paths containing Terraform plugin executable files.
Plugin executables can be downloaded from
https://releases.hashicorp.com/.
When set, the plugin discovery and auto-download behavior of
Terraform is disabled.
The directory structure in the plugin path can be tricky. The
Terraform docs
https://learn.hashicorp.com/tutorials/terraform/automate-
terraform#pre-installed-plugins show a simple directory of
files, but actually, the directory structure has to follow the
same structure you would see if Terraform auto-downloaded the
plugins. See the examples below for a tree output of an
example plugin directory.
"default": !!null "null"
"elements": "path"
"type": "list"
added in: version 1.0.0 of cloud.terraform
= project_path
The path to the root of the Terraform directory with the
vars.tf/main.tf/etc to use.
"type": "path"
added in: version 1.0.0 of cloud.terraform
- provider_upgrade
Allows Terraform init to upgrade providers to versions
specified in the project's version constraints.
"default": !!bool "false"
"type": "bool"
added in: version 1.0.0 of cloud.terraform
- purge_workspace
Only works with state = absent
If true, the workspace will be deleted after the "terraform
destroy" action.
The 'default' workspace will not be deleted.
"default": !!bool "false"
"type": "bool"
added in: version 1.0.0 of cloud.terraform
- state
Goal state of given stage/project.
Option `planned` is deprecated. Its function is equivalent to
running the module in check mode.
choices: ["present", "absent", "planned"]
"default": "present"
"type": "str"
added in: version 1.0.0 of cloud.terraform
- state_file
The path to an existing Terraform state file to use when
building plan. If this is not specified, the default
`terraform.tfstate' will be used.
This option is ignored when plan is specified.
"default": !!null "null"
"type": "path"
added in: version 1.0.0 of cloud.terraform
- targets
A list of specific resources to target in this
plan/application. The resources selected here will also auto-
include any dependencies.
"default": !!null "null"
"elements": "str"
"type": "list"
added in: version 1.0.0 of cloud.terraform
- variables
A group of key-values pairs to override template variables or
those in variables files. By default, only string and number
values are allowed, which are passed on unquoted.
Support complex variable structures (lists, dictionaries,
numbers, and booleans) to reflect terraform variable syntax
when `complex_vars=true'.
Ansible integers or floats are mapped to terraform numbers.
Ansible strings are mapped to terraform strings.
Ansible dictionaries are mapped to terraform objects.
Ansible lists are mapped to terraform lists.
Ansible booleans are mapped to terraform booleans.
*Note* passwords passed as variables will be visible in the
log output. Make sure to use `no_log=true' in production!
"default": !!null "null"
"type": "dict"
added in: version 1.0.0 of cloud.terraform
- variables_files
The path to a variables file for Terraform to fill into the TF
configurations. This can accept a list of paths to multiple
variables files.
Up until Ansible 2.9, this option was usable as
`variables_file'.
aliases: ["variables_file"]
"default": !!null "null"
"elements": "path"
"type": "list"
added in: version 1.0.0 of cloud.terraform
- workspace
The terraform workspace to work with.
"default": "default"
"type": "str"
added in: version 1.0.0 of cloud.terraform
NOTES:
* To just run a `terraform plan', use check mode.
REQUIREMENTS: terraform
AUTHOR: Ryan Scott Brown (@ryansb)
EXAMPLES:
- name: Basic deploy of a service
cloud.terraform.terraform:
project_path: '{{ project_dir }}'
state: present
- name: Define the backend configuration at init
cloud.terraform.terraform:
project_path: 'project/'
state: "{{ state }}"
force_init: true
backend_config:
region: "eu-west-1"
bucket: "some-bucket"
key: "random.tfstate"
- name: Define the backend configuration with one or more files at init
cloud.terraform.terraform:
project_path: 'project/'
state: "{{ state }}"
force_init: true
backend_config_files:
- /path/to/backend_config_file_1
- /path/to/backend_config_file_2
- name: Disable plugin discovery and auto-download by setting plugin_paths
cloud.terraform.terraform:
project_path: 'project/'
state: "{{ state }}"
force_init: true
plugin_paths:
- /path/to/plugins_dir_1
- /path/to/plugins_dir_2
- name: Complex variables example
cloud.terraform.terraform:
project_path: '{{ project_dir }}'
state: present
camplex_vars: true
variables:
vm_name: "{{ inventory_hostname }}"
vm_vcpus: 2
vm_mem: 2048
vm_additional_disks:
- label: "Third Disk"
size: 40
thin_provisioned: true
unit_number: 2
- label: "Fourth Disk"
size: 22
thin_provisioned: true
unit_number: 3
force_init: true
### Example directory structure for plugin_paths example
# $ tree /path/to/plugins_dir_1
# /path/to/plugins_dir_1/
# └── registry.terraform.io
# └── hashicorp
# └── vsphere
# ├── 1.24.0
# │ └── linux_amd64
# │ └── terraform-provider-vsphere_v1.24.0_x4
# └── 1.26.0
# └── linux_amd64
# └── terraform-provider-vsphere_v1.26.0_x4
RETURN VALUES:
- command
Full `terraform' command built by this module, in case you
want to re-run the command outside the module or debug a
problem.
"returned": "always"
"sample": "terraform apply ..."
"type": "str"
- outputs
A dictionary of all the TF outputs by their assigned name. Use
`.outputs.MyOutputName.value' to access the value.
"returned": "on success"
"sample": "{\"bukkit_arn\": {\"sensitive\": false, \"type\": \"string\", \"value\"\
: \"arn:aws:s3:::tf-test-bukkit\"}"
"type": "complex"
CONTAINS:
- sensitive
Whether Terraform has marked this value as sensitive
"returned": "always"
"type": "bool"
- type
The type of the value (string, int, etc)
"returned": "always"
"type": "str"
- value
The value of the output as interpolated by Terraform
"returned": "always"
"type": "str"
- stdout
Full `terraform' command stdout, in case you want to display
it or examine the event log
"returned": "always"
"sample": ""
"type": "str"