Repository: ansible/ansible

Issue:
ec2 rds postgres creation fails with error: Failed to create instance: null
##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report

##### COMPONENT NAME
rds module

##### ANSIBLE VERSION
```
ansible 2.3.0.0
  config file = /home/jmcginn/workspaces/askrail-infrastructure/ansible.cfg
  configured module search path = Default w/o overrides
  python version = 2.7.5 (default, Nov  6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]
```

##### CONFIGURATION
[defaults]
inventory = inventory

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=30m -F ./.ssh_config
control_path = ~/.ssh/ansible-%%r@%%h:%%p

Plus standard AWS environment variables for credentials

##### OS / ENVIRONMENT
Centos 7
Linux version 3.10.0-514.16.1.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) ) #1 SMP Wed Apr 12 15:04:24 UTC 2017

##### SUMMARY
Automating creation of environment in AWS - trying to create postgres database after creating vpc, subnets, security groups, gateways, route tables, ec2 instances, etc.

##### STEPS TO REPRODUCE
Using ec2.py for dynamic inventory
Set ec2.ini to use private IP & DNS
destination_variable = private_dns_name
vpc_destination_variable = private_ip_address

<!--- Paste example playbooks or commands between quotes below -->
Main playbook that invokes roles (following plays omitted)
```yaml
---
- name: Test region network configuration and bastion instance creation
  hosts: localhost
  connection: local
  gather_facts: false
  vars:
    vpc_name: "railinc-aws-test-vpc"
    vpc_cidr_block: "172.35.0.0/16"
    env: "test"
    bastion_hosts_to_proxy: "172.35.*.*"
    public_subnets: 
      - cidr: "172.35.0.0/22"
        az: "us-east-1a"
      - cidr: "172.35.4.0/22"
        az: "us-east-1b"
    private_subnets:
      - cidr: "172.35.16.0/22"
        az: "us-east-1a"
      - cidr: "172.35.32.0/22"
        az: "us-east-1b"
  roles:
    - vpc
    - askrail-infrastructure
```
role defaults for askrail-infrastructure
```yaml
---
# Global default settings
region:                   "us-east-1"

# askrail server instance defaults
askrail_instances_per_az:        1
askrail_server_ami:              "ami-6d1c2007" 
askrail_server_instance_type:    "t2.micro"
askrail_server_key_pair:         "{{ my_key_pair }}"

# askrail server instance volume specs /dev/sda1
askrail_default_volume_type:     "gp2"
askrail_default_volume_size:     8
askrail_default_volume_delete_on_term: yes

# askrail database defaults
database_port:                   5432
database_engine_version:         "9.6.1"
database_instance_class:         "db.t2.small"
database_size:                   20
database_multizone:              no
database_backup_retention_days:  7
database_availability_zone:      "us-east-1a"
```
task for creating rds postgres instance (verified all dependent resources exist - vpc, subnets, db subnet group, security groups). I have played around with different values for engine version and also took the value out completely since the docs are unclear what value should be used.
```yaml
- name:                   "Create askrail database"
  rds:
    command:              "create"
    region:               "{{ region }}"
    instance_name:        "askrail-{{ env }}-db"
    instance_type:        "{{ database_instance_class }}"
    subnet:               "railinc-aws-{{ env }}-db-subnet-grp-01"
    zone:                 "{{ database_availability_zone }}"
    port:                 "{{ database_port }} "
    db_engine:            postgres
    size:                 "{{ database_size }}"
    db_name:              "askrail"
    username:             "railinc"
    password:             "xxxxxxxxxxx"
    license_model:        postgresql-license
    multi_zone:           "{{ database_multizone }}"
    backup_retention:     "{{ database_backup_retention_days }}"
    upgrade:              yes 
    vpc_security_groups:  "{{ postgres_railinc_sec_grp.group_id }}"
    wait:                 yes
```
##### EXPECTED RESULTS
postgres instance to be created and running

