Skip to content

Commit

Permalink
Merge pull request ansible-collections#499 from abikouo/elbv2_ipaddress
Browse files Browse the repository at this point in the history
update elb_xxxx module adding ip_address_type option

Reviewed-by: https://github.com/apps/ansible-zuul
  • Loading branch information
ansible-zuul[bot] authored Apr 27, 2021
2 parents 8392572 + 2dbb8d1 commit 1feced5
Show file tree
Hide file tree
Showing 16 changed files with 541 additions and 38 deletions.
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

0 comments on commit 1feced5

Please sign in to comment.