Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update elb_xxxx module adding ip_address_type option #499

Merged
merged 11 commits into from
Apr 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelogs/499-elb-module-add-ip_address_type_option.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
minor_changes:
- elb_application_lb - added ``ip_address_type`` parameter to support changing application load balancer configuration (https://github.com/ansible-collections/community.aws/pull/499).
- elb_network_lb - added ``ip_address_type`` parameter to support changing network load balancer configuration (https://github.com/ansible-collections/community.aws/pull/499).
- elb_application_lb_info - added ``ip_address_type`` in output when gathering application load balancer parameters (https://github.com/ansible-collections/community.aws/pull/499).
15 changes: 13 additions & 2 deletions plugins/modules/elb_application_lb.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@
- When set to C(no), keep the existing load balancer rules in place. Will modify and add, but will not delete.
default: yes
type: bool
ip_address_type:
description:
- Sets the type of IP addresses used by the subnets of the specified Application Load Balancer.
choices: [ 'ipv4', 'dualstack' ]
type: str
extends_documentation_fragment:
- amazon.aws.aws
- amazon.aws.ec2
Expand Down Expand Up @@ -476,7 +481,6 @@

def create_or_update_elb(elb_obj):
"""Create ELB or modify main attributes. json_exit here"""

if elb_obj.elb:
# ELB exists so check subnets, security groups and tags match what has been passed

Expand Down Expand Up @@ -562,6 +566,9 @@ def create_or_update_elb(elb_obj):
rule_obj.modify()
elb_obj.changed = True

# Update ELB ip address type only if option has been provided
if elb_obj.module.params.get('ip_address_type') is not None:
elb_obj.modify_ip_address_type(elb_obj.module.params.get('ip_address_type'))
# Get the ELB again
elb_obj.update()

Expand All @@ -583,6 +590,9 @@ def create_or_update_elb(elb_obj):
# Change tags to ansible friendly dict
snaked_elb['tags'] = boto3_tag_list_to_ansible_dict(snaked_elb['tags'])

# ip address type
snaked_elb['ip_address_type'] = elb_obj.get_elb_ip_address_type()

elb_obj.module.exit_json(changed=elb_obj.changed, **snaked_elb)


Expand Down Expand Up @@ -629,7 +639,8 @@ def main():
tags=dict(type='dict'),
wait_timeout=dict(type='int'),
wait=dict(default=False, type='bool'),
purge_rules=dict(default=True, type='bool')
purge_rules=dict(default=True, type='bool'),
ip_address_type=dict(type='str', choices=['ipv4', 'dualstack'])
)

module = AnsibleAWSModule(argument_spec=argument_spec,
Expand Down
29 changes: 10 additions & 19 deletions plugins/modules/elb_application_lb_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,94 +70,76 @@
contains:
access_logs_s3_bucket:
description: The name of the S3 bucket for the access logs.
returned: when status is present
type: str
sample: mys3bucket
access_logs_s3_enabled:
description: Indicates whether access logs stored in Amazon S3 are enabled.
returned: when status is present
type: str
sample: true
access_logs_s3_prefix:
description: The prefix for the location in the S3 bucket.
returned: when status is present
type: str
sample: /my/logs
availability_zones:
description: The Availability Zones for the load balancer.
returned: when status is present
type: list
sample: "[{'subnet_id': 'subnet-aabbccddff', 'zone_name': 'ap-southeast-2a'}]"
canonical_hosted_zone_id:
description: The ID of the Amazon Route 53 hosted zone associated with the load balancer.
returned: when status is present
type: str
sample: ABCDEF12345678
created_time:
description: The date and time the load balancer was created.
returned: when status is present
type: str
sample: "2015-02-12T02:14:02+00:00"
deletion_protection_enabled:
description: Indicates whether deletion protection is enabled.
returned: when status is present
type: str
sample: true
dns_name:
description: The public DNS name of the load balancer.
returned: when status is present
type: str
sample: internal-my-elb-123456789.ap-southeast-2.elb.amazonaws.com
idle_timeout_timeout_seconds:
description: The idle timeout value, in seconds.
returned: when status is present
type: str
sample: 60
ip_address_type:
description: The type of IP addresses used by the subnets for the load balancer.
returned: when status is present
type: str
sample: ipv4
load_balancer_arn:
description: The Amazon Resource Name (ARN) of the load balancer.
returned: when status is present
type: str
sample: arn:aws:elasticloadbalancing:ap-southeast-2:0123456789:loadbalancer/app/my-elb/001122334455
load_balancer_name:
description: The name of the load balancer.
returned: when status is present
type: str
sample: my-elb
scheme:
description: Internet-facing or internal load balancer.
returned: when status is present
type: str
sample: internal
security_groups:
description: The IDs of the security groups for the load balancer.
returned: when status is present
type: list
sample: ['sg-0011223344']
state:
description: The state of the load balancer.
returned: when status is present
type: dict
sample: "{'code': 'active'}"
tags:
description: The tags attached to the load balancer.
returned: when status is present
type: dict
sample: "{
'Tag': 'Example'
}"
type:
description: The type of load balancer.
returned: when status is present
type: str
sample: application
vpc_id:
description: The ID of the VPC for the load balancer.
returned: when status is present
type: str
sample: vpc-0011223344
'''
Expand Down Expand Up @@ -213,8 +195,14 @@ def get_load_balancer_tags(connection, module, load_balancer_arn):
module.fail_json_aws(e, msg="Failed to describe load balancer tags")


def list_load_balancers(connection, module):
def get_load_balancer_ipaddresstype(connection, module, load_balancer_arn):
try:
return connection.describe_load_balancers(LoadBalancerArns=[load_balancer_arn])['LoadBalancers'][0]['IpAddressType']
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Failed to describe load balancer ip address type")


def list_load_balancers(connection, module):
load_balancer_arns = module.params.get("load_balancer_arns")
names = module.params.get("names")

Expand Down Expand Up @@ -242,6 +230,9 @@ def list_load_balancers(connection, module):
for listener in load_balancer['listeners']:
listener['rules'] = get_listener_rules(connection, module, listener['ListenerArn'])

# Get ELB ip address type
load_balancer['IpAddressType'] = get_load_balancer_ipaddresstype(connection, module, load_balancer['LoadBalancerArn'])

# Turn the boto3 result in to ansible_friendly_snaked_names
snaked_load_balancers = [camel_dict_to_snake_dict(load_balancer) for load_balancer in load_balancers['LoadBalancers']]

Expand Down
16 changes: 14 additions & 2 deletions plugins/modules/elb_network_lb.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@
description:
- The duration in seconds to wait, used in conjunction with I(wait).
type: int
ip_address_type:
description:
- Sets the type of IP addresses used by the subnets of the specified Application Load Balancer.
choices: [ 'ipv4', 'dualstack' ]
type: str
extends_documentation_fragment:
- amazon.aws.aws
- amazon.aws.ec2
Expand Down Expand Up @@ -314,7 +319,6 @@

def create_or_update_elb(elb_obj):
"""Create ELB or modify main attributes. json_exit here"""

if elb_obj.elb:
# ELB exists so check subnets, security groups and tags match what has been passed

Expand Down Expand Up @@ -379,6 +383,10 @@ def create_or_update_elb(elb_obj):
# Update the ELB attributes
elb_obj.update_elb_attributes()

# Update ELB ip address type only if option has been provided
if elb_obj.module.params.get('ip_address_type') is not None:
elb_obj.modify_ip_address_type(elb_obj.module.params.get('ip_address_type'))

# Convert to snake_case and merge in everything we want to return to the user
snaked_elb = camel_dict_to_snake_dict(elb_obj.elb)
snaked_elb.update(camel_dict_to_snake_dict(elb_obj.elb_attributes))
Expand All @@ -389,6 +397,9 @@ def create_or_update_elb(elb_obj):
# Change tags to ansible friendly dict
snaked_elb['tags'] = boto3_tag_list_to_ansible_dict(snaked_elb['tags'])

# ip address type
snaked_elb['ip_address_type'] = elb_obj.get_elb_ip_address_type()

elb_obj.module.exit_json(changed=elb_obj.changed, **snaked_elb)


Expand Down Expand Up @@ -425,7 +436,8 @@ def main():
state=dict(choices=['present', 'absent'], type='str'),
tags=dict(type='dict'),
wait_timeout=dict(type='int'),
wait=dict(type='bool')
wait=dict(type='bool'),
ip_address_type=dict(type='str', choices=['ipv4', 'dualstack'])
)
)

Expand Down
32 changes: 24 additions & 8 deletions tests/integration/targets/elb_application_lb/tasks/full_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
cidr_block: 10.228.228.0/22
name: '{{ resource_prefix }}_vpc'
state: present
ipv6_cidr: true
register: vpc
- name: create internet gateway
ec2_vpc_igw:
Expand All @@ -14,7 +15,7 @@
tags:
Name: '{{ resource_prefix }}'
register: igw
- name: create public subnet
- name: create private subnet
ec2_vpc_subnet:
cidr: '{{ item.cidr }}'
az: '{{ aws_region}}{{ item.az }}'
Expand All @@ -24,19 +25,33 @@
Public: '{{ item.public|string }}'
Name: '{{ item.public|ternary(''public'', ''private'') }}-{{ item.az }}'
with_items:
- cidr: 10.228.228.0/24
az: a
public: 'True'
- cidr: 10.228.229.0/24
az: b
public: 'True'
- cidr: 10.228.230.0/24
az: a
public: 'False'
- cidr: 10.228.231.0/24
az: b
public: 'False'
register: subnets

- name: create public subnets with ipv6
ec2_vpc_subnet:
cidr: '{{ item.cidr }}'
az: '{{ aws_region}}{{ item.az }}'
vpc_id: '{{ vpc.vpc.id }}'
state: present
ipv6_cidr: '{{ item.vpc_ipv6_cidr }}'
tags:
Public: '{{ item.public|string }}'
Name: '{{ item.public|ternary(''public'', ''private'') }}-{{ item.az }}'
with_items:
- cidr: 10.228.228.0/24
az: a
public: 'True'
vpc_ipv6_cidr: "{{ vpc.vpc.ipv6_cidr_block_association_set[0].ipv6_cidr_block | replace('0::/56','0::/64') }}"
- cidr: 10.228.229.0/24
az: b
public: 'True'
vpc_ipv6_cidr: "{{ vpc.vpc.ipv6_cidr_block_association_set[0].ipv6_cidr_block | replace('0::/56','1::/64') }}"

- ec2_vpc_subnet_info:
filters:
vpc-id: '{{ vpc.vpc.id }}'
Expand Down Expand Up @@ -83,6 +98,7 @@

# Run main tests
- include_tasks: test_alb_bad_listener_options.yml
- include_tasks: test_alb_ip_address_type_options.yml
- include_tasks: test_alb_tags.yml
- include_tasks: test_creating_alb.yml
- include_tasks: test_alb_with_asg.yml
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
- block:
- name: set elb name for ipv6
set_fact:
elb_name_ipv6: "{{ alb_name ~ 'ipv6' }}"

- name: test creating an ELB with invalid ip address type
elb_application_lb:
name: "{{ elb_name_ipv6 }}"
subnets: "{{ alb_subnets }}"
security_groups: "{{ sec_group.group_id }}"
state: present
listeners:
- Protocol: HTTP
Port: 80
DefaultActions:
- Type: forward
TargetGroupName: "{{ tg_name }}"
ip_address_type: "ip_addr_v4_v6"
ignore_errors: yes
register: elb

- assert:
that:
- elb is failed

- name: test creating an ELB with dualstack ip adress type
elb_application_lb:
name: "{{ elb_name_ipv6 }}"
subnets: "{{ alb_subnets }}"
security_groups: "{{ sec_group.group_id }}"
state: present
listeners:
- Protocol: HTTP
Port: 80
DefaultActions:
- Type: forward
TargetGroupName: "{{ tg_name }}"
ip_address_type: "dualstack"
register: elb

- assert:
that:
- elb.ip_address_type == "dualstack"

- name: test updating an ELB with ipv4 adress type
elb_application_lb:
name: "{{ elb_name_ipv6 }}"
subnets: "{{ alb_subnets }}"
security_groups: "{{ sec_group.group_id }}"
state: present
listeners:
- Protocol: HTTP
Port: 80
DefaultActions:
- Type: forward
TargetGroupName: "{{ tg_name }}"
ip_address_type: "ipv4"
register: elb

- assert:
that:
- elb.changed
- elb.ip_address_type == "ipv4"

- name: test idempotence updating an ELB with ipv4 adress type
elb_application_lb:
name: "{{ elb_name_ipv6 }}"
subnets: "{{ alb_subnets }}"
security_groups: "{{ sec_group.group_id }}"
state: present
listeners:
- Protocol: HTTP
Port: 80
DefaultActions:
- Type: forward
TargetGroupName: "{{ tg_name }}"
ip_address_type: "ipv4"
register: elb

- assert:
that:
- not elb.changed
- elb.ip_address_type == "ipv4"

always:
# Cleanup
- name: destroy ALB if created
elb_application_lb:
name: '{{ elb_name_ipv6 }}'
state: absent
wait: true
wait_timeout: 600
ignore_errors: true
2 changes: 2 additions & 0 deletions tests/integration/targets/elb_application_lb_info/aliases
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cloud/aws
shippable/aws/group2
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
resource_short: "{{ '%0.8x'%((16**8) | random(seed=resource_prefix)) }}"
alb_name: "alb-test-{{ resource_short }}"
tg_name: "alb-test-{{ resource_short }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dependencies:
- setup_remote_tmp_dir
Loading