##### ACTUAL RESULTS
```
Error results
```
Using module file /usr/lib/python2.7/site-packages/ansible/modules/cloud/amazon/rds.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: jmcginn
<127.0.0.1> EXEC /bin/sh -c 'echo ~ && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/jmcginn/.ansible/tmp/ansible-tmp-1495153256.36-108353162371443 `" && echo ansible-tmp-1495153256.36-108353162371443="` echo /home/jmcginn/.ansible/tmp/ansible-tmp-1495153256.36-108353162371443 `" ) && sleep 0'                                                                                                             
<127.0.0.1> PUT /tmp/tmpz0LtYq TO /home/jmcginn/.ansible/tmp/ansible-tmp-1495153256.36-108353162371443/rds.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/jmcginn/.ansible/tmp/ansible-tmp-1495153256.36-108353162371443/ /home/jmcginn/.ansible/tmp/ansible-tmp-1495153256.36-108353162371443/rds.py && sleep 0'                                                            
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2 /home/jmcginn/.ansible/tmp/ansible-tmp-1495153256.36-108353162371443/rds.py; rm -rf "/home/jmcginn/.ansible/tmp/ansible-tmp-1495153256.36-108353162371443/" > /dev/null 2>&1 && sleep 0'                          
fatal: [localhost]: FAILED! => {
    "changed": false, 
    "failed": true, 
    "invocation": {
        "module_args": {
            "apply_immediately": false, 
            "aws_access_key": null, 
            "aws_secret_key": null, 
            "backup_retention": "7", 
            "backup_window": null, 
            "character_set_name": null, 
            "command": "create", 
            "db_engine": "postgres", 
            "db_name": "askrail", 
            "ec2_url": null, 
            "engine_version": null, 
            "force_failover": false, 
            "instance_name": "askrail-test-db", 
            "instance_type": "db.t2.small", 
            "iops": null, 
            "license_model": "postgresql-license", 
            "maint_window": null, 
            "multi_zone": false, 
            "new_instance_name": null, 
            "option_group": null, 
            "parameter_group": null, 
            "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", 
            "port": "5432 ", 
            "profile": null, 
            "publicly_accessible": null, 
            "region": "us-east-1", 
            "security_groups": null, 
            "security_token": null, 
            "size": "20", 
            "snapshot": null, 
            "source_instance": null, 
            "subnet": "railinc-aws-test-db-subnet-grp-01", 
            "tags": null, 
            "upgrade": true, 
            "username": "railinc", 
            "validate_certs": true, 
            "vpc_security_groups": [
                "sg-322c6a4c"
            ], 
            "wait": true, 
            "wait_timeout": 300, 
            "zone": "us-east-1a"
        }
    }, 
    "msg": "Failed to create instance: null"

```

```

ec2 rds postgres creation fails with error: Failed to create instance: null
##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report

##### COMPONENT NAME
rds module

##### ANSIBLE VERSION
```
ansible 2.3.0.0
  config file = /home/jmcginn/workspaces/askrail-infrastructure/ansible.cfg
  configured module search path = Default w/o overrides
  python version = 2.7.5 (default, Nov  6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]
```

##### CONFIGURATION
[defaults]
inventory = inventory

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=30m -F ./.ssh_config
control_path = ~/.ssh/ansible-%%r@%%h:%%p

Plus standard AWS environment variables for credentials

##### OS / ENVIRONMENT
Centos 7
Linux version 3.10.0-514.16.1.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) ) #1 SMP Wed Apr 12 15:04:24 UTC 2017

##### SUMMARY
Automating creation of environment in AWS - trying to create postgres database after creating vpc, subnets, security groups, gateways, route tables, ec2 instances, etc.

##### STEPS TO REPRODUCE
Using ec2.py for dynamic inventory
Set ec2.ini to use private IP & DNS
destination_variable = private_dns_name
vpc_destination_variable = private_ip_address

