Open sean-freeman opened 1 year ago
Hi, to fix your issue, you must do:
complex_vars: true
before the variables
blockazs
list as '["str_1", "str_2", "str_3"]'
, you should use: ["str_1", "str_2", "str_3"]
See the below example (based on your provided example) of this fix:
---
- name: "Ansible Playbook"
hosts: localhost
gather_facts: false
vars_prompt:
- name: ansible_var_aws_region
prompt: Please enter AWS Region
private: no
tasks:
- name: Terraform Module for AWS VPC - Terraform init and Terraform apply
register: terraform_result
environment:
AWS_ACCESS_KEY_ID: "{{ ansible_var_aws_access_key }}"
AWS_SECRET_ACCESS_KEY: "{{ ansible_var_aws_secret_access_key }}"
AWS_REGION: "{{ ansible_var_aws_region }}"
cloud.terraform.terraform:
project_path: "{{ playbook_dir }}/tmp/terraform-aws-vpc"
state: present
force_init: true
complex_vars: true # <-- 1. fix
variables:
name: "{{ ansible_var_aws_resources_prefix }}"
....
azs: ["{{ ansible_var_aws_region }}a", "{{ ansible_var_aws_region }}b", "{{ ansible_var_aws_region }}c"] # <-- 2. fix
Design reasoning for requiring complex_vars
given in GH Issue #24
Resolved and closing accordingly
Additional evidence even when using complex_vars: true
and creating malformed variables
If executing an Ansible Task for a Terraform Module that exports a list, the list is malformed when entered into the next Ansible Task for a Terraform Module.
resource "aws_route53_zone" "dns_services_zone" {
name = "rootdomain.tld"
vpc {
vpc_id = "vpc-abcdefgh"
}
}
output "output_dns_nameserver_list" {
value = aws_route53_zone.dns_services_zone.name_servers
}
# Example from integration tests in repo
- name: Set facts for all hosts
ansible.builtin.set_fact:
list_of_strings:
- "kosala"
- 'cli specials"&$%@#*!(){}[]:"" \\'
- "xxx"
- "zzz"
- ansible.builtin.debug:
msg: "{{list_of_strings}}"
# Show output of previous Terraform Module
- ansible.builtin.debug:
msg: "{{terraform_module1_result.outputs.output_dns_nameserver_list.value}}"
# Execute Terraform Module with the output of previous Terraform Module
- name: Terraform Module execution
register: terraform_module2_result
environment:
AWS_ACCESS_KEY_ID: "{{aws_access_key}}"
AWS_SECRET_ACCESS_KEY: "{{aws_secret_access_key}}"
AWS_REGION: "{{aws_region}}"
TF_LOG: "DEBUG"
TF_LOG_PATH: "/tmp/terraform_debug.txt"
cloud.terraform.terraform:
project_path: "{{ playbook_dir }}/tmp/terraform_module_here"
state: present
force_init: true
complex_vars: true
variables:
...
dns_nameserver_list: '{{terraform_module1_result.outputs.output_dns_nameserver_list.value}}'
...
- ansible.builtin.debug:
var: terraform_module2_result
TASK [Set facts for all hosts] *************************
ok: [localhost]
TASK [ansible.builtin.debug] **************************
ok: [localhost] => {
"msg": [
"kosala",
"cli specials\"&$%@#*!(){}[]:\"\" \\\\",
"xxx",
"zzz"
]
}
TASK [ansible.builtin.debug] **************************
ok: [localhost] => {
"msg": [
"ns-0.awsdns-00.com.",
"ns-1024.awsdns-00.org.",
"ns-1536.awsdns-00.co.uk.",
"ns-512.awsdns-00.net."
]
}
TASK [Terraform Module execution 2] **************************
failed: [localhost] =>
{
"changed": false,
"cmd": "/usr/local/bin/terraform apply -no-color -input=false -auto-approve -lock=true /var/folders/f5/xv_7b89d7ss448jmc1crwwl40000gn/T/tmp2m1d8s57.tfplan",
"rc": 1,
"stderr_lines": [
"",
"Error: Invalid index",
"",
" on build_dns_update.tf line 39, in resource \"null_resource\" \"dns_resolv_files\":",
" 39: nameserver ${var.dns_nameserver_list[0]}",
" ├────────────────",
" │ var.dns_nameserver_list is \"[\\\"ns-0.awsdns-00.com.\\\",\\\"ns-1024.awsdns-00.org.\\\",\\\"ns-1536.awsdns-00.co.uk.\\\",\\\"ns-512.awsdns-00.net.\\\"]\"",
"",
"This value does not have any indices."
]
}
2023-01-06T14:53:22.845Z [INFO] CLI args: []string{
"/usr/local/bin/terraform",
"plan",
"-lock=true",
"-input=false",
"-no-color",
"-detailed-exitcode",
"-out",
"/var/folders/f5/xv_7b89d7ss448jmc1crwwl40000gn/T/tmp2m1d8s57.tfplan",
....
"-var",
"dns_nameserver_list=[\"ns-0.awsdns-00.com.\",\"ns-1024.awsdns-00.org.\",\"ns-1536.awsdns-00.co.uk.\",\"ns-512.awsdns-00.net.\"]",
....
}
Examples from Hashicorp always show Terraform Input Variables which are list
or object
types, using enclosing '
.
terraform apply -var='image_id_list=["ami-abc123","ami-def456"]' -var="instance_type=t2.micro"
terraform apply -var='image_id_map={"us-east-1":"ami-abc123","us-east-2":"ami-def456"}'
export TF_VAR_availability_zone_names='["us-west-1b","us-west-1d"]'
terraform apply
Source: https://developer.hashicorp.com/terraform/language/values/variables#variables-on-the-command-line https://developer.hashicorp.com/terraform/language/values/variables#complex-typed-values
To preserve Terraform Input Variable formatting, to create a *.tfvars and use operator -var-file=
.
Given that a .tfplan is always generated using this Terraform Template execution Ansible Module, use of temporary .tfvars should at least be offered as an operator for the Ansible Module in addition to complex_vars: true
? For example, use_temporary_tfvars: true
?
Hi, I have gone through your example code and tested it on my system. I've tried to reproduce your error using older versions of python (3.7) and different versions of this collection (1.0.0, 1.0.1), but the error isn't reproducible. I've also noticed that your playbook example above doesn't include a task named Terraform Module execution 2
as shown in your error output. There is also no example code for Terraform Module 2
. If you want us to reproduce this error, please provide a minimal reproducible example.
SUMMARY
Variable insertions are malformed when excuted with inline Terraform Variables.
Variable insertion into AWS Availability Zones does not work, due to Ansible Module for Terraform performing incorrect parsing.....
azs: '["{{ ansible_var_aws_region }}a", "{{ ansible_var_aws_region }}b", "{{ ansible_var_aws_region }}c"]'
results in
-var 'azs=['\"'\"'us-west-2a'\"'\"', '\"'\"'us-west-2b'\"'\"', '\"'\"'us-west-2c'\"'\"']'
instead of
-var 'azs=[\"us-west-2a\", \"us-west-2b\", \"us-west-2c\"]'
NOTE: related comment in Issue 24 copied below
ISSUE TYPE
ANSIBLE VERSION
COLLECTION VERSION
OS / ENVIRONMENT
STEPS TO REPRODUCE
EXPECTED RESULTS
ACTUAL RESULTS