てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible/Terraform] cloud.terraform.terraform モジュールの init 関連オプションの関係

はじめに

cloud.terraform.terraform モジュールは、Ansible から Terraform を実行できるモジュールです。

Terraform には initplanapplydestroy といったサブコマンドがあります。当初「モジュール のstate オプションで initplanapplydestroy が指定できるかな」なんて安易な想像していましたが、そうはなっていません。

とくに init については、それらしいオプションが複数あって、初見ではわかりませんでした。

自分なりに調べたので、それぞれの関係についてまとめます。

  • 環境
    • cloud.terraform コレクション 3.0.0
    • ansible-core 2.16.6
    • terraform 1.8.2

init 関連のオプション 3つの関係

init に関するオプションは以下の 3つがあります。

オプション名 概要 デフォルト
force_init init を強制する false
overwrite_init project_path で指定したディレクトリ配下の .terraform/terraform.tfstate が存在していても init する true
init_reconfigure init 時に バックエンドの reconfigure する false

実際に init されるかどうかは、以下のように決まります。(関連コード

  1. まず評価されるのは force_init (デフォルト false)。true の場合は次へ
    • 逆に force_initfalse の場合は、overwrite_initinit_reconfigure オプションの指定は意味がない
  2. overwrite_inittrue」または「project_path で指定したディレクトリ配下の .terraform/terraform.tfstate がない場合」 は init する

そして、init_reconfiguretrue であれば、terraform init コマンドに -reconfigure オプションが付くようです。

init してない状態で force_init: false (デフォルト) するとエラー

terraform init してない状態から、force_init: false (デフォルト)の Playbook を実行するとエラーになります。

Playbook

---
- name: Terraform test
  hosts: localhost
  gather_facts: false
  connection: local

    - name: Call Terraform
      cloud.terraform.terraform:
        project_path: ./
        state: present

実行

TASK [Call Terraform] ***************************************************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: 
fatal: [localhost]: FAILED! => {"changed": false, "module_stderr": "Traceback (most recent call last):\n  File \"/Users/sakana/.ansible/tmp/ansible-tmp-1717077948.8694599-21156-268676552788140/AnsiballZ_terraform.py\", line 107, in <module>\n    _ansiballz_main()\n  File \"/Users/sakana/.ansible/tmp/ansible-tmp-1717077948.8694599-21156-268676552788140/AnsiballZ_terraform.py\", line 99, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/Users/sakana/.ansible/tmp/ansible-tmp-1717077948.8694599-21156-268676552788140/AnsiballZ_terraform.py\", line 47, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.cloud.terraform.plugins.modules.terraform', init_globals=dict(_module_fqn='ansible_collections.cloud.terraform.plugins.modules.terraform', _modlib_path=modlib_path),\n  File \"<frozen runpy>\", line 226, in run_module\n  File \"<frozen runpy>\", line 98, in _run_module_code\n  File \"<frozen runpy>\", line 88, in _run_code\n  File \"/var/folders/2s/h6djr0fn3773tj1zy4mg442c0000gn/T/ansible_cloud.terraform.terraform_payload_wkmoj22q/ansible_cloud.terraform.terraform_payload.zip/ansible_collections/cloud/terraform/plugins/modules/terraform.py\", line 660, in <module>\n  File \"/var/folders/2s/h6djr0fn3773tj1zy4mg442c0000gn/T/ansible_cloud.terraform.terraform_payload_wkmoj22q/ansible_cloud.terraform.terraform_payload.zip/ansible_collections/cloud/terraform/plugins/modules/terraform.py\", line 513, in main\n  File \"/var/folders/2s/h6djr0fn3773tj1zy4mg442c0000gn/T/ansible_cloud.terraform.terraform_payload_wkmoj22q/ansible_cloud.terraform.terraform_payload.zip/ansible_collections/cloud/terraform/plugins/module_utils/terraform_commands.py\", line 169, in providers_schema\nansible_collections.cloud.terraform.plugins.module_utils.errors.TerraformWarning: Could not get provider schemas. \nstdout: \nstderr: \u001b[31m\u001b[31m╷\u001b[0m\u001b[0m\n\u001b[31m│\u001b[0m \u001b[0m\u001b[1m\u001b[31mError: \u001b[0m\u001b[0m\u001b[1mInconsistent dependency lock file\u001b[0m\n\u001b[31m│\u001b[0m \u001b[0m\n\u001b[31m│\u001b[0m \u001b[0m\u001b[0mThe following dependency selections recorded in the lock file are\n\u001b[31m│\u001b[0m \u001b[0minconsistent with the current configuration:\n\u001b[31m│\u001b[0m \u001b[0m  - provider registry.terraform.io/hashicorp/azurerm: required by this configuration but no version is selected\n\u001b[31m│\u001b[0m \u001b[0m\n\u001b[31m│\u001b[0m \u001b[0mTo make the initial dependency selections that will initialize the\n\u001b[31m│\u001b[0m \u001b[0mdependency lock file, run:\n\u001b[31m│\u001b[0m \u001b[0m  terraform init\n\u001b[31m╵\u001b[0m\u001b[0m\n\u001b[0m\u001b[0m\n\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}

読みにくいですが、いきなり plan しようとしたときのようなエラーになってます。実際はモジュール内で terraform providers schema -json を実行したときにエラーが発生するようです。

整形すると以下のようなエラーです。

Could not get provider schemas.
...(略)...
Error: Inconsistent dependency lock file
...(略)...
To make the initial dependency selections that will initialize the
dependency lock file, run:
  terraform init

おわりに

force_initoverwrite_init の関係がとくに分からなかったのですが、落ち着いて見ると難しい話ではありませんでした。