We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Serverless Module - Support Verbose Mode
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Feature Idea

##### COMPONENT NAME
<!--- Name of the module/plugin/task/feature -->
<!--- Please do not include extra details here, e.g. "vyos_command" not "the network module vyos_command" -->
- serverless.py

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.4.0.0
```

##### 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).
-->
```
DEFAULT_HOST_LIST(env: ANSIBLE_INVENTORY) = [u'/.../inventory/dev']
```

##### 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.
-->
- N/A

##### SUMMARY
<!--- Explain the problem briefly -->

When using Ansible to deploy Serverless projects it would be very helpful to be able to turn on verbose mode (`-v`)

**Reference:** https://serverless.com/framework/docs/providers/aws/cli-reference/deploy/

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

<!--- Paste example playbooks or commands between quotes below -->
Add `verbose="true"` to `serverless` command and/or piggyback on Ansible verbose mode
```yaml
- name: configure | Run Serverless
  serverless: stage="{{ env }}" region="{{ ec2_region }}" service_path="{{ serverless_service_path }}" verbose="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? -->
You would see Serverless verbose logging in the Ansible log
```
Serverless: Packaging service...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
CloudFormation - CREATE_IN_PROGRESS - AWS::CloudFormation::Stack - ***
CloudFormation - CREATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket
(removed additional printout)
Serverless: Operation failed!
```
##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```
Serverless: Packaging service...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
....
Serverless: Operation failed!
```
**Note:** The `....` seen above is Serverless not listing all AWS commands because it's not in verbose mode

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lib/ansible/modules/cloud/misc/serverless.py`
Content:
```
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 
4 # (c) 2016, Ryan Scott Brown <ryansb@redhat.com>
5 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
6 
7 from __future__ import absolute_import, division, print_function
8 __metaclass__ = type
9 
10 
11 ANSIBLE_METADATA = {'metadata_version': '1.1',
12                     'status': ['preview'],
13                     'supported_by': 'community'}
14 
15 
16 DOCUMENTATION = '''
17 ---
18 module: serverless
19 short_description: Manages a Serverless Framework project
20 description:
21      - Provides support for managing Serverless Framework (https://serverless.com/) project deployments and stacks.
22 version_added: "2.3"
23 options:
24   state:
25     choices: ['present', 'absent']
26     description:
27       - Goal state of given stage/project
28     required: false
29     default: present
30   serverless_bin_path:
31     description:
32       - The path of a serverless framework binary relative to the 'service_path' eg. node_module/.bin/serverless
33     required: false
34     version_added: "2.4"
35   service_path:
36     description:
37       - The path to the root of the Serverless Service to be operated on.
38     required: true
39   stage:
40     description:
41       - The name of the serverless framework project stage to deploy to. This uses the serverless framework default "dev".
42     required: false
43   functions:
44     description:
45       - A list of specific functions to deploy. If this is not provided, all functions in the service will be deployed.
46     required: false
47     default: []
48   region:
49     description:
50       - AWS region to deploy the service to
51     required: false
52     default: us-east-1
53   deploy:
54     description:
55       - Whether or not to deploy artifacts after building them. When this option is `false` all the functions will be built, but no stack update will be
56         run to send them out. This is mostly useful for generating artifacts to be stored/deployed elsewhere.
57     required: false
58     default: true
59 notes:
60    - Currently, the `serverless` command must be in the path of the node executing the task. In the future this may be a flag.
61 requirements: [ "serverless", "yaml" ]
62 author: "Ryan Scott Brown @ryansb"
63 '''
64 
65 EXAMPLES = """
66 # Basic deploy of a service
67 - serverless:
68     service_path: '{{ project_dir }}'
69     state: present
70 
71 # Deploy specific functions
72 - serverless:
73     service_path: '{{ project_dir }}'
74     functions:
75       - my_func_one
76       - my_func_two
77 
78 # deploy a project, then pull its resource list back into Ansible
79 - serverless:
80     stage: dev
81     region: us-east-1
82     service_path: '{{ project_dir }}'
83   register: sls
84 # The cloudformation stack is always named the same as the full service, so the
85 # cloudformation_facts module can get a full list of the stack resources, as
86 # well as stack events and outputs
87 - cloudformation_facts:
88     region: us-east-1
89     stack_name: '{{ sls.service_name }}'
90     stack_resources: true
91 
92 # Deploy a project but use a locally installed serverless binary instead of the global serverless binary
93 - serverless:
94     stage: dev
95     region: us-east-1
96     service_path: '{{ project_dir }}'
97     serverless_bin_path: node_modules/.bin/serverless
98 """
99 
100 RETURN = """
101 service_name:
102   type: string
103   description: The service name specified in the serverless.yml that was just deployed.
104   returned: always
105   sample: my-fancy-service-dev
106 state:
107   type: string
108   description: Whether the stack for the serverless project is present/absent.
109   returned: always
110 command:
111   type: string
112   description: Full `serverless` command run by this module, in case you want to re-run the command outside the module.
113   returned: always
114   sample: serverless deploy --stage production
115 """
116 
117 import os
118 import traceback
119 
120 try:
121     import yaml
122     HAS_YAML = True
123 except ImportError:
124     HAS_YAML = False
125 
126 from ansible.module_utils.basic import AnsibleModule
127 
128 
129 def read_serverless_config(module):
130     path = module.params.get('service_path')
131 
132     try:
133         with open(os.path.join(path, 'serverless.yml')) as sls_config:
134             config = yaml.safe_load(sls_config.read())
135             return config
136     except IOError as e:
137         module.fail_json(msg="Could not open serverless.yml in {}. err: {}".format(path, str(e)), exception=traceback.format_exc())
138 
139     module.fail_json(msg="Failed to open serverless config at {}".format(
140         os.path.join(path, 'serverless.yml')))
141 
142 
143 def get_service_name(module, stage):
144     config = read_serverless_config(module)
145     if config.get('service') is None:
146         module.fail_json(msg="Could not read `service` key from serverless.yml file")
147 
148     if stage:
149         return "{}-{}".format(config['service'], stage)
150 
151     return "{}-{}".format(config['service'], config.get('stage', 'dev'))
152 
153 
154 def main():
155     module = AnsibleModule(
156         argument_spec=dict(
157             service_path=dict(required=True, type='path'),
158             state=dict(default='present', choices=['present', 'absent'], required=False),
159             functions=dict(type='list', required=False),
160             region=dict(default='', required=False),
161             stage=dict(default='', required=False),
162             deploy=dict(default=True, type='bool', required=False),
163             serverless_bin_path=dict(required=False, type='path')
164         ),
165     )
166 
167     if not HAS_YAML:
168         module.fail_json(msg='yaml is required for this module')
169 
170     service_path = module.params.get('service_path')
171     state = module.params.get('state')
172     functions = module.params.get('functions')
173     region = module.params.get('region')
174     stage = module.params.get('stage')
175     deploy = module.params.get('deploy', True)
176     serverless_bin_path = module.params.get('serverless_bin_path')
177 
178     if serverless_bin_path is not None:
179         command = serverless_bin_path + " "
180     else:
181         command = "serverless "
182 
183     if state == 'present':
184         command += 'deploy '
185     elif state == 'absent':
186         command += 'remove '
187     else:
188         module.fail_json(msg="State must either be 'present' or 'absent'. Received: {}".format(state))
189 
190     if not deploy and state == 'present':
191         command += '--noDeploy '
192     if region:
193         command += '--region {} '.format(region)
194     if stage:
195         command += '--stage {} '.format(stage)
196 
197     rc, out, err = module.run_command(command, cwd=service_path)
198     if rc != 0:
199         if state == 'absent' and "-{}' does not exist".format(stage) in out:
200             module.exit_json(changed=False, state='absent', command=command,
201                              out=out, service_name=get_service_name(module, stage))
202 
203         module.fail_json(msg="Failure when executing Serverless command. Exited {}.\nstdout: {}\nstderr: {}".format(rc, out, err))
204 
205     # gather some facts about the deployment
206     module.exit_json(changed=True, state='present', out=out, command=command,
207                      service_name=get_service_name(module, stage))
208 
209 
210 if __name__ == '__main__':
211     main()
212
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/lib/ansible/modules/cloud/misc/serverless.py b/lib/ansible/modules/cloud/misc/serverless.py
--- a/lib/ansible/modules/cloud/misc/serverless.py
+++ b/lib/ansible/modules/cloud/misc/serverless.py
@@ -56,6 +56,18 @@
         run to send them out. This is mostly useful for generating artifacts to be stored/deployed elsewhere.
     required: false
     default: true
+  force:
+    description:
+      - Whether or not to force full deployment, equivalent to serverless `--force` option.
+    required: false
+    default: false
+    version_added: "2.7"
+  verbose:
+    description:
+      - Shows all stack events during deployment, and display any Stack Output.
+    required: false
+    default: false
+    version_added: "2.7"
 notes:
    - Currently, the `serverless` command must be in the path of the node executing the task. In the future this may be a flag.
 requirements: [ "serverless", "yaml" ]
@@ -160,7 +172,9 @@
             region=dict(default='', required=False),
             stage=dict(default='', required=False),
             deploy=dict(default=True, type='bool', required=False),
-            serverless_bin_path=dict(required=False, type='path')
+            serverless_bin_path=dict(required=False, type='path'),
+            force=dict(default=False, required=False),
+            verbose=dict(default=False, required=False)
         ),
     )
 
@@ -173,6 +187,8 @@
     region = module.params.get('region')
     stage = module.params.get('stage')
     deploy = module.params.get('deploy', True)
+    force = module.params.get('force', False)
+    verbose = module.params.get('verbose', False)
     serverless_bin_path = module.params.get('serverless_bin_path')
 
     if serverless_bin_path is not None:
@@ -187,12 +203,18 @@
     else:
         module.fail_json(msg="State must either be 'present' or 'absent'. Received: {}".format(state))
 
-    if not deploy and state == 'present':
-        command += '--noDeploy '
+    if state == 'present':
+        if not deploy:
+            command += '--noDeploy '
+        elif force:
+            command += '--force '
+
     if region:
         command += '--region {} '.format(region)
     if stage:
         command += '--stage {} '.format(stage)
+    if verbose:
+        command += '--verbose '
 
     rc, out, err = module.run_command(command, cwd=service_path)
     if rc != 0:

{"golden_diff": "diff --git a/lib/ansible/modules/cloud/misc/serverless.py b/lib/ansible/modules/cloud/misc/serverless.py\n--- a/lib/ansible/modules/cloud/misc/serverless.py\n+++ b/lib/ansible/modules/cloud/misc/serverless.py\n@@ -56,6 +56,18 @@\n         run to send them out. This is mostly useful for generating artifacts to be stored/deployed elsewhere.\n     required: false\n     default: true\n+  force:\n+    description:\n+      - Whether or not to force full deployment, equivalent to serverless `--force` option.\n+    required: false\n+    default: false\n+    version_added: \"2.7\"\n+  verbose:\n+    description:\n+      - Shows all stack events during deployment, and display any Stack Output.\n+    required: false\n+    default: false\n+    version_added: \"2.7\"\n notes:\n    - Currently, the `serverless` command must be in the path of the node executing the task. In the future this may be a flag.\n requirements: [ \"serverless\", \"yaml\" ]\n@@ -160,7 +172,9 @@\n             region=dict(default='', required=False),\n             stage=dict(default='', required=False),\n             deploy=dict(default=True, type='bool', required=False),\n-            serverless_bin_path=dict(required=False, type='path')\n+            serverless_bin_path=dict(required=False, type='path'),\n+            force=dict(default=False, required=False),\n+            verbose=dict(default=False, required=False)\n         ),\n     )\n \n@@ -173,6 +187,8 @@\n     region = module.params.get('region')\n     stage = module.params.get('stage')\n     deploy = module.params.get('deploy', True)\n+    force = module.params.get('force', False)\n+    verbose = module.params.get('verbose', False)\n     serverless_bin_path = module.params.get('serverless_bin_path')\n \n     if serverless_bin_path is not None:\n@@ -187,12 +203,18 @@\n     else:\n         module.fail_json(msg=\"State must either be 'present' or 'absent'. Received: {}\".format(state))\n \n-    if not deploy and state == 'present':\n-        command += '--noDeploy '\n+    if state == 'present':\n+        if not deploy:\n+            command += '--noDeploy '\n+        elif force:\n+            command += '--force '\n+\n     if region:\n         command += '--region {} '.format(region)\n     if stage:\n         command += '--stage {} '.format(stage)\n+    if verbose:\n+        command += '--verbose '\n \n     rc, out, err = module.run_command(command, cwd=service_path)\n     if rc != 0:\n", "issue": "Serverless Module - Support Verbose Mode\n<!---\r\nVerify first that your issue/request is not already reported on GitHub.\r\nAlso test if the latest release, and master branch are affected too.\r\n-->\r\n\r\n##### ISSUE TYPE\r\n<!--- Pick one below and delete the rest: -->\r\n - Feature Idea\r\n\r\n##### COMPONENT NAME\r\n<!--- Name of the module/plugin/task/feature -->\r\n<!--- Please do not include extra details here, e.g. \"vyos_command\" not \"the network module vyos_command\" -->\r\n- serverless.py\r\n\r\n##### ANSIBLE VERSION\r\n<!--- Paste verbatim output from \"ansible --version\" between quotes below -->\r\n```\r\nansible 2.4.0.0\r\n```\r\n\r\n##### CONFIGURATION\r\n<!---\r\nIf using Ansible 2.4 or above, paste the results of \"ansible-config dump --only-changed\"\r\n\r\nOtherwise, mention any settings you have changed/added/removed in ansible.cfg\r\n(or using the ANSIBLE_* environment variables).\r\n-->\r\n```\r\nDEFAULT_HOST_LIST(env: ANSIBLE_INVENTORY) = [u'/.../inventory/dev']\r\n```\r\n\r\n##### OS / ENVIRONMENT\r\n<!---\r\nMention the OS you are running Ansible from, and the OS you are\r\nmanaging, or say \"N/A\" for anything that is not platform-specific.\r\nAlso mention the specific version of what you are trying to control,\r\ne.g. if this is a network bug the version of firmware on the network device.\r\n-->\r\n- N/A\r\n\r\n##### SUMMARY\r\n<!--- Explain the problem briefly -->\r\n\r\nWhen using Ansible to deploy Serverless projects it would be very helpful to be able to turn on verbose mode (`-v`)\r\n\r\n**Reference:** https://serverless.com/framework/docs/providers/aws/cli-reference/deploy/\r\n\r\n##### STEPS TO REPRODUCE\r\n<!---\r\nFor bugs, show exactly how to reproduce the problem, using a minimal test-case.\r\nFor new features, show how the feature would be used.\r\n-->\r\n\r\n<!--- Paste example playbooks or commands between quotes below -->\r\nAdd `verbose=\"true\"` to `serverless` command and/or piggyback on Ansible verbose mode\r\n```yaml\r\n- name: configure | Run Serverless\r\n  serverless: stage=\"{{ env }}\" region=\"{{ ec2_region }}\" service_path=\"{{ serverless_service_path }}\" verbose=\"true\"\r\n```\r\n\r\n<!--- You can also paste gist.github.com links for larger files -->\r\n\r\n##### EXPECTED RESULTS\r\n<!--- What did you expect to happen when running the steps above? -->\r\nYou would see Serverless verbose logging in the Ansible log\r\n```\r\nServerless: Packaging service...\r\nServerless: Creating Stack...\r\nServerless: Checking Stack create progress...\r\nCloudFormation - CREATE_IN_PROGRESS - AWS::CloudFormation::Stack - ***\r\nCloudFormation - CREATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket\r\n(removed additional printout)\r\nServerless: Operation failed!\r\n```\r\n##### ACTUAL RESULTS\r\n<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->\r\n\r\n<!--- Paste verbatim command output between quotes below -->\r\n```\r\nServerless: Packaging service...\r\nServerless: Creating Stack...\r\nServerless: Checking Stack create progress...\r\n....\r\nServerless: Operation failed!\r\n```\r\n**Note:** The `....` seen above is Serverless not listing all AWS commands because it's not in verbose mode\n", "before_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# (c) 2016, Ryan Scott Brown <ryansb@redhat.com>\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\nfrom __future__ import absolute_import, division, print_function\n__metaclass__ = type\n\n\nANSIBLE_METADATA = {'metadata_version': '1.1',\n                    'status': ['preview'],\n                    'supported_by': 'community'}\n\n\nDOCUMENTATION = '''\n---\nmodule: serverless\nshort_description: Manages a Serverless Framework project\ndescription:\n     - Provides support for managing Serverless Framework (https://serverless.com/) project deployments and stacks.\nversion_added: \"2.3\"\noptions:\n  state:\n    choices: ['present', 'absent']\n    description:\n      - Goal state of given stage/project\n    required: false\n    default: present\n  serverless_bin_path:\n    description:\n      - The path of a serverless framework binary relative to the 'service_path' eg. node_module/.bin/serverless\n    required: false\n    version_added: \"2.4\"\n  service_path:\n    description:\n      - The path to the root of the Serverless Service to be operated on.\n    required: true\n  stage:\n    description:\n      - The name of the serverless framework project stage to deploy to. This uses the serverless framework default \"dev\".\n    required: false\n  functions:\n    description:\n      - A list of specific functions to deploy. If this is not provided, all functions in the service will be deployed.\n    required: false\n    default: []\n  region:\n    description:\n      - AWS region to deploy the service to\n    required: false\n    default: us-east-1\n  deploy:\n    description:\n      - Whether or not to deploy artifacts after building them. When this option is `false` all the functions will be built, but no stack update will be\n        run to send them out. This is mostly useful for generating artifacts to be stored/deployed elsewhere.\n    required: false\n    default: true\nnotes:\n   - Currently, the `serverless` command must be in the path of the node executing the task. In the future this may be a flag.\nrequirements: [ \"serverless\", \"yaml\" ]\nauthor: \"Ryan Scott Brown @ryansb\"\n'''\n\nEXAMPLES = \"\"\"\n# Basic deploy of a service\n- serverless:\n    service_path: '{{ project_dir }}'\n    state: present\n\n# Deploy specific functions\n- serverless:\n    service_path: '{{ project_dir }}'\n    functions:\n      - my_func_one\n      - my_func_two\n\n# deploy a project, then pull its resource list back into Ansible\n- serverless:\n    stage: dev\n    region: us-east-1\n    service_path: '{{ project_dir }}'\n  register: sls\n# The cloudformation stack is always named the same as the full service, so the\n# cloudformation_facts module can get a full list of the stack resources, as\n# well as stack events and outputs\n- cloudformation_facts:\n    region: us-east-1\n    stack_name: '{{ sls.service_name }}'\n    stack_resources: true\n\n# Deploy a project but use a locally installed serverless binary instead of the global serverless binary\n- serverless:\n    stage: dev\n    region: us-east-1\n    service_path: '{{ project_dir }}'\n    serverless_bin_path: node_modules/.bin/serverless\n\"\"\"\n\nRETURN = \"\"\"\nservice_name:\n  type: string\n  description: The service name specified in the serverless.yml that was just deployed.\n  returned: always\n  sample: my-fancy-service-dev\nstate:\n  type: string\n  description: Whether the stack for the serverless project is present/absent.\n  returned: always\ncommand:\n  type: string\n  description: Full `serverless` command run by this module, in case you want to re-run the command outside the module.\n  returned: always\n  sample: serverless deploy --stage production\n\"\"\"\n\nimport os\nimport traceback\n\ntry:\n    import yaml\n    HAS_YAML = True\nexcept ImportError:\n    HAS_YAML = False\n\nfrom ansible.module_utils.basic import AnsibleModule\n\n\ndef read_serverless_config(module):\n    path = module.params.get('service_path')\n\n    try:\n        with open(os.path.join(path, 'serverless.yml')) as sls_config:\n            config = yaml.safe_load(sls_config.read())\n            return config\n    except IOError as e:\n        module.fail_json(msg=\"Could not open serverless.yml in {}. err: {}\".format(path, str(e)), exception=traceback.format_exc())\n\n    module.fail_json(msg=\"Failed to open serverless config at {}\".format(\n        os.path.join(path, 'serverless.yml')))\n\n\ndef get_service_name(module, stage):\n    config = read_serverless_config(module)\n    if config.get('service') is None:\n        module.fail_json(msg=\"Could not read `service` key from serverless.yml file\")\n\n    if stage:\n        return \"{}-{}\".format(config['service'], stage)\n\n    return \"{}-{}\".format(config['service'], config.get('stage', 'dev'))\n\n\ndef main():\n    module = AnsibleModule(\n        argument_spec=dict(\n            service_path=dict(required=True, type='path'),\n            state=dict(default='present', choices=['present', 'absent'], required=False),\n            functions=dict(type='list', required=False),\n            region=dict(default='', required=False),\n            stage=dict(default='', required=False),\n            deploy=dict(default=True, type='bool', required=False),\n            serverless_bin_path=dict(required=False, type='path')\n        ),\n    )\n\n    if not HAS_YAML:\n        module.fail_json(msg='yaml is required for this module')\n\n    service_path = module.params.get('service_path')\n    state = module.params.get('state')\n    functions = module.params.get('functions')\n    region = module.params.get('region')\n    stage = module.params.get('stage')\n    deploy = module.params.get('deploy', True)\n    serverless_bin_path = module.params.get('serverless_bin_path')\n\n    if serverless_bin_path is not None:\n        command = serverless_bin_path + \" \"\n    else:\n        command = \"serverless \"\n\n    if state == 'present':\n        command += 'deploy '\n    elif state == 'absent':\n        command += 'remove '\n    else:\n        module.fail_json(msg=\"State must either be 'present' or 'absent'. Received: {}\".format(state))\n\n    if not deploy and state == 'present':\n        command += '--noDeploy '\n    if region:\n        command += '--region {} '.format(region)\n    if stage:\n        command += '--stage {} '.format(stage)\n\n    rc, out, err = module.run_command(command, cwd=service_path)\n    if rc != 0:\n        if state == 'absent' and \"-{}' does not exist\".format(stage) in out:\n            module.exit_json(changed=False, state='absent', command=command,\n                             out=out, service_name=get_service_name(module, stage))\n\n        module.fail_json(msg=\"Failure when executing Serverless command. Exited {}.\\nstdout: {}\\nstderr: {}\".format(rc, out, err))\n\n    # gather some facts about the deployment\n    module.exit_json(changed=True, state='present', out=out, command=command,\n                     service_name=get_service_name(module, stage))\n\n\nif __name__ == '__main__':\n    main()\n", "path": "lib/ansible/modules/cloud/misc/serverless.py"}], "after_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# (c) 2016, Ryan Scott Brown <ryansb@redhat.com>\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\nfrom __future__ import absolute_import, division, print_function\n__metaclass__ = type\n\n\nANSIBLE_METADATA = {'metadata_version': '1.1',\n                    'status': ['preview'],\n                    'supported_by': 'community'}\n\n\nDOCUMENTATION = '''\n---\nmodule: serverless\nshort_description: Manages a Serverless Framework project\ndescription:\n     - Provides support for managing Serverless Framework (https://serverless.com/) project deployments and stacks.\nversion_added: \"2.3\"\noptions:\n  state:\n    choices: ['present', 'absent']\n    description:\n      - Goal state of given stage/project\n    required: false\n    default: present\n  serverless_bin_path:\n    description:\n      - The path of a serverless framework binary relative to the 'service_path' eg. node_module/.bin/serverless\n    required: false\n    version_added: \"2.4\"\n  service_path:\n    description:\n      - The path to the root of the Serverless Service to be operated on.\n    required: true\n  stage:\n    description:\n      - The name of the serverless framework project stage to deploy to. This uses the serverless framework default \"dev\".\n    required: false\n  functions:\n    description:\n      - A list of specific functions to deploy. If this is not provided, all functions in the service will be deployed.\n    required: false\n    default: []\n  region:\n    description:\n      - AWS region to deploy the service to\n    required: false\n    default: us-east-1\n  deploy:\n    description:\n      - Whether or not to deploy artifacts after building them. When this option is `false` all the functions will be built, but no stack update will be\n        run to send them out. This is mostly useful for generating artifacts to be stored/deployed elsewhere.\n    required: false\n    default: true\n  force:\n    description:\n      - Whether or not to force full deployment, equivalent to serverless `--force` option.\n    required: false\n    default: false\n    version_added: \"2.7\"\n  verbose:\n    description:\n      - Shows all stack events during deployment, and display any Stack Output.\n    required: false\n    default: false\n    version_added: \"2.7\"\nnotes:\n   - Currently, the `serverless` command must be in the path of the node executing the task. In the future this may be a flag.\nrequirements: [ \"serverless\", \"yaml\" ]\nauthor: \"Ryan Scott Brown @ryansb\"\n'''\n\nEXAMPLES = \"\"\"\n# Basic deploy of a service\n- serverless:\n    service_path: '{{ project_dir }}'\n    state: present\n\n# Deploy specific functions\n- serverless:\n    service_path: '{{ project_dir }}'\n    functions:\n      - my_func_one\n      - my_func_two\n\n# deploy a project, then pull its resource list back into Ansible\n- serverless:\n    stage: dev\n    region: us-east-1\n    service_path: '{{ project_dir }}'\n  register: sls\n# The cloudformation stack is always named the same as the full service, so the\n# cloudformation_facts module can get a full list of the stack resources, as\n# well as stack events and outputs\n- cloudformation_facts:\n    region: us-east-1\n    stack_name: '{{ sls.service_name }}'\n    stack_resources: true\n\n# Deploy a project but use a locally installed serverless binary instead of the global serverless binary\n- serverless:\n    stage: dev\n    region: us-east-1\n    service_path: '{{ project_dir }}'\n    serverless_bin_path: node_modules/.bin/serverless\n\"\"\"\n\nRETURN = \"\"\"\nservice_name:\n  type: string\n  description: The service name specified in the serverless.yml that was just deployed.\n  returned: always\n  sample: my-fancy-service-dev\nstate:\n  type: string\n  description: Whether the stack for the serverless project is present/absent.\n  returned: always\ncommand:\n  type: string\n  description: Full `serverless` command run by this module, in case you want to re-run the command outside the module.\n  returned: always\n  sample: serverless deploy --stage production\n\"\"\"\n\nimport os\nimport traceback\n\ntry:\n    import yaml\n    HAS_YAML = True\nexcept ImportError:\n    HAS_YAML = False\n\nfrom ansible.module_utils.basic import AnsibleModule\n\n\ndef read_serverless_config(module):\n    path = module.params.get('service_path')\n\n    try:\n        with open(os.path.join(path, 'serverless.yml')) as sls_config:\n            config = yaml.safe_load(sls_config.read())\n            return config\n    except IOError as e:\n        module.fail_json(msg=\"Could not open serverless.yml in {}. err: {}\".format(path, str(e)), exception=traceback.format_exc())\n\n    module.fail_json(msg=\"Failed to open serverless config at {}\".format(\n        os.path.join(path, 'serverless.yml')))\n\n\ndef get_service_name(module, stage):\n    config = read_serverless_config(module)\n    if config.get('service') is None:\n        module.fail_json(msg=\"Could not read `service` key from serverless.yml file\")\n\n    if stage:\n        return \"{}-{}\".format(config['service'], stage)\n\n    return \"{}-{}\".format(config['service'], config.get('stage', 'dev'))\n\n\ndef main():\n    module = AnsibleModule(\n        argument_spec=dict(\n            service_path=dict(required=True, type='path'),\n            state=dict(default='present', choices=['present', 'absent'], required=False),\n            functions=dict(type='list', required=False),\n            region=dict(default='', required=False),\n            stage=dict(default='', required=False),\n            deploy=dict(default=True, type='bool', required=False),\n            serverless_bin_path=dict(required=False, type='path'),\n            force=dict(default=False, required=False),\n            verbose=dict(default=False, required=False)\n        ),\n    )\n\n    if not HAS_YAML:\n        module.fail_json(msg='yaml is required for this module')\n\n    service_path = module.params.get('service_path')\n    state = module.params.get('state')\n    functions = module.params.get('functions')\n    region = module.params.get('region')\n    stage = module.params.get('stage')\n    deploy = module.params.get('deploy', True)\n    force = module.params.get('force', False)\n    verbose = module.params.get('verbose', False)\n    serverless_bin_path = module.params.get('serverless_bin_path')\n\n    if serverless_bin_path is not None:\n        command = serverless_bin_path + \" \"\n    else:\n        command = \"serverless \"\n\n    if state == 'present':\n        command += 'deploy '\n    elif state == 'absent':\n        command += 'remove '\n    else:\n        module.fail_json(msg=\"State must either be 'present' or 'absent'. Received: {}\".format(state))\n\n    if state == 'present':\n        if not deploy:\n            command += '--noDeploy '\n        elif force:\n            command += '--force '\n\n    if region:\n        command += '--region {} '.format(region)\n    if stage:\n        command += '--stage {} '.format(stage)\n    if verbose:\n        command += '--verbose '\n\n    rc, out, err = module.run_command(command, cwd=service_path)\n    if rc != 0:\n        if state == 'absent' and \"-{}' does not exist\".format(stage) in out:\n            module.exit_json(changed=False, state='absent', command=command,\n                             out=out, service_name=get_service_name(module, stage))\n\n        module.fail_json(msg=\"Failure when executing Serverless command. Exited {}.\\nstdout: {}\\nstderr: {}\".format(rc, out, err))\n\n    # gather some facts about the deployment\n    module.exit_json(changed=True, state='present', out=out, command=command,\n                     service_name=get_service_name(module, stage))\n\n\nif __name__ == '__main__':\n    main()\n", "path": "lib/ansible/modules/cloud/misc/serverless.py"}]}