Skip to content

Instantly share code, notes, and snippets.

@danwashusen
Created September 1, 2022 04:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danwashusen/52130c8568d6809d4d40e39918bcfec4 to your computer and use it in GitHub Desktop.
Save danwashusen/52130c8568d6809d4d40e39918bcfec4 to your computer and use it in GitHub Desktop.
A very simple Ansible module to send IAM v4 signed requests to an OpenSearch domain
#!/usr/bin/python3
# NOTE: must be in the ./library directory
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible.module_utils.basic import AnsibleModule
from requests_aws4auth import AWS4Auth
from botocore.session import Session
import requests
import json
def run_module():
module_args = dict(
url=dict(type='str', required=True),
method=dict(type='str', default='GET'),
region=dict(type='str', required=True),
payload=dict(type='dict', default=None),
expected_status_codes=dict(type='list', default=[200])
)
result = dict(
changed=False,
status_code=0,
status_reason='',
response=None,
error=None,
)
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=False,
)
credentials = Session().get_credentials()
auth = AWS4Auth(region=module.params['region'], service='es', refreshable_credentials=credentials)
url = module.params['url']
response = requests.request(module.params['method'], url, json=module.params['payload'], timeout=30, auth=auth)
result['status_code'] = response.status_code
result['status_reason'] = response.reason
if response.status_code in module.params['expected_status_codes']:
if module.params['method'] in ['POST', 'PUT', 'PATCH', 'DELETE']:
result['changed'] = True
result['response'] = json.loads(response.text)
module.exit_json(**result)
else:
result['error'] = response.text
module.fail_json(msg=str(response.status_code) + ': ' + response.reason, **result)
def main():
run_module()
if __name__ == '__main__':
main()
---
- name: Provision a index
hosts: "*"
become: false
vars:
endpoint: "your.opensearch.endpoint.amazonaws.com"
ops_role: "arn:aws:iam::12345678:role/RollAllowedToInteractWithOpensearch"
tasks:
- name: Install the required dependcies
ansible.builtin.pip:
name:
- botocore
- boto3
- requests
- requests-aws4auth
- python-dateutil
- pytz
umask: '0022'
state: present
become: true
- name: Fetch credentials to use while provisioning
community.aws.sts_assume_role:
role_arn: "{{ ops_role }}"
role_session_name: "opensearch-provisioning"
duration_seconds: 900
register: assume_role_output
changed_when: false
- name: Setup the index
block:
- name: Check if the index exists
iam_opensearch_request:
url: "https://{{ endpoint }}/{{ index_name }}"
expected_status_codes:
- 200
- 404
region: us-west-1
register: check_index_response
changed_when: false
environment:
AWS_ACCESS_KEY_ID: "{{ assume_role_output.sts_creds.access_key }}"
AWS_SECRET_ACCESS_KEY: "{{ assume_role_output.sts_creds.secret_key }}"
AWS_SESSION_TOKEN: "{{ assume_role_output.sts_creds.session_token }}"
- name: Create the index if its missing
iam_opensearch_request:
url: "https://{{ endpoint }}/{{ index_name }}"
method: PUT
payload: "{{ lookup('ansible.builtin.file', 'schema/search/buckets.json') | from_json }}"
region: us-west-1
when: check_index_response.status_code == 404
environment:
AWS_ACCESS_KEY_ID: "{{ assume_role_output.sts_creds.access_key }}"
AWS_SECRET_ACCESS_KEY: "{{ assume_role_output.sts_creds.secret_key }}"
AWS_SESSION_TOKEN: "{{ assume_role_output.sts_creds.session_token }}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment