-
Notifications
You must be signed in to change notification settings - Fork 398
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add lightsail_static_ip module (#259)
Add lightsail_static_ip module SUMMARY Adds a module to manage AWS Lightsail Static IP addresses Fixes #250 ISSUE TYPE New Module Pull Request COMPONENT NAME community.aws.lightsail_static_ip ADDITIONAL INFORMATION As per my earlier pull request, this is part of larger work to add functionality to this module in terms of managing AWS Lightsail. Apologies if there are any issues/I have missed anything. I am new to Ansible development, but have tried to follow the contribution docs as best as I can. Example playbook: - name: create static IP community.aws.lightsail_static_ip: name: "test_static" state: present region: ap-southeast-2 Reviewed-by: Jill R <None> Reviewed-by: Mark Chappell <None>
- Loading branch information
1 parent
d7e3617
commit 88f5d0c
Showing
5 changed files
with
247 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
#!/usr/bin/python | ||
|
||
# -*- coding: utf-8 -*- | ||
# Copyright: Ansible Project | ||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) | ||
|
||
from __future__ import absolute_import, division, print_function | ||
__metaclass__ = type | ||
|
||
|
||
DOCUMENTATION = ''' | ||
--- | ||
module: lightsail_static_ip | ||
version_added: 4.1.0 | ||
short_description: Manage static IP addresses in AWS Lightsail | ||
description: | ||
- Manage static IP addresses in AWS Lightsail. | ||
author: | ||
- "Daniel Cotton (@danielcotton)" | ||
options: | ||
state: | ||
description: | ||
- Describes the desired state. | ||
default: present | ||
choices: ['present', 'absent'] | ||
type: str | ||
name: | ||
description: Name of the static IP. | ||
required: true | ||
type: str | ||
extends_documentation_fragment: | ||
- amazon.aws.aws | ||
- amazon.aws.ec2 | ||
''' | ||
|
||
|
||
EXAMPLES = ''' | ||
- name: Provision a Lightsail static IP | ||
community.aws.lightsail_static_ip: | ||
state: present | ||
name: my_static_ip | ||
register: my_ip | ||
- name: Remove a static IP | ||
community.aws.lightsail_static_ip: | ||
state: absent | ||
name: my_static_ip | ||
''' | ||
|
||
RETURN = ''' | ||
static_ip: | ||
description: static_ipinstance data | ||
returned: always | ||
type: dict | ||
sample: | ||
arn: "arn:aws:lightsail:ap-southeast-2:184297340509:StaticIp/d8f47672-c261-4443-a484-4a2ec983db9a" | ||
created_at: "2021-02-28T00:04:05.202000+10:30" | ||
ip_address: "192.0.2.5" | ||
is_attached: false | ||
location: | ||
availability_zone: all | ||
region_name: ap-southeast-2 | ||
name: "static_ip" | ||
resource_type: StaticIp | ||
support_code: "677585553206/192.0.2.5" | ||
''' | ||
|
||
try: | ||
import botocore | ||
except ImportError: | ||
# will be caught by AnsibleAWSModule | ||
pass | ||
|
||
from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict | ||
|
||
from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule | ||
from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code | ||
|
||
|
||
def find_static_ip_info(module, client, static_ip_name, fail_if_not_found=False): | ||
|
||
try: | ||
res = client.get_static_ip(staticIpName=static_ip_name) | ||
except is_boto3_error_code('NotFoundException') as e: | ||
if fail_if_not_found: | ||
module.fail_json_aws(e) | ||
return None | ||
except botocore.exceptions.ClientError as e: # pylint: disable=duplicate-except | ||
module.fail_json_aws(e) | ||
return res['staticIp'] | ||
|
||
|
||
def create_static_ip(module, client, static_ip_name): | ||
|
||
inst = find_static_ip_info(module, client, static_ip_name) | ||
if inst: | ||
module.exit_json(changed=False, static_ip=camel_dict_to_snake_dict(inst)) | ||
else: | ||
create_params = {'staticIpName': static_ip_name} | ||
|
||
try: | ||
client.allocate_static_ip(**create_params) | ||
except botocore.exceptions.ClientError as e: | ||
module.fail_json_aws(e) | ||
|
||
inst = find_static_ip_info(module, client, static_ip_name, fail_if_not_found=True) | ||
|
||
module.exit_json(changed=True, static_ip=camel_dict_to_snake_dict(inst)) | ||
|
||
|
||
def delete_static_ip(module, client, static_ip_name): | ||
|
||
inst = find_static_ip_info(module, client, static_ip_name) | ||
if inst is None: | ||
module.exit_json(changed=False, static_ip={}) | ||
|
||
changed = False | ||
try: | ||
client.release_static_ip(staticIpName=static_ip_name) | ||
changed = True | ||
except botocore.exceptions.ClientError as e: | ||
module.fail_json_aws(e) | ||
|
||
module.exit_json(changed=changed, static_ip=camel_dict_to_snake_dict(inst)) | ||
|
||
|
||
def main(): | ||
|
||
argument_spec = dict( | ||
name=dict(type='str', required=True), | ||
state=dict(type='str', default='present', choices=['present', 'absent']), | ||
) | ||
|
||
module = AnsibleAWSModule(argument_spec=argument_spec) | ||
|
||
client = module.client('lightsail') | ||
|
||
name = module.params.get('name') | ||
state = module.params.get('state') | ||
|
||
if state == 'present': | ||
create_static_ip(module, client, name) | ||
elif state == 'absent': | ||
delete_static_ip(module, client, name) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
cloud/aws |
1 change: 1 addition & 0 deletions
1
tests/integration/targets/lightsail_static_ip/defaults/main.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
static_ip_name: "{{ resource_prefix }}_static_ip" |
96 changes: 96 additions & 0 deletions
96
tests/integration/targets/lightsail_static_ip/tasks/main.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
--- | ||
|
||
- module_defaults: | ||
group/aws: | ||
aws_access_key: '{{ aws_access_key | default(omit) }}' | ||
aws_secret_key: '{{ aws_secret_key | default(omit) }}' | ||
security_token: '{{ security_token | default(omit) }}' | ||
region: '{{ aws_region | default(omit) }}' | ||
|
||
block: | ||
|
||
# ==== Tests =================================================== | ||
|
||
- name: Create a new static IP | ||
lightsail_static_ip: | ||
name: "{{ static_ip_name }}" | ||
register: result | ||
|
||
- assert: | ||
that: | ||
- result.changed == True | ||
- '"static_ip" in result' | ||
- '"arn" in result.static_ip' | ||
- '"created_at" in result.static_ip' | ||
- '"ip_address" in result.static_ip' | ||
- '"is_attached" in result.static_ip' | ||
- '"location" in result.static_ip' | ||
- '"name" in result.static_ip' | ||
- '"resource_type" in result.static_ip' | ||
- '"support_code" in result.static_ip' | ||
- result.static_ip.arn.startswith("arn:") | ||
- result.static_ip.name == static_ip_name | ||
- result.static_ip.resource_type == 'StaticIp' | ||
- result.static_ip.is_attached == false | ||
- result.static_ip.ip_address | ansible.utils.ipaddr | ||
- '"availability_zone" in result.static_ip.location' | ||
- '"region_name" in result.static_ip.location' | ||
|
||
- set_fact: | ||
lightsail_ip_arn: '{{ result.static_ip.arn }}' | ||
lightsail_ip_address: '{{ result.static_ip.ip_address }}' | ||
|
||
- name: Make sure create is idempotent | ||
lightsail_static_ip: | ||
name: "{{ static_ip_name }}" | ||
register: result | ||
|
||
- assert: | ||
that: | ||
- result.changed == False | ||
- '"static_ip" in result' | ||
- '"arn" in result.static_ip' | ||
- '"created_at" in result.static_ip' | ||
- '"ip_address" in result.static_ip' | ||
- '"is_attached" in result.static_ip' | ||
- '"location" in result.static_ip' | ||
- '"name" in result.static_ip' | ||
- '"resource_type" in result.static_ip' | ||
- '"support_code" in result.static_ip' | ||
- result.static_ip.arn == lightsail_ip_arn | ||
- result.static_ip.name == static_ip_name | ||
- result.static_ip.resource_type == 'StaticIp' | ||
- result.static_ip.is_attached == false | ||
- result.static_ip.ip_address == lightsail_ip_address | ||
- '"availability_zone" in result.static_ip.location' | ||
- '"region_name" in result.static_ip.location' | ||
|
||
- name: Delete the static IP | ||
lightsail_static_ip: | ||
name: "{{ static_ip_name }}" | ||
state: absent | ||
register: result | ||
|
||
- assert: | ||
that: | ||
- result.changed == True | ||
|
||
- name: Make sure deletion is idempotent | ||
lightsail_static_ip: | ||
name: "{{ static_ip_name }}" | ||
state: absent | ||
register: result | ||
|
||
- assert: | ||
that: | ||
- result.changed == False | ||
|
||
# ==== Cleanup ==================================================== | ||
|
||
always: | ||
|
||
- name: Cleanup - delete static IP | ||
lightsail_static_ip: | ||
name: "{{ static_ip_name }}" | ||
state: absent | ||
ignore_errors: yes |