We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add new example for `amazon.aws.aws_secret` that includes use of `region=` and `aws_profile=` parameters
### Summary

In order to get my `amazon.aws.aws_secret` lookup to work, I had to add the `region=` and `aws_profile=` parameters. I found these through Google searches and guesswork... Would it be worth having a new example that shows them in use?

For example, to take one of the existing examples and modify it a little:
```
- name: lookup secretsmanager secret in the current region using the nested feature - specify region and AWS Profile
  debug: msg="{{ lookup('amazon.aws.aws_secret', 'secrets.environments.production.password', nested=true, region=us-east-1, aws_profile=dev-profile) }}"
  # The secret can be queried using the following syntax: `aws_secret_object_name.key1.key2.key3`.
  # If an object is of the form `{"key1":{"key2":{"key3":1}}}` the query would return the value `1`.
  # region= should be changed to reflect what region AWS Secret is stored
  # aws_profile= should reflect what AWS Profile to use, that has access to the AWS Secret
```
Just a thought, if you feel this isn't needed, please ignore.

Thanks!

### Issue Type

Documentation Report

### Component Name

amazon.aws.aws_secret

### Ansible Version

```console (paste below)
$ ansible --version

```


### Collection Versions

```console (paste below)
$ ansible-galaxy collection list
```


### Configuration

```console (paste below)
$ ansible-config dump --only-changed

```


### OS / Environment

_No response_

### Additional Information

_No response_

### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `plugins/lookup/aws_secret.py`
Content:
```
1 # Copyright: (c) 2018, Aaron Smith <ajsmith10381@gmail.com>
2 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
3 
4 from __future__ import (absolute_import, division, print_function)
5 __metaclass__ = type
6 
7 DOCUMENTATION = r'''
8 lookup: aws_secret
9 author:
10   - Aaron Smith <ajsmith10381@gmail.com>
11 requirements:
12   - python >= 3.6
13   - boto3
14   - botocore >= 1.16.0
15 extends_documentation_fragment:
16 - amazon.aws.aws_credentials
17 - amazon.aws.aws_region
18 
19 short_description: Look up secrets stored in AWS Secrets Manager.
20 description:
21   - Look up secrets stored in AWS Secrets Manager provided the caller
22     has the appropriate permissions to read the secret.
23   - Lookup is based on the secret's I(Name) value.
24   - Optional parameters can be passed into this lookup; I(version_id) and I(version_stage)
25 options:
26   _terms:
27     description: Name of the secret to look up in AWS Secrets Manager.
28     required: True
29   bypath:
30     description: A boolean to indicate whether the parameter is provided as a hierarchy.
31     default: false
32     type: boolean
33     version_added: 1.4.0
34   nested:
35     description: A boolean to indicate the secret contains nested values.
36     type: boolean
37     default: false
38     version_added: 1.4.0
39   version_id:
40     description: Version of the secret(s).
41     required: False
42   version_stage:
43     description: Stage of the secret version.
44     required: False
45   join:
46     description:
47         - Join two or more entries to form an extended secret.
48         - This is useful for overcoming the 4096 character limit imposed by AWS.
49         - No effect when used with I(bypath).
50     type: boolean
51     default: false
52   on_missing:
53     description:
54         - Action to take if the secret is missing.
55         - C(error) will raise a fatal error when the secret is missing.
56         - C(skip) will silently ignore the missing secret.
57         - C(warn) will skip over the missing secret but issue a warning.
58     default: error
59     type: string
60     choices: ['error', 'skip', 'warn']
61   on_denied:
62     description:
63         - Action to take if access to the secret is denied.
64         - C(error) will raise a fatal error when access to the secret is denied.
65         - C(skip) will silently ignore the denied secret.
66         - C(warn) will skip over the denied secret but issue a warning.
67     default: error
68     type: string
69     choices: ['error', 'skip', 'warn']
70 '''
71 
72 EXAMPLES = r"""
73  - name: lookup secretsmanager secret in the current region
74    debug: msg="{{ lookup('amazon.aws.aws_secret', '/path/to/secrets', bypath=true) }}"
75 
76  - name: Create RDS instance with aws_secret lookup for password param
77    rds:
78      command: create
79      instance_name: app-db
80      db_engine: MySQL
81      size: 10
82      instance_type: db.m1.small
83      username: dbadmin
84      password: "{{ lookup('amazon.aws.aws_secret', 'DbSecret') }}"
85      tags:
86        Environment: staging
87 
88  - name: skip if secret does not exist
89    debug: msg="{{ lookup('amazon.aws.aws_secret', 'secret-not-exist', on_missing='skip')}}"
90 
91  - name: warn if access to the secret is denied
92    debug: msg="{{ lookup('amazon.aws.aws_secret', 'secret-denied', on_denied='warn')}}"
93 
94  - name: lookup secretsmanager secret in the current region using the nested feature
95    debug: msg="{{ lookup('amazon.aws.aws_secret', 'secrets.environments.production.password', nested=true) }}"
96    # The secret can be queried using the following syntax: `aws_secret_object_name.key1.key2.key3`.
97    # If an object is of the form `{"key1":{"key2":{"key3":1}}}` the query would return the value `1`.
98 """
99 
100 RETURN = r"""
101 _raw:
102   description:
103     Returns the value of the secret stored in AWS Secrets Manager.
104 """
105 
106 import json
107 
108 try:
109     import boto3
110     import botocore
111 except ImportError:
112     pass  # will be captured by imported HAS_BOTO3
113 
114 from ansible.errors import AnsibleError
115 from ansible.module_utils.six import string_types
116 from ansible.module_utils._text import to_native
117 from ansible.plugins.lookup import LookupBase
118 
119 from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code
120 from ansible_collections.amazon.aws.plugins.module_utils.ec2 import HAS_BOTO3
121 
122 
123 def _boto3_conn(region, credentials):
124     boto_profile = credentials.pop('aws_profile', None)
125 
126     try:
127         connection = boto3.session.Session(profile_name=boto_profile).client('secretsmanager', region, **credentials)
128     except (botocore.exceptions.ProfileNotFound, botocore.exceptions.PartialCredentialsError) as e:
129         if boto_profile:
130             try:
131                 connection = boto3.session.Session(profile_name=boto_profile).client('secretsmanager', region)
132             except (botocore.exceptions.ProfileNotFound, botocore.exceptions.PartialCredentialsError) as e:
133                 raise AnsibleError("Insufficient credentials found.")
134         else:
135             raise AnsibleError("Insufficient credentials found.")
136     return connection
137 
138 
139 class LookupModule(LookupBase):
140     def run(self, terms, variables=None, boto_profile=None, aws_profile=None,
141             aws_secret_key=None, aws_access_key=None, aws_security_token=None, region=None,
142             bypath=False, nested=False, join=False, version_stage=None, version_id=None, on_missing='error',
143             on_denied='error'):
144         '''
145                    :arg terms: a list of lookups to run.
146                        e.g. ['parameter_name', 'parameter_name_too' ]
147                    :kwarg variables: ansible variables active at the time of the lookup
148                    :kwarg aws_secret_key: identity of the AWS key to use
149                    :kwarg aws_access_key: AWS secret key (matching identity)
150                    :kwarg aws_security_token: AWS session key if using STS
151                    :kwarg decrypt: Set to True to get decrypted parameters
152                    :kwarg region: AWS region in which to do the lookup
153                    :kwarg bypath: Set to True to do a lookup of variables under a path
154                    :kwarg nested: Set to True to do a lookup of nested secrets
155                    :kwarg join: Join two or more entries to form an extended secret
156                    :kwarg version_stage: Stage of the secret version
157                    :kwarg version_id: Version of the secret(s)
158                    :kwarg on_missing: Action to take if the secret is missing
159                    :kwarg on_denied: Action to take if access to the secret is denied
160                    :returns: A list of parameter values or a list of dictionaries if bypath=True.
161                '''
162         if not HAS_BOTO3:
163             raise AnsibleError('botocore and boto3 are required for aws_ssm lookup.')
164 
165         missing = on_missing.lower()
166         if not isinstance(missing, string_types) or missing not in ['error', 'warn', 'skip']:
167             raise AnsibleError('"on_missing" must be a string and one of "error", "warn" or "skip", not %s' % missing)
168 
169         denied = on_denied.lower()
170         if not isinstance(denied, string_types) or denied not in ['error', 'warn', 'skip']:
171             raise AnsibleError('"on_denied" must be a string and one of "error", "warn" or "skip", not %s' % denied)
172 
173         credentials = {}
174         if aws_profile:
175             credentials['aws_profile'] = aws_profile
176         else:
177             credentials['aws_profile'] = boto_profile
178         credentials['aws_secret_access_key'] = aws_secret_key
179         credentials['aws_access_key_id'] = aws_access_key
180         credentials['aws_session_token'] = aws_security_token
181 
182         # fallback to IAM role credentials
183         if not credentials['aws_profile'] and not (
184                 credentials['aws_access_key_id'] and credentials['aws_secret_access_key']):
185             session = botocore.session.get_session()
186             if session.get_credentials() is not None:
187                 credentials['aws_access_key_id'] = session.get_credentials().access_key
188                 credentials['aws_secret_access_key'] = session.get_credentials().secret_key
189                 credentials['aws_session_token'] = session.get_credentials().token
190 
191         client = _boto3_conn(region, credentials)
192 
193         if bypath:
194             secrets = {}
195             for term in terms:
196                 try:
197                     response = client.list_secrets(Filters=[{'Key': 'name', 'Values': [term]}])
198 
199                     if 'SecretList' in response:
200                         for secret in response['SecretList']:
201                             secrets.update({secret['Name']: self.get_secret_value(secret['Name'], client,
202                                                                                   on_missing=missing,
203                                                                                   on_denied=denied)})
204                 except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
205                     raise AnsibleError("Failed to retrieve secret: %s" % to_native(e))
206             secrets = [secrets]
207         else:
208             secrets = []
209             for term in terms:
210                 value = self.get_secret_value(term, client,
211                                               version_stage=version_stage, version_id=version_id,
212                                               on_missing=missing, on_denied=denied, nested=nested)
213                 if value:
214                     secrets.append(value)
215             if join:
216                 joined_secret = []
217                 joined_secret.append(''.join(secrets))
218                 return joined_secret
219 
220         return secrets
221 
222     def get_secret_value(self, term, client, version_stage=None, version_id=None, on_missing=None, on_denied=None, nested=False):
223         params = {}
224         params['SecretId'] = term
225         if version_id:
226             params['VersionId'] = version_id
227         if version_stage:
228             params['VersionStage'] = version_stage
229         if nested:
230             if len(term.split('.')) < 2:
231                 raise AnsibleError("Nested query must use the following syntax: `aws_secret_name.<key_name>.<key_name>")
232             secret_name = term.split('.')[0]
233             params['SecretId'] = secret_name
234 
235         try:
236             response = client.get_secret_value(**params)
237             if 'SecretBinary' in response:
238                 return response['SecretBinary']
239             if 'SecretString' in response:
240                 if nested:
241                     secrets = []
242                     query = term.split('.')[1:]
243                     secret_string = json.loads(response['SecretString'])
244                     ret_val = secret_string
245                     for key in query:
246                         if key in ret_val:
247                             ret_val = ret_val[key]
248                         else:
249                             raise AnsibleError("Successfully retrieved secret but there exists no key {0} in the secret".format(key))
250                     return str(ret_val)
251                 else:
252                     return response['SecretString']
253         except is_boto3_error_code('ResourceNotFoundException'):
254             if on_missing == 'error':
255                 raise AnsibleError("Failed to find secret %s (ResourceNotFound)" % term)
256             elif on_missing == 'warn':
257                 self._display.warning('Skipping, did not find secret %s' % term)
258         except is_boto3_error_code('AccessDeniedException'):  # pylint: disable=duplicate-except
259             if on_denied == 'error':
260                 raise AnsibleError("Failed to access secret %s (AccessDenied)" % term)
261             elif on_denied == 'warn':
262                 self._display.warning('Skipping, access denied for secret %s' % term)
263         except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:  # pylint: disable=duplicate-except
264             raise AnsibleError("Failed to retrieve secret: %s" % to_native(e))
265 
266         return None
267
```
--- 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/plugins/lookup/aws_secret.py b/plugins/lookup/aws_secret.py
--- a/plugins/lookup/aws_secret.py
+++ b/plugins/lookup/aws_secret.py
@@ -95,6 +95,14 @@
    debug: msg="{{ lookup('amazon.aws.aws_secret', 'secrets.environments.production.password', nested=true) }}"
    # The secret can be queried using the following syntax: `aws_secret_object_name.key1.key2.key3`.
    # If an object is of the form `{"key1":{"key2":{"key3":1}}}` the query would return the value `1`.
+ - name: lookup secretsmanager secret in a specific region using specified region and aws profile using nested feature
+   debug: >
+    msg="{{ lookup('amazon.aws.aws_secret', 'secrets.environments.production.password', region=region, aws_profile=aws_profile,
+    aws_access_key=aws_access_key, aws_secret_key=aws_secret_key, nested=true) }}"
+   # The secret can be queried using the following syntax: `aws_secret_object_name.key1.key2.key3`.
+   # If an object is of the form `{"key1":{"key2":{"key3":1}}}` the query would return the value `1`.
+   # Region is the AWS region where the AWS secret is stored.
+   # AWS_profile is the aws profile to use, that has access to the AWS secret.
 """
 
 RETURN = r"""

{"golden_diff": "diff --git a/plugins/lookup/aws_secret.py b/plugins/lookup/aws_secret.py\n--- a/plugins/lookup/aws_secret.py\n+++ b/plugins/lookup/aws_secret.py\n@@ -95,6 +95,14 @@\n    debug: msg=\"{{ lookup('amazon.aws.aws_secret', 'secrets.environments.production.password', nested=true) }}\"\n    # The secret can be queried using the following syntax: `aws_secret_object_name.key1.key2.key3`.\n    # If an object is of the form `{\"key1\":{\"key2\":{\"key3\":1}}}` the query would return the value `1`.\n+ - name: lookup secretsmanager secret in a specific region using specified region and aws profile using nested feature\n+   debug: >\n+    msg=\"{{ lookup('amazon.aws.aws_secret', 'secrets.environments.production.password', region=region, aws_profile=aws_profile,\n+    aws_access_key=aws_access_key, aws_secret_key=aws_secret_key, nested=true) }}\"\n+   # The secret can be queried using the following syntax: `aws_secret_object_name.key1.key2.key3`.\n+   # If an object is of the form `{\"key1\":{\"key2\":{\"key3\":1}}}` the query would return the value `1`.\n+   # Region is the AWS region where the AWS secret is stored.\n+   # AWS_profile is the aws profile to use, that has access to the AWS secret.\n \"\"\"\n \n RETURN = r\"\"\"\n", "issue": "Add new example for `amazon.aws.aws_secret` that includes use of `region=` and `aws_profile=` parameters\n### Summary\r\n\r\nIn order to get my `amazon.aws.aws_secret` lookup to work, I had to add the `region=` and `aws_profile=` parameters. I found these through Google searches and guesswork... Would it be worth having a new example that shows them in use?\r\n\r\nFor example, to take one of the existing examples and modify it a little:\r\n```\r\n- name: lookup secretsmanager secret in the current region using the nested feature - specify region and AWS Profile\r\n  debug: msg=\"{{ lookup('amazon.aws.aws_secret', 'secrets.environments.production.password', nested=true, region=us-east-1, aws_profile=dev-profile) }}\"\r\n  # The secret can be queried using the following syntax: `aws_secret_object_name.key1.key2.key3`.\r\n  # If an object is of the form `{\"key1\":{\"key2\":{\"key3\":1}}}` the query would return the value `1`.\r\n  # region= should be changed to reflect what region AWS Secret is stored\r\n  # aws_profile= should reflect what AWS Profile to use, that has access to the AWS Secret\r\n```\r\nJust a thought, if you feel this isn't needed, please ignore.\r\n\r\nThanks!\r\n\r\n### Issue Type\r\n\r\nDocumentation Report\r\n\r\n### Component Name\r\n\r\namazon.aws.aws_secret\r\n\r\n### Ansible Version\r\n\r\n```console (paste below)\r\n$ ansible --version\r\n\r\n```\r\n\r\n\r\n### Collection Versions\r\n\r\n```console (paste below)\r\n$ ansible-galaxy collection list\r\n```\r\n\r\n\r\n### Configuration\r\n\r\n```console (paste below)\r\n$ ansible-config dump --only-changed\r\n\r\n```\r\n\r\n\r\n### OS / Environment\r\n\r\n_No response_\r\n\r\n### Additional Information\r\n\r\n_No response_\r\n\r\n### Code of Conduct\r\n\r\n- [X] I agree to follow the Ansible Code of Conduct\n", "before_files": [{"content": "# Copyright: (c) 2018, Aaron Smith <ajsmith10381@gmail.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\nDOCUMENTATION = r'''\nlookup: aws_secret\nauthor:\n  - Aaron Smith <ajsmith10381@gmail.com>\nrequirements:\n  - python >= 3.6\n  - boto3\n  - botocore >= 1.16.0\nextends_documentation_fragment:\n- amazon.aws.aws_credentials\n- amazon.aws.aws_region\n\nshort_description: Look up secrets stored in AWS Secrets Manager.\ndescription:\n  - Look up secrets stored in AWS Secrets Manager provided the caller\n    has the appropriate permissions to read the secret.\n  - Lookup is based on the secret's I(Name) value.\n  - Optional parameters can be passed into this lookup; I(version_id) and I(version_stage)\noptions:\n  _terms:\n    description: Name of the secret to look up in AWS Secrets Manager.\n    required: True\n  bypath:\n    description: A boolean to indicate whether the parameter is provided as a hierarchy.\n    default: false\n    type: boolean\n    version_added: 1.4.0\n  nested:\n    description: A boolean to indicate the secret contains nested values.\n    type: boolean\n    default: false\n    version_added: 1.4.0\n  version_id:\n    description: Version of the secret(s).\n    required: False\n  version_stage:\n    description: Stage of the secret version.\n    required: False\n  join:\n    description:\n        - Join two or more entries to form an extended secret.\n        - This is useful for overcoming the 4096 character limit imposed by AWS.\n        - No effect when used with I(bypath).\n    type: boolean\n    default: false\n  on_missing:\n    description:\n        - Action to take if the secret is missing.\n        - C(error) will raise a fatal error when the secret is missing.\n        - C(skip) will silently ignore the missing secret.\n        - C(warn) will skip over the missing secret but issue a warning.\n    default: error\n    type: string\n    choices: ['error', 'skip', 'warn']\n  on_denied:\n    description:\n        - Action to take if access to the secret is denied.\n        - C(error) will raise a fatal error when access to the secret is denied.\n        - C(skip) will silently ignore the denied secret.\n        - C(warn) will skip over the denied secret but issue a warning.\n    default: error\n    type: string\n    choices: ['error', 'skip', 'warn']\n'''\n\nEXAMPLES = r\"\"\"\n - name: lookup secretsmanager secret in the current region\n   debug: msg=\"{{ lookup('amazon.aws.aws_secret', '/path/to/secrets', bypath=true) }}\"\n\n - name: Create RDS instance with aws_secret lookup for password param\n   rds:\n     command: create\n     instance_name: app-db\n     db_engine: MySQL\n     size: 10\n     instance_type: db.m1.small\n     username: dbadmin\n     password: \"{{ lookup('amazon.aws.aws_secret', 'DbSecret') }}\"\n     tags:\n       Environment: staging\n\n - name: skip if secret does not exist\n   debug: msg=\"{{ lookup('amazon.aws.aws_secret', 'secret-not-exist', on_missing='skip')}}\"\n\n - name: warn if access to the secret is denied\n   debug: msg=\"{{ lookup('amazon.aws.aws_secret', 'secret-denied', on_denied='warn')}}\"\n\n - name: lookup secretsmanager secret in the current region using the nested feature\n   debug: msg=\"{{ lookup('amazon.aws.aws_secret', 'secrets.environments.production.password', nested=true) }}\"\n   # The secret can be queried using the following syntax: `aws_secret_object_name.key1.key2.key3`.\n   # If an object is of the form `{\"key1\":{\"key2\":{\"key3\":1}}}` the query would return the value `1`.\n\"\"\"\n\nRETURN = r\"\"\"\n_raw:\n  description:\n    Returns the value of the secret stored in AWS Secrets Manager.\n\"\"\"\n\nimport json\n\ntry:\n    import boto3\n    import botocore\nexcept ImportError:\n    pass  # will be captured by imported HAS_BOTO3\n\nfrom ansible.errors import AnsibleError\nfrom ansible.module_utils.six import string_types\nfrom ansible.module_utils._text import to_native\nfrom ansible.plugins.lookup import LookupBase\n\nfrom ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code\nfrom ansible_collections.amazon.aws.plugins.module_utils.ec2 import HAS_BOTO3\n\n\ndef _boto3_conn(region, credentials):\n    boto_profile = credentials.pop('aws_profile', None)\n\n    try:\n        connection = boto3.session.Session(profile_name=boto_profile).client('secretsmanager', region, **credentials)\n    except (botocore.exceptions.ProfileNotFound, botocore.exceptions.PartialCredentialsError) as e:\n        if boto_profile:\n            try:\n                connection = boto3.session.Session(profile_name=boto_profile).client('secretsmanager', region)\n            except (botocore.exceptions.ProfileNotFound, botocore.exceptions.PartialCredentialsError) as e:\n                raise AnsibleError(\"Insufficient credentials found.\")\n        else:\n            raise AnsibleError(\"Insufficient credentials found.\")\n    return connection\n\n\nclass LookupModule(LookupBase):\n    def run(self, terms, variables=None, boto_profile=None, aws_profile=None,\n            aws_secret_key=None, aws_access_key=None, aws_security_token=None, region=None,\n            bypath=False, nested=False, join=False, version_stage=None, version_id=None, on_missing='error',\n            on_denied='error'):\n        '''\n                   :arg terms: a list of lookups to run.\n                       e.g. ['parameter_name', 'parameter_name_too' ]\n                   :kwarg variables: ansible variables active at the time of the lookup\n                   :kwarg aws_secret_key: identity of the AWS key to use\n                   :kwarg aws_access_key: AWS secret key (matching identity)\n                   :kwarg aws_security_token: AWS session key if using STS\n                   :kwarg decrypt: Set to True to get decrypted parameters\n                   :kwarg region: AWS region in which to do the lookup\n                   :kwarg bypath: Set to True to do a lookup of variables under a path\n                   :kwarg nested: Set to True to do a lookup of nested secrets\n                   :kwarg join: Join two or more entries to form an extended secret\n                   :kwarg version_stage: Stage of the secret version\n                   :kwarg version_id: Version of the secret(s)\n                   :kwarg on_missing: Action to take if the secret is missing\n                   :kwarg on_denied: Action to take if access to the secret is denied\n                   :returns: A list of parameter values or a list of dictionaries if bypath=True.\n               '''\n        if not HAS_BOTO3:\n            raise AnsibleError('botocore and boto3 are required for aws_ssm lookup.')\n\n        missing = on_missing.lower()\n        if not isinstance(missing, string_types) or missing not in ['error', 'warn', 'skip']:\n            raise AnsibleError('\"on_missing\" must be a string and one of \"error\", \"warn\" or \"skip\", not %s' % missing)\n\n        denied = on_denied.lower()\n        if not isinstance(denied, string_types) or denied not in ['error', 'warn', 'skip']:\n            raise AnsibleError('\"on_denied\" must be a string and one of \"error\", \"warn\" or \"skip\", not %s' % denied)\n\n        credentials = {}\n        if aws_profile:\n            credentials['aws_profile'] = aws_profile\n        else:\n            credentials['aws_profile'] = boto_profile\n        credentials['aws_secret_access_key'] = aws_secret_key\n        credentials['aws_access_key_id'] = aws_access_key\n        credentials['aws_session_token'] = aws_security_token\n\n        # fallback to IAM role credentials\n        if not credentials['aws_profile'] and not (\n                credentials['aws_access_key_id'] and credentials['aws_secret_access_key']):\n            session = botocore.session.get_session()\n            if session.get_credentials() is not None:\n                credentials['aws_access_key_id'] = session.get_credentials().access_key\n                credentials['aws_secret_access_key'] = session.get_credentials().secret_key\n                credentials['aws_session_token'] = session.get_credentials().token\n\n        client = _boto3_conn(region, credentials)\n\n        if bypath:\n            secrets = {}\n            for term in terms:\n                try:\n                    response = client.list_secrets(Filters=[{'Key': 'name', 'Values': [term]}])\n\n                    if 'SecretList' in response:\n                        for secret in response['SecretList']:\n                            secrets.update({secret['Name']: self.get_secret_value(secret['Name'], client,\n                                                                                  on_missing=missing,\n                                                                                  on_denied=denied)})\n                except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:\n                    raise AnsibleError(\"Failed to retrieve secret: %s\" % to_native(e))\n            secrets = [secrets]\n        else:\n            secrets = []\n            for term in terms:\n                value = self.get_secret_value(term, client,\n                                              version_stage=version_stage, version_id=version_id,\n                                              on_missing=missing, on_denied=denied, nested=nested)\n                if value:\n                    secrets.append(value)\n            if join:\n                joined_secret = []\n                joined_secret.append(''.join(secrets))\n                return joined_secret\n\n        return secrets\n\n    def get_secret_value(self, term, client, version_stage=None, version_id=None, on_missing=None, on_denied=None, nested=False):\n        params = {}\n        params['SecretId'] = term\n        if version_id:\n            params['VersionId'] = version_id\n        if version_stage:\n            params['VersionStage'] = version_stage\n        if nested:\n            if len(term.split('.')) < 2:\n                raise AnsibleError(\"Nested query must use the following syntax: `aws_secret_name.<key_name>.<key_name>\")\n            secret_name = term.split('.')[0]\n            params['SecretId'] = secret_name\n\n        try:\n            response = client.get_secret_value(**params)\n            if 'SecretBinary' in response:\n                return response['SecretBinary']\n            if 'SecretString' in response:\n                if nested:\n                    secrets = []\n                    query = term.split('.')[1:]\n                    secret_string = json.loads(response['SecretString'])\n                    ret_val = secret_string\n                    for key in query:\n                        if key in ret_val:\n                            ret_val = ret_val[key]\n                        else:\n                            raise AnsibleError(\"Successfully retrieved secret but there exists no key {0} in the secret\".format(key))\n                    return str(ret_val)\n                else:\n                    return response['SecretString']\n        except is_boto3_error_code('ResourceNotFoundException'):\n            if on_missing == 'error':\n                raise AnsibleError(\"Failed to find secret %s (ResourceNotFound)\" % term)\n            elif on_missing == 'warn':\n                self._display.warning('Skipping, did not find secret %s' % term)\n        except is_boto3_error_code('AccessDeniedException'):  # pylint: disable=duplicate-except\n            if on_denied == 'error':\n                raise AnsibleError(\"Failed to access secret %s (AccessDenied)\" % term)\n            elif on_denied == 'warn':\n                self._display.warning('Skipping, access denied for secret %s' % term)\n        except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:  # pylint: disable=duplicate-except\n            raise AnsibleError(\"Failed to retrieve secret: %s\" % to_native(e))\n\n        return None\n", "path": "plugins/lookup/aws_secret.py"}], "after_files": [{"content": "# Copyright: (c) 2018, Aaron Smith <ajsmith10381@gmail.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\nDOCUMENTATION = r'''\nlookup: aws_secret\nauthor:\n  - Aaron Smith <ajsmith10381@gmail.com>\nrequirements:\n  - python >= 3.6\n  - boto3\n  - botocore >= 1.16.0\nextends_documentation_fragment:\n- amazon.aws.aws_credentials\n- amazon.aws.aws_region\n\nshort_description: Look up secrets stored in AWS Secrets Manager.\ndescription:\n  - Look up secrets stored in AWS Secrets Manager provided the caller\n    has the appropriate permissions to read the secret.\n  - Lookup is based on the secret's I(Name) value.\n  - Optional parameters can be passed into this lookup; I(version_id) and I(version_stage)\noptions:\n  _terms:\n    description: Name of the secret to look up in AWS Secrets Manager.\n    required: True\n  bypath:\n    description: A boolean to indicate whether the parameter is provided as a hierarchy.\n    default: false\n    type: boolean\n    version_added: 1.4.0\n  nested:\n    description: A boolean to indicate the secret contains nested values.\n    type: boolean\n    default: false\n    version_added: 1.4.0\n  version_id:\n    description: Version of the secret(s).\n    required: False\n  version_stage:\n    description: Stage of the secret version.\n    required: False\n  join:\n    description:\n        - Join two or more entries to form an extended secret.\n        - This is useful for overcoming the 4096 character limit imposed by AWS.\n        - No effect when used with I(bypath).\n    type: boolean\n    default: false\n  on_missing:\n    description:\n        - Action to take if the secret is missing.\n        - C(error) will raise a fatal error when the secret is missing.\n        - C(skip) will silently ignore the missing secret.\n        - C(warn) will skip over the missing secret but issue a warning.\n    default: error\n    type: string\n    choices: ['error', 'skip', 'warn']\n  on_denied:\n    description:\n        - Action to take if access to the secret is denied.\n        - C(error) will raise a fatal error when access to the secret is denied.\n        - C(skip) will silently ignore the denied secret.\n        - C(warn) will skip over the denied secret but issue a warning.\n    default: error\n    type: string\n    choices: ['error', 'skip', 'warn']\n'''\n\nEXAMPLES = r\"\"\"\n - name: lookup secretsmanager secret in the current region\n   debug: msg=\"{{ lookup('amazon.aws.aws_secret', '/path/to/secrets', bypath=true) }}\"\n\n - name: Create RDS instance with aws_secret lookup for password param\n   rds:\n     command: create\n     instance_name: app-db\n     db_engine: MySQL\n     size: 10\n     instance_type: db.m1.small\n     username: dbadmin\n     password: \"{{ lookup('amazon.aws.aws_secret', 'DbSecret') }}\"\n     tags:\n       Environment: staging\n\n - name: skip if secret does not exist\n   debug: msg=\"{{ lookup('amazon.aws.aws_secret', 'secret-not-exist', on_missing='skip')}}\"\n\n - name: warn if access to the secret is denied\n   debug: msg=\"{{ lookup('amazon.aws.aws_secret', 'secret-denied', on_denied='warn')}}\"\n\n - name: lookup secretsmanager secret in the current region using the nested feature\n   debug: msg=\"{{ lookup('amazon.aws.aws_secret', 'secrets.environments.production.password', nested=true) }}\"\n   # The secret can be queried using the following syntax: `aws_secret_object_name.key1.key2.key3`.\n   # If an object is of the form `{\"key1\":{\"key2\":{\"key3\":1}}}` the query would return the value `1`.\n - name: lookup secretsmanager secret in a specific region using specified region and aws profile using nested feature\n   debug: >\n    msg=\"{{ lookup('amazon.aws.aws_secret', 'secrets.environments.production.password', region=region, aws_profile=aws_profile,\n    aws_access_key=aws_access_key, aws_secret_key=aws_secret_key, nested=true) }}\"\n   # The secret can be queried using the following syntax: `aws_secret_object_name.key1.key2.key3`.\n   # If an object is of the form `{\"key1\":{\"key2\":{\"key3\":1}}}` the query would return the value `1`.\n   # Region is the AWS region where the AWS secret is stored.\n   # AWS_profile is the aws profile to use, that has access to the AWS secret.\n\"\"\"\n\nRETURN = r\"\"\"\n_raw:\n  description:\n    Returns the value of the secret stored in AWS Secrets Manager.\n\"\"\"\n\nimport json\n\ntry:\n    import boto3\n    import botocore\nexcept ImportError:\n    pass  # will be captured by imported HAS_BOTO3\n\nfrom ansible.errors import AnsibleError\nfrom ansible.module_utils.six import string_types\nfrom ansible.module_utils._text import to_native\nfrom ansible.plugins.lookup import LookupBase\n\nfrom ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code\nfrom ansible_collections.amazon.aws.plugins.module_utils.ec2 import HAS_BOTO3\n\n\ndef _boto3_conn(region, credentials):\n    boto_profile = credentials.pop('aws_profile', None)\n\n    try:\n        connection = boto3.session.Session(profile_name=boto_profile).client('secretsmanager', region, **credentials)\n    except (botocore.exceptions.ProfileNotFound, botocore.exceptions.PartialCredentialsError) as e:\n        if boto_profile:\n            try:\n                connection = boto3.session.Session(profile_name=boto_profile).client('secretsmanager', region)\n            except (botocore.exceptions.ProfileNotFound, botocore.exceptions.PartialCredentialsError) as e:\n                raise AnsibleError(\"Insufficient credentials found.\")\n        else:\n            raise AnsibleError(\"Insufficient credentials found.\")\n    return connection\n\n\nclass LookupModule(LookupBase):\n    def run(self, terms, variables=None, boto_profile=None, aws_profile=None,\n            aws_secret_key=None, aws_access_key=None, aws_security_token=None, region=None,\n            bypath=False, nested=False, join=False, version_stage=None, version_id=None, on_missing='error',\n            on_denied='error'):\n        '''\n                   :arg terms: a list of lookups to run.\n                       e.g. ['parameter_name', 'parameter_name_too' ]\n                   :kwarg variables: ansible variables active at the time of the lookup\n                   :kwarg aws_secret_key: identity of the AWS key to use\n                   :kwarg aws_access_key: AWS secret key (matching identity)\n                   :kwarg aws_security_token: AWS session key if using STS\n                   :kwarg decrypt: Set to True to get decrypted parameters\n                   :kwarg region: AWS region in which to do the lookup\n                   :kwarg bypath: Set to True to do a lookup of variables under a path\n                   :kwarg nested: Set to True to do a lookup of nested secrets\n                   :kwarg join: Join two or more entries to form an extended secret\n                   :kwarg version_stage: Stage of the secret version\n                   :kwarg version_id: Version of the secret(s)\n                   :kwarg on_missing: Action to take if the secret is missing\n                   :kwarg on_denied: Action to take if access to the secret is denied\n                   :returns: A list of parameter values or a list of dictionaries if bypath=True.\n               '''\n        if not HAS_BOTO3:\n            raise AnsibleError('botocore and boto3 are required for aws_ssm lookup.')\n\n        missing = on_missing.lower()\n        if not isinstance(missing, string_types) or missing not in ['error', 'warn', 'skip']:\n            raise AnsibleError('\"on_missing\" must be a string and one of \"error\", \"warn\" or \"skip\", not %s' % missing)\n\n        denied = on_denied.lower()\n        if not isinstance(denied, string_types) or denied not in ['error', 'warn', 'skip']:\n            raise AnsibleError('\"on_denied\" must be a string and one of \"error\", \"warn\" or \"skip\", not %s' % denied)\n\n        credentials = {}\n        if aws_profile:\n            credentials['aws_profile'] = aws_profile\n        else:\n            credentials['aws_profile'] = boto_profile\n        credentials['aws_secret_access_key'] = aws_secret_key\n        credentials['aws_access_key_id'] = aws_access_key\n        credentials['aws_session_token'] = aws_security_token\n\n        # fallback to IAM role credentials\n        if not credentials['aws_profile'] and not (\n                credentials['aws_access_key_id'] and credentials['aws_secret_access_key']):\n            session = botocore.session.get_session()\n            if session.get_credentials() is not None:\n                credentials['aws_access_key_id'] = session.get_credentials().access_key\n                credentials['aws_secret_access_key'] = session.get_credentials().secret_key\n                credentials['aws_session_token'] = session.get_credentials().token\n\n        client = _boto3_conn(region, credentials)\n\n        if bypath:\n            secrets = {}\n            for term in terms:\n                try:\n                    response = client.list_secrets(Filters=[{'Key': 'name', 'Values': [term]}])\n\n                    if 'SecretList' in response:\n                        for secret in response['SecretList']:\n                            secrets.update({secret['Name']: self.get_secret_value(secret['Name'], client,\n                                                                                  on_missing=missing,\n                                                                                  on_denied=denied)})\n                except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:\n                    raise AnsibleError(\"Failed to retrieve secret: %s\" % to_native(e))\n            secrets = [secrets]\n        else:\n            secrets = []\n            for term in terms:\n                value = self.get_secret_value(term, client,\n                                              version_stage=version_stage, version_id=version_id,\n                                              on_missing=missing, on_denied=denied, nested=nested)\n                if value:\n                    secrets.append(value)\n            if join:\n                joined_secret = []\n                joined_secret.append(''.join(secrets))\n                return joined_secret\n\n        return secrets\n\n    def get_secret_value(self, term, client, version_stage=None, version_id=None, on_missing=None, on_denied=None, nested=False):\n        params = {}\n        params['SecretId'] = term\n        if version_id:\n            params['VersionId'] = version_id\n        if version_stage:\n            params['VersionStage'] = version_stage\n        if nested:\n            if len(term.split('.')) < 2:\n                raise AnsibleError(\"Nested query must use the following syntax: `aws_secret_name.<key_name>.<key_name>\")\n            secret_name = term.split('.')[0]\n            params['SecretId'] = secret_name\n\n        try:\n            response = client.get_secret_value(**params)\n            if 'SecretBinary' in response:\n                return response['SecretBinary']\n            if 'SecretString' in response:\n                if nested:\n                    secrets = []\n                    query = term.split('.')[1:]\n                    secret_string = json.loads(response['SecretString'])\n                    ret_val = secret_string\n                    for key in query:\n                        if key in ret_val:\n                            ret_val = ret_val[key]\n                        else:\n                            raise AnsibleError(\"Successfully retrieved secret but there exists no key {0} in the secret\".format(key))\n                    return str(ret_val)\n                else:\n                    return response['SecretString']\n        except is_boto3_error_code('ResourceNotFoundException'):\n            if on_missing == 'error':\n                raise AnsibleError(\"Failed to find secret %s (ResourceNotFound)\" % term)\n            elif on_missing == 'warn':\n                self._display.warning('Skipping, did not find secret %s' % term)\n        except is_boto3_error_code('AccessDeniedException'):  # pylint: disable=duplicate-except\n            if on_denied == 'error':\n                raise AnsibleError(\"Failed to access secret %s (AccessDenied)\" % term)\n            elif on_denied == 'warn':\n                self._display.warning('Skipping, access denied for secret %s' % term)\n        except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:  # pylint: disable=duplicate-except\n            raise AnsibleError(\"Failed to retrieve secret: %s\" % to_native(e))\n\n        return None\n", "path": "plugins/lookup/aws_secret.py"}]}