はじめに
AnsibleでTerraformモジュールを使った際に、気を付けるポイントを書き留めておきます。
以下にはまりました。
- Terraformのoutputの変数名にハイフンを使用していたため、Ansibleで呼び出せずエラーになった。
- 原因はTerraformでは変数名にハイフンを使えるが、Ansibleでは使えないため。
- terraformモジュール実行後、次のタスクが失敗することがあった。
解決策
以下で解決しました。
- outputの変数名をハイフンからアンダースコアに修正しました。
- Terraform全体では、ハイフンとアンダースコアが混ざっている状態なのでちょっともやもや。
- OSSを連携させるときに、こういった仕様も確認しなくては。
- shellモジュールを用いて、起動するまで待つステータスチェックのAWSコマンドを使用しました。
- awsモジュールで実現したかったけど、見つけられませんでした。
環境
terraformで構築するインスタンス
outputの変数名はアンダースコアに修正済みです。
インスタンスIDはAWSコマンドの引数として使用するため、outputで出力しています。
provider "aws" { region = "ap-northeast-1" access_key = "XXXXX" secret_key = "XXXXX" } resource "aws_instance" "mito-ec2" { ami = "ami-03f4fa076d2981b45" instance_type = "t2.micro" associate_public_ip_address = "true" vpc_security_group_ids = ["XXXXX"] key_name = "XXXXX" tags = { Name = "mito-ec2" } } output "ec2_id"{ value = aws_instance.mito-ec2.id }
実行するPlaybook
インスタンスの起動完了待ちは、aws ec2 wait instance-status-ok
コマンドを使用します。
引数に、outputで出力したインスタンスIDを指定します。
--- - hosts: localhost gather_facts: no tasks: - name: terraform apply community.general.terraform: project_path: 'terraform/' force_init: yes state: present register: result - name: wait instance_status_ok shell: cmd: "aws ec2 wait instance-status-ok --instance-ids {{ result.outputs.ec2_id.value }}" - name: get instance_status shell: cmd: "aws ec2 describe-instance-status --instance-ids {{ result.outputs.ec2_id.value }}" register: result_instance_status - name: debug debug: msg: "{{ result_instance_status.stdout_lines }}"
実行ログ
Playbookを実行します。
aws ec2 describe-instance-status
の実行結果で、起動完了が確認できます。
$ ansible-playbook terraform_module.yml [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' PLAY [localhost] ************************************************************** TASK [terraform apply] ******************************************************** changed: [localhost] TASK [wait instance_status_ok] ************************************************ changed: [localhost] TASK [get instance_status] **************************************************** changed: [localhost] TASK [debug] ***************************************************************** ok: [localhost] => { "msg": [ "{", " "InstanceStatuses": [", " {", " "AvailabilityZone": "ap-northeast-1c",", " "InstanceId": "i-0080415c81f9dd541",", " "InstanceState": {", " "Code": 16,", " "Name": "running"", " },", " "InstanceStatus": {", " "Details": [", " {", " "Name": "reachability",", " "Status": "passed"", " }", " ],", " "Status": "ok"", " },", " "SystemStatus": {", " "Details": [", " {", " "Name": "reachability",", " "Status": "passed"", " }", " ],", " "Status": "ok"", " }", " }", " ]", "}" ] } PLAY RECAP ******************************************************************* localhost: ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 $
エラーメッセージ
outputの変数にハイフンを使った場合のエラーで、ec2-id
としています。
リソースは作成されますが、waitで失敗します。
$ ansible-playbook terraform_module.yml [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' PLAY [localhost] *************************************************************** TASK [terraform apply] ********************************************************* changed: [localhost] TASK [wait instance_status_ok] ************************************************* fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'ec2'\n\nThe error appears to be in '/home/ubuntu/test/terraform_module.yml': line 13, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: wait instance_status_ok\n ^ here\n"} PLAY RECAP ********************************************************************* localhost: ok=1 changed=1 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0 $