Repository: ansible/ansible

Issue:
Missing force_init function in module
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and devel branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
 - Bug Report

##### COMPONENT NAME
<!---
Name of the module, plugin, task or feature
Do not include extra details here, e.g. "vyos_command" not "the network module vyos_command" or the full path
-->

- terraform

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
(ansible) ubuntu@ip-172-31-45-246:~$ ansible --version
ansible 2.6.0
  config file = /home/ubuntu/kubernetes/ansible.cfg
  configured module search path = [u'/home/ubuntu/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/ubuntu/ansible/local/lib/python2.7/site-packages/ansible
  executable location = /home/ubuntu/ansible/bin/ansible
  python version = 2.7.12 (default, Dec  4 2017, 14:50:18) [GCC 5.4.0 20160609]
```

##### CONFIGURATION
<!---
If using Ansible 2.4 or above, paste the results of "ansible-config dump --only-changed"
Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->
Nothing.

##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
```
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.2 LTS
Release:        16.04
Codename:       xenial
```

##### SUMMARY
<!--- Explain the problem briefly -->
We need to run `terraform init` to download providers for Terraform.
In documentation we have `force_init` parameter which is missing in terraform.py module

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->
* ansible-playbook -c local main.yml

<!--- Paste example playbooks or commands between quotes below -->
```yaml
  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
      force_init: true
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
Ansible runs `terraform init`, all providers have been downloaded successful, terraform files are running.

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
```
TASK [Provide infrastructure] *********************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Unsupported parameters for (terraform) module: force_init Supported parameters include: binary_path, lock, lock_timeout, plan_file, project_path, state, state_file, targets, variables, variables_file"}
```




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 --->

Resolving patch:
diff --git a/lib/ansible/modules/cloud/misc/terraform.py b/lib/ansible/modules/cloud/misc/terraform.py
--- a/lib/ansible/modules/cloud/misc/terraform.py
+++ b/lib/ansible/modules/cloud/misc/terraform.py
@@ -79,8 +79,9 @@
       - To avoid duplicating infra, if a state file can't be found this will
         force a `terraform init`. Generally, this should be turned off unless
         you intend to provision an entirely new Terraform deployment.
-    required: false
     default: false
+    required: false
+    type: bool
 notes:
    - To just run a `terraform plan`, use check mode.
 requirements: [ "terraform" ]
@@ -155,6 +156,13 @@ def _state_args(state_file):
     return []
 
 
+def init_plugins(bin_path, project_path):
+    command = [bin_path, 'init']
+    rc, out, err = module.run_command(command, cwd=project_path)
+    if rc != 0:
+        module.fail_json(msg="Failed to initialize Terraform modules:\r\n{0}".format(err))
+
+
 def build_plan(bin_path, project_path, variables_args, state_file, plan_path=None):
     if plan_path is None:
         f, plan_path = tempfile.mkstemp(suffix='.tfplan')
@@ -191,6 +199,7 @@ def main():
             targets=dict(type='list', default=[]),
             lock=dict(type='bool', default=True),
             lock_timeout=dict(type='int',),
+            force_init=dict(type='bool', default=False)
         ),
         required_if=[('state', 'planned', ['plan_file'])],
         supports_check_mode=True,
@@ -203,12 +212,16 @@ def main():
     variables_file = module.params.get('variables_file')
     plan_file = module.params.get('plan_file')
     state_file = module.params.get('state_file')
+    force_init = module.params.get('force_init')
 
     if bin_path is not None:
         command = [bin_path]
     else:
         command = [module.get_bin_path('terraform')]
 
+    if force_init:
+        init_plugins(command[0], project_path)
+
     variables_args = []
     for k, v in variables.items():
         variables_args.extend([


Test patch:
diff --git a/test/sanity/validate-modules/ignore.txt b/test/sanity/validate-modules/ignore.txt
--- a/test/sanity/validate-modules/ignore.txt
+++ b/test/sanity/validate-modules/ignore.txt
@@ -573,7 +573,6 @@ lib/ansible/modules/cloud/misc/rhevm.py E324
 lib/ansible/modules/cloud/misc/rhevm.py E325
 lib/ansible/modules/cloud/misc/serverless.py E324
 lib/ansible/modules/cloud/misc/serverless.py E325
-lib/ansible/modules/cloud/misc/terraform.py E323
 lib/ansible/modules/cloud/misc/terraform.py E324
 lib/ansible/modules/cloud/misc/terraform.py E325
 lib/ansible/modules/cloud/misc/virt.py E322