diff --git a/lib/ansible/modules/cloud/amazon/ssm_parameter_store.py b/lib/ansible/modules/cloud/amazon/ssm_parameter_store.py
new file mode 100644
index 0000000000..2419731866
--- /dev/null
+++ b/lib/ansible/modules/cloud/amazon/ssm_parameter_store.py
@@ -0,0 +1,220 @@
+#!/usr/bin/python
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see .
+ANSIBLE_METADATA = {'status': ['preview'],
+ 'supported_by': 'community',
+ 'metadata_version': '1.1'}
+
+DOCUMENTATION = '''
+---
+module: ssm_parameter_store
+short_description: Manage key-value pairs in aws parameter store.
+description:
+ - Manage key-value pairs in aws parameter store.
+version_added: "2.5"
+options:
+ name:
+ description:
+ - parameter key name.
+ required: true
+ description:
+ description:
+ - parameter key desciption.
+ required: false
+ value:
+ description:
+ - Parameter value.
+ required: false
+ state:
+ description:
+ - Creates or modifies an existing parameter
+ - Deletes a parameter
+ required: false
+ choices: ['present', 'absent']
+ default: present
+ string_type:
+ description:
+ - Parameter String type
+ required: false
+ choices: ['String', 'StringList', 'SecureString']
+ default: String
+ decryption:
+ description:
+ - Work with SecureString type to get plain text secrets
+ - Boolean
+ required: false
+ default: True
+ key_id:
+ description:
+ - aws KMS key to decrypt the secrets.
+ required: false
+ default: aws/ssm (this key is automatically generated at the first parameter created).
+ overwrite:
+ description:
+ - Overwrite the value when create or update parameter
+ - Boolean
+ required: false
+ default: True
+ region:
+ description:
+ - region.
+ required: false
+author: Bill Wang (ozbillwang@gmail.com)
+extends_documentation_fragment: aws
+requirements: [ botocore, boto3 ]
+'''
+
+EXAMPLES = '''
+- name: Create or update key/value pair in aws parameter store
+ ssm_parameter_store:
+ name: "Hello"
+ description: "This is your first key"
+ value: "World"
+
+- name: Delete the key
+ ssm_parameter_store:
+ name: "Hello"
+ state: absent
+
+- name: Create or update secure key/value pair with default kms key (aws/ssm)
+ ssm_parameter_store:
+ name: "Hello"
+ description: "This is your first key"
+ string_type: "SecureString"
+ value: "World"
+
+- name: Create or update secure key/value pair with nominated kms key
+ ssm_parameter_store:
+ name: "Hello"
+ description: "This is your first key"
+ string_type: "SecureString"
+ key_id: "alias/demo"
+ value: "World"
+
+- name: recommend to use with ssm lookup plugin
+ debug: msg="{{ lookup('ssm', 'hello') }}"
+'''
+
+RETURN = '''
+put_parameter:
+ description: Add one or more paramaters to the system.
+ returned: success
+ type: dictionary
+delete_parameter:
+ description: Delete a parameter from the system.
+ returned: success
+ type: dictionary
+'''
+
+import traceback
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.ec2 import HAS_BOTO3, camel_dict_to_snake_dict
+from ansible.module_utils.ec2 import boto3_conn, ec2_argument_spec, get_aws_connection_info
+
+try:
+ from botocore.exceptions import ClientError, NoCredentialsError
+except ImportError:
+ pass # will be captured by imported HAS_BOTO3
+
+
+def create_update_parameter(client, module):
+ changed = False
+ response = {}
+
+ args = dict(
+ Name=module.params.get('name'),
+ Value=module.params.get('value'),
+ Type=module.params.get('string_type'),
+ Overwrite=module.params.get('overwrite')
+ )
+
+ if module.params.get('description'):
+ args.update(Description=module.params.get('description'))
+
+ if module.params.get('string_type') == 'SecureString':
+ args.update(KeyId=module.params.get('key_id'))
+
+ try:
+ response = client.put_parameter(**args)
+ changed = True
+ except ClientError as e:
+ module.fail_json(msg=e.message, exception=traceback.format_exc(),
+ **camel_dict_to_snake_dict(e.response))
+
+ return changed, response
+
+
+def delete_parameter(client, module):
+ changed = False
+ response = {}
+
+ try:
+ get_response = client.get_parameters(
+ Names=[module.params.get('name')]
+ )
+ except ClientError as e:
+ module.fail_json(msg=e.message, exception=traceback.format_exc(),
+ **camel_dict_to_snake_dict(e.response))
+
+ if get_response['Parameters']:
+ try:
+ response = client.delete_parameter(
+ Name=module.params.get('name')
+ )
+ changed = True
+ except ClientError as e:
+ module.fail_json(msg=e.message, exception=traceback.format_exc(),
+ **camel_dict_to_snake_dict(e.response))
+
+ return changed, response
+
+
+def main():
+
+ argument_spec = ec2_argument_spec()
+ argument_spec.update(
+ dict(
+ name=dict(required=True),
+ description=dict(),
+ value=dict(required=False),
+ state=dict(default='present', choices=['present', 'absent']),
+ string_type=dict(default='String', choices=['String', 'StringList', 'SecureString']),
+ decryption=dict(default=True, type='bool'),
+ key_id=dict(default="alias/aws/ssm"),
+ overwrite=dict(default=True, type='bool'),
+ region=dict(required=False),
+ )
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec)
+
+ if not HAS_BOTO3:
+ module.fail_json(msg='boto3 are required.')
+ state = module.params.get('state')
+ try:
+ region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True)
+ client = boto3_conn(module, conn_type='client', resource='ssm', region=region, endpoint=ec2_url, **aws_connect_kwargs)
+ except NoCredentialsError as e:
+ module.fail_json(msg="Can't authorize connection - %s" % str(e))
+
+ invocations = {
+ "present": create_update_parameter,
+ "absent": delete_parameter,
+ }
+ (changed, response) = invocations[state](client, module)
+ module.exit_json(changed=changed, response=response)
+
+if __name__ == '__main__':
+ main()
diff --git a/lib/ansible/plugins/lookup/ssm.py b/lib/ansible/plugins/lookup/ssm.py
new file mode 100644
index 0000000000..5fa4ebd3c9
--- /dev/null
+++ b/lib/ansible/plugins/lookup/ssm.py
@@ -0,0 +1,98 @@
+# (c) 2016, Bill Wang
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see .
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+from ansible.module_utils.ec2 import HAS_BOTO3
+from ansible.errors import AnsibleError
+from ansible.plugins.lookup import LookupBase
+
+try:
+ from botocore.exceptions import ClientError
+ import boto3
+except ImportError:
+ pass # will be captured by imported HAS_BOTO3
+
+
+class LookupModule(LookupBase):
+ def run(self, terms, variables, **kwargs):
+ '''
+ # lookup sample:
+ - name: lookup ssm parameter store in the current region
+ debug: msg="{{ lookup('ssm', 'Hello' ) }}"
+
+ - name: lookup a key which doesn't exist, return ""
+ debug: msg="{{ lookup('ssm', 'NoKey') }}"
+
+ - name: lookup ssm parameter store in nominated region
+ debug: msg="{{ lookup('ssm', 'Hello', 'region=us-east-2' ) }}"
+
+ - name: lookup ssm parameter store without decrypted
+ debug: msg="{{ lookup('ssm', 'Hello', 'decrypt=False' ) }}"
+
+ - name: lookup ssm parameter store in nominated aws profile
+ debug: msg="{{ lookup('ssm', 'Hello', 'aws_profile=myprofile' ) }}"
+
+ - name: lookup ssm parameter store with all options.
+ debug: msg="{{ lookup('ssm', 'Hello', 'decrypt=false', 'region=us-east-2', 'aws_profile=myprofile') }}"
+ '''
+
+ ret = {}
+ response = {}
+ session = {}
+ ssm_dict = {}
+
+ if not HAS_BOTO3:
+ raise AnsibleError('botocore and boto3 are required.')
+
+ ssm_dict['WithDecryption'] = True
+ ssm_dict['Names'] = [terms[0]]
+
+ if len(terms) > 1:
+ for param in terms[1:]:
+ if "=" in param:
+ key, value = param.split('=')
+ else:
+ raise AnsibleError("ssm parameter store plugin needs key=value pairs, but received %s" % param)
+
+ if key == "region" or key == "aws_profile":
+ session[key] = value
+
+ # decrypt the value or not
+ if key == "decrypt" and value.lower() == "false":
+ ssm_dict['WithDecryption'] = False
+
+ if "aws_profile" in session:
+ boto3.setup_default_session(profile_name=session['aws_profile'])
+
+ if "region" in session:
+ client = boto3.client('ssm', region_name=session['region'])
+ else:
+ client = boto3.client('ssm')
+
+ try:
+ response = client.get_parameters(**ssm_dict)
+ except ClientError as e:
+ raise AnsibleError("SSM lookup exception: {0}".format(e))
+
+ ret.update(response)
+
+ if ret['Parameters']:
+ return [ret['Parameters'][0]['Value']]
+ else:
+ return None