はじめに
Ansible の cloud.terraform.terraform
モジュールは、Ansible から Terraform を呼べるモジュールです。
モジュールで指定するオプションに応じて、さまざま terraform
コマンドが実行されます。
で、「このときは実際にどういうコマンドが実行されるんだろう?」と気になることがあります。
調べてみると、Ansible 本体の AnsibleModule
クラスの run_command
メソッド経由でコマンドが実行されることがわかりました。
このメソッドの中ではログを出力する処理があるので、このログを見ればどんなコマンドが実行されるかが確認できることになります。
ということで、試してみました。
- 環境
- ansible-core 2.16.6
- cloud.terraform コレクション 3.0.0
- 挙動説明、コードへのリンクも 3.0.0
- macOS 13.6.7
- Ansible と Terraform は同一マシンに入れて
hosts: localhost
で実行
基本的なお作法
run_command
メソッド内で実行されるコマンドをデバッグするは、設定項目 DEFAULT_DEBUG
でデバッグを有効にします(デフォルト無効)。環境変数で設定する場合は ANSIBLE_DEBUG
です。
このデバッグを有効にすると、Playbook 実行時にデバッグ情報が no_log: true
にしたもの含めて大量に表示されるので注意してください。
(このデバッグほどしなくてもいい方法があれば教えてください)
デフォルトでは、ファシリティ INFO として出力されます。ファシリティを変更する場合は、設置項目 DEFAULT_SYSLOG_FACILITY
で変更します。
今回は macOS を使うので、log
コマンドで確認します。process はざっくり Python
にしておきます。
(確認方法は各環境に合わせてください)
log
コマンドは、こちらのページを参考にさせていただきました。ありがとうございます!
ログ出力の待機
% log stream --info --predicate 'process == "Python"' Filtering the log data using "process == "Python"" (出力待ち)
Playbook 実行:
ANSIBLE_DEBUG=True ansible-playbook -i localhost, ansible_terraform.yml
すると以下のようにログが表示されます。
% log stream --info --predicate 'process == "Python"' Filtering the log data using "process == "Python"" Timestamp Thread Type Activity PID TTL 2024-06-09 14:38:02.930838+0900 0xdbbd6 Info 0x0 18358 0 Python: (syslog.cpython-311-darwin.so) Invoked with project_path=./ state=present force_init=True workspace=default purge_workspace=False complex_vars=False targets=[] lock=True init_reconfigure=False overwrite_init=True check_destroy=False provider_upgrade=False binary_path=None plugin_paths=None variables=None variables_files=None plan_file=None state_file=None lock_timeout=None backend_config=None backend_config_files=None parallelism=None 2024-06-09 14:38:02.932716+0900 0xdbbd6 Info 0x0 18358 0 Python: (syslog.cpython-311-darwin.so) Executing: /usr/local/bin/terraform version -json 2024-06-09 14:38:06.268688+0900 0xdbbd6 Info 0x0 18358 0 Python: (syslog.cpython-311-darwin.so) Executing: /usr/local/bin/terraform init -input=false -no-color 2024-06-09 14:38:11.463882+0900 0xdbbd6 Info 0x0 18358 0 Python: (syslog.cpython-311-darwin.so) Executing: /usr/local/bin/terraform providers schema -json 2024-06-09 14:38:15.128367+0900 0xdbbd6 Info 0x0 18358 0 Python: (syslog.cpython-311-darwin.so) Executing: /usr/local/bin/terraform show -json
Executing:
のあとに各種 terraform
コマンドが確認できます。
おためし
いつくかのパターンで試してみます。
見やすさのため、以下からはログのうち Executing: /usr/local/bin/terraform
の terraform
以降の文字列のみを乗せます。
また、途中でコードの解説を含みますが、ざっと読んだ程度ですので、詳細、正確なところはコードをあたってください。
パターン1: リソースがない状態から作成
ほしいリソースがまだない状態から、terraform init
含めてリソースを作成するパターンです。
Playbook は以下のとおり。
- name: Call Terraform cloud.terraform.terraform: project_path: ./ state: present force_init: true
表示された terraform
コマンドは以下のとおりです。結構いろいろ表示されますね。
terraform version -json terraform init -input=false -no-color terraform providers schema -json -no-color terraform show -json terraform workspace list -no-color terraform plan -lock=true -input=false -no-color -detailed-exitcode -out /var/folders/2s/h6djr0fn3773tj1zy4mg442c0000gn/T/tmphxtb7o8u.tfplan terraform validate terraform show -json /var/folders/2s/h6djr0fn3773tj1zy4mg442c0000gn/T/tmphxtb7o8u.tfplan terraform apply -no-color -input=false -auto-approve -lock=true /var/folders/2s/h6djr0fn3773tj1zy4mg442c0000gn/T/tmphxtb7o8u.tfplan terraform show -json terraform output -no-color -json
最初に terraform version
を実行しています。これはあとで、バージョンによってオプションを切り替えるために取得しているようです。見つけた範囲ですと、apply
時に自動で yes
して進めるオプションを -auto-approve
にするか -auto-approve=true
にするか、の判断に使われていました。
force_init: true
を指定していて overwrite_init
もデフォルトの true
のままなので、init
が実行されています(参考)。他のコマンド含め、-input=false
が指定されているので、変数の値を入力するプロンプトは表示されず、未割り当ての変数があっても処理を続行します。Ansible から見ると terraform
コマンド実行後の対話処理はないほうがいいのでこうなっているのだと思います。
いきなり terraform apply
するのではなく terraform plan
で .tfplan
ファイルを作成してから terraform apply
しているのが特徴でしょうか。plan_file
の指定がない場合は、一時ファイルとして作成されます。
validate
が実行されるのは意外でした。project_path
や bin_path
の妥当性をチェックする流れで validate
もするようです。
3回 terraform show
を実行しているのは、事前事後で diff を取得するためのようです。 それぞれの概要は以下のとおりです。
- 1回目は、事前状態の取得
- 2回目は、事前に
terraform plan -out
して生成した.tfplan
ファイルからの状態の取得- 通常(チェックモードでない)は、ここの情報はその後とくに利用されないように見える
- 3回目は、事後(
apply
後)状態の取得- 後述のチェックモードの場合は、2回目の結果が事後結果として扱われる
terraform apply
にある -detailed-exitcode
オプションは、終了コードによって、変更有無を判断するためのオプションです。
パターン2: リソース作成済みから再実行
最後は、リソースがある状態から再度同じ Playbook を実行するパターンです。タスクのステータス的には OK
です。
表示された terraform
コマンドは以下のとおりです。
terraform version -json terraform init -input=false -no-color terraform providers schema -json terraform show -json terraform workspace list -no-color terraform plan -lock=true -input=false -no-color -detailed-exitcode -out /var/folders/2s/h6djr0fn3773tj1zy4smg442c0000gn/T/tmpscohbatx.tfplan terraform validate terraform show -json /var/folders/2s/h6djr0fn3773tj1zy4mg442c0000gn/T/tmpscohbatx.tfplan terraform show -json terraform output -no-color -json
terraform apply
コマンドがないですね。
コード的には terraform apply
を担当するメソッドは呼ばれますが、terraform plan
時に変更が検出されなかったため、terraform apply
不要(needs_application
が false
)という扱いで処理されているようです。
パターン3: チェックモード
ドキュメントに terraform plan
したいときは Playbook をチェックモードで実行してね、と記載があります。
リソースがまだない状態から試してみます。
terraform version -json terraform init -input=false -no-color terraform providers schema -json terraform show -json terraform workspace list -no-color terraform plan -lock=true -input=false -no-color -detailed-exitcode -out /var/folders/2s/h6djr0fn3773tj1zy4mg442c0000gn/T/tmpr0m76lku.tfplan terraform validate terraform show -json /var/folders/2s/h6djr0fn3773tj1zy4mg442c0000gn/T/tmpr0m76lku.tfplan terraform output -no-color -json
やはり terraform apply
がないですね。
3回目の terraform show
(事後状態) がないのも特徴です。チェックモードだと実行されないようになっています。
パターン4: リソースの削除
最後は、リソースがある状態からリソースを削除するパターンです。
Playbook は以下のとおりです。
- name: Call Terraform cloud.terraform.terraform: project_path: ./ state: absent # destroy 相当
表示された terraform
コマンドは以下のとおりです。
terraform version -json terraform init -input=false -no-color terraform providers schema -json terraform show -json terraform workspace list -no-color terraform plan -lock=true -input=false -no-color -detailed-exitcode -out /var/folders/2s/h6djr0fn3773tj1zy4mg442c0000gn/T/tmpu74d8r3v.tfplan -destroy terraform validate terraform show -json /var/folders/2s/h6djr0fn3773tj1zy4mg442c0000gn/T/tmpu74d8r3v.tfplan terraform apply -no-color -input=false -auto-approve -lock=true /var/folders/2s/h6djr0fn3773tj1zy4mg442c0000gn/T/tmpu74d8r3v.tfplan terraform show -json terraform output -no-color -json
直接 terraform destroy
するのではなく、terraform plan
時に -destroy
オプションを付けてできた .tfplan
ファイルを terraform apply
しています。
Ansible としては、変更の有無を検出しながら段階をおって処理するための工夫なのかなと思います。
おわりに
実際にどんなコマンドが実行されているかわかるとスッキリしますね。
今回はとてもシンプルなPlaybookで試しましたが、例えば、variables
を指定したり workspace
を指定があるときは色々変化があって、確認するとおもしろいかもしれません。