Repository: ansible/ansible
Pull request: Add variables and variable_file in terraform module
##### SUMMARY
<!--- Describe the change, including rationale and design decisions -->
Fixes #36837
Added variables and variable_file options for validate command.

<!---
If you are fixing an existing issue, please include "Fixes #nnn" in your
commit message and your description; but you should still explain what
the change does.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bugfix Pull Request


##### COMPONENT NAME
<!--- Name of the module, plugin, module or task -->
terraform

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.6.0
  config file = None
  configured module search path = [u'/home/mnaletov/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/mnaletov/.local/share/virtualenvs/ansible-UKLfXmN5/local/lib/python2.7/site-packages/ansible
  executable location = /home/mnaletov/.local/share/virtualenvs/ansible-UKLfXmN5/bin/ansible
  python version = 2.7.12 (default, Dec  4 2017, 14:50:18) [GCC 5.4.0 20160609]
```


##### ADDITIONAL INFORMATION
<!---
Include additional information to help people understand the change here.
For bugs that don't have a linked bug report, a step-by-step reproduction
of the problem is helpful.
  -->

<!--- Paste verbatim command output below, e.g. before and after your change -->

Problem statement:
Terraform module doesn't use variables dictionary
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
- terraform

##### ANSIBLE VERSION
```
ansible 2.5.0b1
```

##### CONFIGURATION
Just main.yml

##### OS / ENVIRONMENT
WSL, Ubuntu 16.04.3 LTS

##### SUMMARY
I want to try terraform module from ansible 2.5 beta version. Terraform module always validates terraform files before starts applying, but it doesn't include variables specified in terraform module `variables` section. 

##### STEPS TO REPRODUCE
- Terraform variable file:
```variables.tf:
variable "cluster_tag" {
  description = "Tag of Cluster"
}

variable "aws_access_key" {}

variable "aws_secret_key" {}

variable "aws_region" {
  description = "Region for AWS"
}
```
- ansible-playbook -c local main.yml

<!--- Paste example playbooks or commands between quotes below -->
```- hosts: localhost
  tasks:
  - name: Provide infrastructure
    terraform:
      variables:
        aws_access_key: <access_key>
        aws_secret_key: <secret_keky>
        aws_region: eu-west-1
        cluster_tag: ansible-test
      project_path: ./terraform
```

##### EXPECTED RESULTS
Terraform considers specified variables, validate and will run specified actions, if terraform file validate successful.

##### ACTUAL RESULTS
```
ansible-playbook -c local main.yml
 [WARNING]: Unable to parse /etc/ansible/hosts as an inventory source

 [WARNING]: No inventory was parsed, only implicit localhost is available

 [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'


PLAY [localhost] **********************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************
ok: [localhost]

TASK [Provide infrastructure] ********************************************************************************************************************************$
fatal: [localhost]: FAILED! => {
    "changed": false,
    "failed": true
}

MSG:
Failed to validate Terraform configuration files:

Error: Required variable not set: aws_region
Error: Required variable not set: aws_access_key
Error: Required variable not set: aws_secret_key
Error: Required variable not set: cluster_tag
```

Hints from issue discussion:
Files identified in the description:
* [lib/ansible/modules/cloud/misc/terraform.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/misc/terraform.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @ryansb
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Commit message: Fixes #36837

Added terraform variables for validate command

Patch to review:
diff --git a/lib/ansible/modules/cloud/misc/terraform.py b/lib/ansible/modules/cloud/misc/terraform.py
index cfc26dfd18d761..3ccfac6cb5698d 100644
--- a/lib/ansible/modules/cloud/misc/terraform.py
+++ b/lib/ansible/modules/cloud/misc/terraform.py
@@ -136,13 +136,13 @@
 module = None
 
 
-def preflight_validation(bin_path, project_path, variables_file=None, plan_file=None):
+def preflight_validation(bin_path, project_path, variables_args=None, plan_file=None):
     if not os.path.exists(bin_path):
         module.fail_json(msg="Path for Terraform binary '{0}' doesn't exist on this host - check the path and try again please.".format(project_path))
     if not os.path.isdir(project_path):
         module.fail_json(msg="Path for Terraform project '{0}' doesn't exist on this host - check the path and try again please.".format(project_path))
 
-    rc, out, err = module.run_command([bin_path, 'validate'], cwd=project_path)
+    rc, out, err = module.run_command([bin_path, 'validate'] + variables_args, cwd=project_path)
     if rc != 0:
         module.fail_json(msg="Failed to validate Terraform configuration files:\r\n{0}".format(err))
 
@@ -209,7 +209,16 @@ def main():
     else:
         command = [module.get_bin_path('terraform')]
 
-    preflight_validation(command[0], project_path)
+    variables_args = []
+    for k, v in variables.items():
+        variables_args.extend([
+            '-var',
+            '{0}={1}'.format(k, v)
+        ])
+    if variables_file:
+        variables_args.append('-var-file', variables_file)
+
+    preflight_validation(command[0], project_path, variables_args)
 
     if state == 'present':
         command.extend(APPLY_ARGS)
@@ -224,15 +233,6 @@ def main():
     if module.params.get('lock_timeout') is not None:
         command.append('-lock-timeout=%ds' % module.params.get('lock_timeout'))
 
-    variables_args = []
-    for k, v in variables.items():
-        variables_args.extend([
-            '-var',
-            '{0}={1}'.format(k, v)
-        ])
-    if variables_file:
-        variables_args.append('-var-file', variables_file)
-
     for t in (module.params.get('targets') or []):
         command.extend(['-target', t])
 


Code review comments:
diff_hunk: @@ -209,7 +209,16 @@ def main():
     else:
         command = [module.get_bin_path('terraform')]
 
-    preflight_validation(command[0], project_path)
+    variables_args = []
+    for k, v in variables.items():
+        variables_args.extend([
+            '-var',
+            '{0}={1}'.format(k, v)
+        ])
+    if variables_file:
+        variables_args.append('-var-file', variables_file)
path: lib/ansible/modules/cloud/misc/terraform.py
text: @user1:
This likely needs to be:

```
variables_args.extend(['-var-file', variables_file])
```