<!--- Paste example playbooks or commands between quotes below -->
Main playbook that invokes roles (following plays omitted)
```yaml
---
- name: Test region network configuration and bastion instance creation
  hosts: localhost
  connection: local
  gather_facts: false
  vars:
    vpc_name: "railinc-aws-test-vpc"
    vpc_cidr_block: "172.35.0.0/16"
    env: "test"
    bastion_hosts_to_proxy: "172.35.*.*"
    public_subnets: 
      - cidr: "172.35.0.0/22"
        az: "us-east-1a"
      - cidr: "172.35.4.0/22"
        az: "us-east-1b"
    private_subnets:
      - cidr: "172.35.16.0/22"
        az: "us-east-1a"
      - cidr: "172.35.32.0/22"
        az: "us-east-1b"
  roles:
    - vpc
    - askrail-infrastructure
```
role defaults for askrail-infrastructure
```yaml
---
# Global default settings
region:                   "us-east-1"

# askrail server instance defaults
askrail_instances_per_az:        1
askrail_server_ami:              "ami-6d1c2007" 
askrail_server_instance_type:    "t2.micro"
askrail_server_key_pair:         "{{ my_key_pair }}"

# askrail server instance volume specs /dev/sda1
askrail_default_volume_type:     "gp2"
askrail_default_volume_size:     8
askrail_default_volume_delete_on_term: yes

# askrail database defaults
database_port:                   5432
database_engine_version:         "9.6.1"
database_instance_class:         "db.t2.small"
database_size:                   20
database_multizone:              no
database_backup_retention_days:  7
database_availability_zone:      "us-east-1a"
```
task for creating rds postgres instance (verified all dependent resources exist - vpc, subnets, db subnet group, security groups). I have played around with different values for engine version and also took the value out completely since the docs are unclear what value should be used.
```yaml
- name:                   "Create askrail database"
  rds:
    command:              "create"
    region:               "{{ region }}"
    instance_name:        "askrail-{{ env }}-db"
    instance_type:        "{{ database_instance_class }}"
    subnet:               "railinc-aws-{{ env }}-db-subnet-grp-01"
    zone:                 "{{ database_availability_zone }}"
    port:                 "{{ database_port }} "
    db_engine:            postgres
    size:                 "{{ database_size }}"
    db_name:              "askrail"
    username:             "railinc"
    password:             "xxxxxxxxxxx"
    license_model:        postgresql-license
    multi_zone:           "{{ database_multizone }}"
    backup_retention:     "{{ database_backup_retention_days }}"
    upgrade:              yes 
    vpc_security_groups:  "{{ postgres_railinc_sec_grp.group_id }}"
    wait:                 yes
```
##### EXPECTED RESULTS
postgres instance to be created and running

##### ACTUAL RESULTS
```
Error results
```
Using module file /usr/lib/python2.7/site-packages/ansible/modules/cloud/amazon/rds.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: jmcginn
<127.0.0.1> EXEC /bin/sh -c 'echo ~ && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/jmcginn/.ansible/tmp/ansible-tmp-1495153256.36-108353162371443 `" && echo ansible-tmp-1495153256.36-108353162371443="` echo /home/jmcginn/.ansible/tmp/ansible-tmp-1495153256.36-108353162371443 `" ) && sleep 0'                                                                                                             
<127.0.0.1> PUT /tmp/tmpz0LtYq TO /home/jmcginn/.ansible/tmp/ansible-tmp-1495153256.36-108353162371443/rds.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/jmcginn/.ansible/tmp/ansible-tmp-1495153256.36-108353162371443/ /home/jmcginn/.ansible/tmp/ansible-tmp-1495153256.36-108353162371443/rds.py && sleep 0'                                                            
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2 /home/jmcginn/.ansible/tmp/ansible-tmp-1495153256.36-108353162371443/rds.py; rm -rf "/home/jmcginn/.ansible/tmp/ansible-tmp-1495153256.36-108353162371443/" > /dev/null 2>&1 && sleep 0'                          
fatal: [localhost]: FAILED! => {
    "changed": false, 
    "failed": true, 
    "invocation": {
        "module_args": {
            "apply_immediately": false, 
            "aws_access_key": null, 
            "aws_secret_key": null, 
            "backup_retention": "7", 
            "backup_window": null, 
            "character_set_name": null, 
            "command": "create", 
            "db_engine": "postgres", 
            "db_name": "askrail", 
            "ec2_url": null, 
            "engine_version": null, 
            "force_failover": false, 
            "instance_name": "askrail-test-db", 
            "instance_type": "db.t2.small", 
            "iops": null, 
            "license_model": "postgresql-license", 
            "maint_window": null, 
            "multi_zone": false, 
            "new_instance_name": null, 
            "option_group": null, 
            "parameter_group": null, 
            "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", 
            "port": "5432 ", 
            "profile": null, 
            "publicly_accessible": null, 
            "region": "us-east-1", 
            "security_groups": null, 
            "security_token": null, 
            "size": "20", 
            "snapshot": null, 
            "source_instance": null, 
            "subnet": "railinc-aws-test-db-subnet-grp-01", 
            "tags": null, 
            "upgrade": true, 
            "username": "railinc", 
            "validate_certs": true, 
            "vpc_security_groups": [
                "sg-322c6a4c"
            ], 
            "wait": true, 
            "wait_timeout": 300, 
            "zone": "us-east-1a"
        }
    }, 
    "msg": "Failed to create instance: null"

```

```



Discussion:
cc @bpennypacker @willthames
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Adding boto versions:
python2-boto.noarch                     2.45.0-3.el7                   @epel    
python2-boto3.noarch                    1.4.4-1.el7                    @epel    
python2-botocore.noarch                 1.5.26-1.el7                   @epel    
python-boto.noarch                      2.25.0-2.el7.centos            extras   

I originally installed ansible/boto via pip but rolled it all back and followed recommendation to use package manager (yum)
RDSException appears to be hiding the root cause:

```python
class RDSException(Exception):
    def __init__(self, exc):
        if hasattr(exc, 'error_message') and exc.error_message:
            self.message = exc.error_message
            self.code = exc.error_code
        elif hasattr(exc, 'body') and 'Error' in exc.body:
            #self.message = exc.body['Error']['Message']
            #self.code = exc.body['Error']['Code']
            self.message = str(exc.body)
            self.code = str(exc.body)
        else:
            self.message = str(exc)
            self.code = 'Unknown Error
```

When I change the commented out code as above I get the following error:
"msg": "Failed to create instance: {u'RequestId': u'0ed39b7d-3c92-11e7-bb9d-17d74eae2b02', u'Error': {u'Message': u'null', u'Code': u'MalformedInput', u'Type': u'Sender'}}"

So it appears boto may be submitting an invalid request?
I'm having trouble reproducing the error you're getting, but I think it may be because engine_version is shown in the invocation as null. This error message could definitely be improved. What happens if you run your task specifying `engine_version: "{{ database_engine_version }}"`?
Same :(, I had a hard time finding the correct version numbers to put in engine_version too. boto lists some in their output, but the actual version numbers on aws console has -RC2 on the end of it, I've tried several flavors of it though. The docs say engine_version can be null and it will use the default version, but I noticed AWS may have just recently changed their postgres default version, a few days ago it would default to a 9.5 version now it seems to default to the latest 9.6 version
```
Using module file /usr/lib/python2.7/site-packages/ansible/modules/cloud/amazon/rds.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: jmcginn
<127.0.0.1> EXEC /bin/sh -c 'echo ~ && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/jmcginn/.ansible/tmp/ansible-tmp-1495236302.2-274484842711964 `" && echo ansible-tmp-1495236302.2-274484842711964="` echo /home/jmcginn/.ansible/tmp/ansible-tmp-1495236302.2-274484842711964 `" ) && sleep 0'                                                                                                                
<127.0.0.1> PUT /tmp/tmpvxzY0D TO /home/jmcginn/.ansible/tmp/ansible-tmp-1495236302.2-274484842711964/rds.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/jmcginn/.ansible/tmp/ansible-tmp-1495236302.2-274484842711964/ /home/jmcginn/.ansible/tmp/ansible-tmp-1495236302.2-274484842711964/rds.py && sleep 0'                                                              
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2 /home/jmcginn/.ansible/tmp/ansible-tmp-1495236302.2-274484842711964/rds.py; rm -rf "/home/jmcginn/.ansible/tmp/ansible-tmp-1495236302.2-274484842711964/" > /dev/null 2>&1 && sleep 0'                            
fatal: [localhost]: FAILED! => {
    "changed": false, 
    "failed": true, 
    "invocation": {
        "module_args": {
            "apply_immediately": false, 
            "aws_access_key": null, 
            "aws_secret_key": null, 
            "backup_retention": "7", 
            "backup_window": null, 
            "character_set_name": null, 
            "command": "create", 
            "db_engine": "postgres", 
            "db_name": "askrail", 
            "ec2_url": null, 
            "engine_version": "9.6.2", 
            "force_failover": false, 
            "instance_name": "askrail-test-db2", 
            "instance_type": "db.t2.small", 
            "iops": null, 
            "license_model": "postgresql-license", 
            "maint_window": null, 
            "multi_zone": false, 
            "new_instance_name": null, 
            "option_group": null, 
            "parameter_group": null, 
            "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", 
            "port": "5432 ", 
            "profile": null, 
            "publicly_accessible": null, 
            "region": "us-east-1", 
            "security_groups": null, 
            "security_token": null, 
            "size": "20", 
            "snapshot": null, 
            "source_instance": null, 
            "subnet": "railinc-aws-test-db-subnet-grp-01", 
            "tags": null, 
            "upgrade": true, 
            "username": "railinc", 
            "validate_certs": false, 
            "vpc_security_groups": [
                "sg-322c6a4c"
            ], 
            "wait": true, 
            "wait_timeout": 300, 
            "zone": "us-east-1a"
        }
    }, 
    "msg": "Failed to create instance: {u'RequestId': u'62406378-3cea-11e7-8fb2-d97b800d85c1', u'Error': {u'Message': u'null', u'Code': u'MalformedInput', u'Type': u'Sender'}}"
```
Hm :( Thanks for the additional details. I'm able to create it if the engine_version is 9.3. I'll look at fixing this!
I just tried 9.3 and got the same error - appreciate the help
I have found the issue by turning on boto logging. I noticed the following in the create database post:
"Port":"5432 " <- notice quotes and extra space.

I was using a variable to set the port, changing this to a hardcoded value in my task fixed the malformed content error. 
Port: 5432

I'll try the int filter on the variable to see if that resolves the use of the variable and report back
Using the int filter resolved the issue so now my create db task looks like:
```
- name:                   "Create postgres database {{ database_name }} in subnet group {{ database_subnet_group_name }}"
  rds:
    command:              "create"
    region:               "{{ region }}"
    instance_name:        "{{ database_instance_name }}"
    instance_type:        "{{ database_instance_class }}"
    subnet:               "{{ database_subnet_group_name }}"
    zone:                 "{{ database_availability_zone }}"
    port:                 "{{database_port|int}}"
    db_engine:            postgres
    engine_version:       "{{ database_engine_version }}"
    size:                 "{{ database_size }}"
    db_name:              "{{ database_name}}"
    username:             "{{ database_user|default(database_master_user) }}"
    password:             "{{ database_password }}"
    license_model:        postgresql-license
    multi_zone:           "{{ database_multizone }}"
    backup_retention:     "{{ database_backup_retention_days }}"
    upgrade:              yes
    vpc_security_groups:  "{{ postgres_railinc_sec_grp.group_id }}"
    wait:                 yes
    wait_timeout:         1000
  register:               postgres_db
  notify:
    - "refresh inventory"
```
Ah!! Tricky. Thanks for sharing that.
cc @bpennypacker @willthames
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Adding boto versions:
python2-boto.noarch                     2.45.0-3.el7                   @epel    
python2-boto3.noarch                    1.4.4-1.el7                    @epel    
python2-botocore.noarch                 1.5.26-1.el7                   @epel    
python-boto.noarch                      2.25.0-2.el7.centos            extras   

I originally installed ansible/boto via pip but rolled it all back and followed recommendation to use package manager (yum)
RDSException appears to be hiding the root cause:

```python
class RDSException(Exception):
    def __init__(self, exc):
        if hasattr(exc, 'error_message') and exc.error_message:
            self.message = exc.error_message
            self.code = exc.error_code
        elif hasattr(exc, 'body') and 'Error' in exc.body:
            #self.message = exc.body['Error']['Message']
            #self.code = exc.body['Error']['Code']
            self.message = str(exc.body)
            self.code = str(exc.body)
        else:
            self.message = str(exc)
            self.code = 'Unknown Error
```

When I change the commented out code as above I get the following error:
"msg": "Failed to create instance: {u'RequestId': u'0ed39b7d-3c92-11e7-bb9d-17d74eae2b02', u'Error': {u'Message': u'null', u'Code': u'MalformedInput', u'Type': u'Sender'}}"

So it appears boto may be submitting an invalid request?
I'm having trouble reproducing the error you're getting, but I think it may be because engine_version is shown in the invocation as null. This error message could definitely be improved. What happens if you run your task specifying `engine_version: "{{ database_engine_version }}"`?
Same :(, I had a hard time finding the correct version numbers to put in engine_version too. boto lists some in their output, but the actual version numbers on aws console has -RC2 on the end of it, I've tried several flavors of it though. The docs say engine_version can be null and it will use the default version, but I noticed AWS may have just recently changed their postgres default version, a few days ago it would default to a 9.5 version now it seems to default to the latest 9.6 version
```
Using module file /usr/lib/python2.7/site-packages/ansible/modules/cloud/amazon/rds.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: jmcginn
<127.0.0.1> EXEC /bin/sh -c 'echo ~ && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/jmcginn/.ansible/tmp/ansible-tmp-1495236302.2-274484842711964 `" && echo ansible-tmp-1495236302.2-274484842711964="` echo /home/jmcginn/.ansible/tmp/ansible-tmp-1495236302.2-274484842711964 `" ) && sleep 0'                                                                                                                
<127.0.0.1> PUT /tmp/tmpvxzY0D TO /home/jmcginn/.ansible/tmp/ansible-tmp-1495236302.2-274484842711964/rds.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/jmcginn/.ansible/tmp/ansible-tmp-1495236302.2-274484842711964/ /home/jmcginn/.ansible/tmp/ansible-tmp-1495236302.2-274484842711964/rds.py && sleep 0'                                                              
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2 /home/jmcginn/.ansible/tmp/ansible-tmp-1495236302.2-274484842711964/rds.py; rm -rf "/home/jmcginn/.ansible/tmp/ansible-tmp-1495236302.2-274484842711964/" > /dev/null 2>&1 && sleep 0'                            
fatal: [localhost]: FAILED! => {
    "changed": false, 
    "failed": true, 
    "invocation": {
        "module_args": {
            "apply_immediately": false, 
            "aws_access_key": null, 
            "aws_secret_key": null, 
            "backup_retention": "7", 
            "backup_window": null, 
            "character_set_name": null, 
            "command": "create", 
            "db_engine": "postgres", 
            "db_name": "askrail", 
            "ec2_url": null, 
            "engine_version": "9.6.2", 
            "force_failover": false, 
            "instance_name": "askrail-test-db2", 
            "instance_type": "db.t2.small", 
            "iops": null, 
            "license_model": "postgresql-license", 
            "maint_window": null, 
            "multi_zone": false, 
            "new_instance_name": null, 
            "option_group": null, 
            "parameter_group": null, 
            "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", 
            "port": "5432 ", 
            "profile": null, 
            "publicly_accessible": null, 
            "region": "us-east-1", 
            "security_groups": null, 
            "security_token": null, 
            "size": "20", 
            "snapshot": null, 
            "source_instance": null, 
            "subnet": "railinc-aws-test-db-subnet-grp-01", 
            "tags": null, 
            "upgrade": true, 
            "username": "railinc", 
            "validate_certs": false, 
            "vpc_security_groups": [
                "sg-322c6a4c"
            ], 
            "wait": true, 
            "wait_timeout": 300, 
            "zone": "us-east-1a"
        }
    }, 
    "msg": "Failed to create instance: {u'RequestId': u'62406378-3cea-11e7-8fb2-d97b800d85c1', u'Error': {u'Message': u'null', u'Code': u'MalformedInput', u'Type': u'Sender'}}"
```
Hm :( Thanks for the additional details. I'm able to create it if the engine_version is 9.3. I'll look at fixing this!
I just tried 9.3 and got the same error - appreciate the help
I have found the issue by turning on boto logging. I noticed the following in the create database post:
"Port":"5432 " <- notice quotes and extra space.

I was using a variable to set the port, changing this to a hardcoded value in my task fixed the malformed content error. 
Port: 5432

I'll try the int filter on the variable to see if that resolves the use of the variable and report back
Using the int filter resolved the issue so now my create db task looks like:
```
- name:                   "Create postgres database {{ database_name }} in subnet group {{ database_subnet_group_name }}"
  rds:
    command:              "create"
    region:               "{{ region }}"
    instance_name:        "{{ database_instance_name }}"
    instance_type:        "{{ database_instance_class }}"
    subnet:               "{{ database_subnet_group_name }}"
    zone:                 "{{ database_availability_zone }}"
    port:                 "{{database_port|int}}"
    db_engine:            postgres
    engine_version:       "{{ database_engine_version }}"
    size:                 "{{ database_size }}"
    db_name:              "{{ database_name}}"
    username:             "{{ database_user|default(database_master_user) }}"
    password:             "{{ database_password }}"
    license_model:        postgresql-license
    multi_zone:           "{{ database_multizone }}"
    backup_retention:     "{{ database_backup_retention_days }}"
    upgrade:              yes
    vpc_security_groups:  "{{ postgres_railinc_sec_grp.group_id }}"
    wait:                 yes
    wait_timeout:         1000
  register:               postgres_db
  notify:
    - "refresh inventory"
```
Ah!! Tricky. Thanks for sharing that.

Resolving patch:
diff --git a/lib/ansible/modules/cloud/amazon/rds.py b/lib/ansible/modules/cloud/amazon/rds.py
--- a/lib/ansible/modules/cloud/amazon/rds.py
+++ b/lib/ansible/modules/cloud/amazon/rds.py
@@ -1084,7 +1084,7 @@ def main():
         iops=dict(required=False),
         security_groups=dict(required=False),
         vpc_security_groups=dict(type='list', required=False),
-        port=dict(required=False),
+        port=dict(required=False, type='int'),
         upgrade=dict(type='bool', default=False),
         option_group=dict(required=False),
         maint_window=dict(required=False),


Test patch: