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

add check_mode for elb_application_lb* & refactor integration tests #894

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
minor_changes:
- elb_application_lb - add check_mode support and refactor integration tests (https://github.com/ansible-collections/community.aws/pull/894)
- elb_application_lb_info - update documentation and refactor integration tests (https://github.com/ansible-collections/community.aws/pull/894)
135 changes: 104 additions & 31 deletions plugins/modules/elb_application_lb.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
type: list
elements: dict
description:
- A list of ALB Listener Rules.
- A list of ELB Listener Rules.
- 'For the complete documentation of possible Conditions and Actions please see the boto3 documentation:'
- 'https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/elbv2.html#ElasticLoadBalancingv2.Client.create_rule'
suboptions:
Expand Down Expand Up @@ -240,9 +240,9 @@
TargetGroupName: # Required. The name of the target group
state: present

# Create an ALB with listeners and rules
# Create an ELB with listeners and rules
- community.aws.elb_application_lb:
name: test-alb
name: test-elb
subnets:
- subnet-12345678
- subnet-87654321
Expand Down Expand Up @@ -315,27 +315,32 @@
description: The name of the S3 bucket for the access logs.
returned: when state is present
type: str
sample: mys3bucket
sample: "mys3bucket"
access_logs_s3_enabled:
description: Indicates whether access logs stored in Amazon S3 are enabled.
returned: when state is present
type: str
type: bool
sample: true
access_logs_s3_prefix:
description: The prefix for the location in the S3 bucket.
returned: when state is present
type: str
sample: my/logs
sample: "my/logs"
availability_zones:
description: The Availability Zones for the load balancer.
returned: when state is present
type: list
sample: "[{'subnet_id': 'subnet-aabbccddff', 'zone_name': 'ap-southeast-2a'}]"
sample: [{ "load_balancer_addresses": [], "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 state is present
type: str
sample: ABCDEF12345678
sample: "ABCDEF12345678"
changed:
description: Whether an ELB was created/updated/deleted
returned: always
type: bool
sample: true
created_time:
description: The date and time the load balancer was created.
returned: when state is present
Expand All @@ -344,23 +349,28 @@
deletion_protection_enabled:
description: Indicates whether deletion protection is enabled.
returned: when state is present
type: str
type: bool
sample: true
dns_name:
description: The public DNS name of the load balancer.
returned: when state is present
type: str
sample: internal-my-elb-123456789.ap-southeast-2.elb.amazonaws.com
sample: "internal-my-elb-123456789.ap-southeast-2.elb.amazonaws.com"
failed:
description: Indicates whether or not the action has failed.
returned: always
type: bool
sample: false
idle_timeout_timeout_seconds:
description: The idle timeout value, in seconds.
returned: when state is present
type: int
sample: 60
ip_address_type:
description: The type of IP addresses used by the subnets for the load balancer.
description: The type of IP addresses used by the subnets for the load balancer.
returned: when state is present
type: str
sample: ipv4
sample: "ipv4"
listeners:
description: Information about the listeners.
returned: when state is present
Expand All @@ -385,7 +395,7 @@
description: The protocol for connections from clients to the load balancer.
returned: when state is present
type: str
sample: HTTPS
sample: "HTTPS"
certificates:
description: The SSL server certificate.
returned: when state is present
Expand Down Expand Up @@ -420,22 +430,42 @@
description: The Amazon Resource Name (ARN) of the load balancer.
returned: when state is present
type: str
sample: arn:aws:elasticloadbalancing:ap-southeast-2:0123456789:loadbalancer/app/my-elb/001122334455
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 state is present
type: str
sample: my-elb
sample: "my-elb"
routing_http2_enabled:
description: Indicates whether HTTP/2 is enabled.
returned: when state is present
type: str
type: bool
sample: true
routing_http_desync_mitigation_mode:
description: Determines how the load balancer handles requests that might pose a security risk to an application.
returned: when state is present
type: str
sample: "defensive"
routing_http_drop_invalid_header_fields_enabled:
description: Indicates whether HTTP headers with invalid header fields are removed by the load balancer (true) or routed to targets (false).
returned: when state is present
type: bool
sample: false
routing_http_x_amzn_tls_version_and_cipher_suite_enabled:
description: Indicates whether the two headers are added to the client request before sending it to the target.
returned: when state is present
type: bool
sample: false
routing_http_xff_client_port_enabled:
description: Indicates whether the X-Forwarded-For header should preserve the source port that the client used to connect to the load balancer.
returned: when state is present
type: bool
sample: false
scheme:
description: Internet-facing or internal load balancer.
returned: when state is present
type: str
sample: internal
sample: "internal"
security_groups:
description: The IDs of the security groups for the load balancer.
returned: when state is present
Expand All @@ -445,29 +475,35 @@
description: The state of the load balancer.
returned: when state is present
type: dict
sample: "{'code': 'active'}"
sample: {'code': 'active'}
tags:
description: The tags attached to the load balancer.
returned: when state is present
type: dict
sample: "{
sample: {
'Tag': 'Example'
}"
}
type:
description: The type of load balancer.
returned: when state is present
type: str
sample: application
sample: "application"
vpc_id:
description: The ID of the VPC for the load balancer.
returned: when state is present
type: str
sample: vpc-0011223344
sample: "vpc-0011223344"
waf_fail_open_enabled:
description: Indicates whether to allow a AWS WAF-enabled load balancer to route requests to targets if it is unable to forward the request to AWS WAF.
returned: when state is present
type: bool
sample: false
'''
alinabuzachis marked this conversation as resolved.
Show resolved Hide resolved

from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict, boto3_tag_list_to_ansible_dict, compare_aws_tags

from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_tag_list_to_ansible_dict
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import compare_aws_tags
from ansible_collections.amazon.aws.plugins.module_utils.elbv2 import (
ApplicationLoadBalancer,
ELBListener,
Expand All @@ -482,21 +518,29 @@ 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

# Subnets
if not elb_obj.compare_subnets():
if elb_obj.module.check_mode:
elb_obj.module.exit_json(changed=True, msg='Would have updated ELB if not in check mode.')
elb_obj.modify_subnets()

# Security Groups
if not elb_obj.compare_security_groups():
if elb_obj.module.check_mode:
elb_obj.module.exit_json(changed=True, msg='Would have updated ELB if not in check mode.')
elb_obj.modify_security_groups()

# Tags - only need to play with tags if tags parameter has been set to something
if elb_obj.tags is not None:

# Delete necessary tags
tags_need_modify, tags_to_delete = compare_aws_tags(boto3_tag_list_to_ansible_dict(elb_obj.elb['tags']),
boto3_tag_list_to_ansible_dict(elb_obj.tags), elb_obj.purge_tags)

# Exit on check_mode
if elb_obj.module.check_mode and (tags_need_modify or tags_to_delete):
elb_obj.module.exit_json(changed=True, msg='Would have updated ELB if not in check mode.')

# Delete necessary tags
if tags_to_delete:
elb_obj.delete_tags(tags_to_delete)

Expand All @@ -506,6 +550,8 @@ def create_or_update_elb(elb_obj):

else:
# Create load balancer
if elb_obj.module.check_mode:
elb_obj.module.exit_json(changed=True, msg='Would have created ELB if not in check mode.')
elb_obj.create_elb()

# ELB attributes
Expand All @@ -514,9 +560,12 @@ def create_or_update_elb(elb_obj):

# Listeners
listeners_obj = ELBListeners(elb_obj.connection, elb_obj.module, elb_obj.elb['LoadBalancerArn'])

listeners_to_add, listeners_to_modify, listeners_to_delete = listeners_obj.compare_listeners()

# Exit on check_mode
if elb_obj.module.check_mode and (listeners_to_add or listeners_to_modify or listeners_to_delete):
elb_obj.module.exit_json(changed=True, msg='Would have updated ELB if not in check mode.')
jatorcasso marked this conversation as resolved.
Show resolved Hide resolved

# Delete listeners
for listener_to_delete in listeners_to_delete:
listener_obj = ELBListener(elb_obj.connection, elb_obj.module, listener_to_delete, elb_obj.elb['LoadBalancerArn'])
Expand All @@ -543,9 +592,12 @@ def create_or_update_elb(elb_obj):
for listener in listeners_obj.listeners:
if 'Rules' in listener:
rules_obj = ELBListenerRules(elb_obj.connection, elb_obj.module, elb_obj.elb['LoadBalancerArn'], listener['Rules'], listener['Port'])

rules_to_add, rules_to_modify, rules_to_delete = rules_obj.compare_rules()

# Exit on check_mode
if elb_obj.module.check_mode and (rules_to_add or rules_to_modify or rules_to_delete):
elb_obj.module.exit_json(changed=True, msg='Would have updated ELB if not in check mode.')

# Delete rules
if elb_obj.module.params['purge_rules']:
for rule in rules_to_delete:
Expand All @@ -566,8 +618,17 @@ def create_or_update_elb(elb_obj):
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:
if elb_obj.module.params.get('ip_address_type') and elb_obj.elb_ip_addr_type != elb_obj.module.params.get('ip_address_type'):
# Exit on check_mode
if elb_obj.module.check_mode:
elb_obj.module.exit_json(changed=True, msg='Would have updated ELB if not in check mode.')

elb_obj.modify_ip_address_type(elb_obj.module.params.get('ip_address_type'))

# Exit on check_mode - no changes
if elb_obj.module.check_mode:
elb_obj.module.exit_json(changed=False, msg='IN CHECK MODE - no changes to make to ELB specified.')

# Get the ELB again
elb_obj.update()

Expand Down Expand Up @@ -598,13 +659,24 @@ def create_or_update_elb(elb_obj):
def delete_elb(elb_obj):

if elb_obj.elb:

# Exit on check_mode
if elb_obj.module.check_mode:
elb_obj.module.exit_json(changed=True, msg='Would have deleted ELB if not in check mode.')

listeners_obj = ELBListeners(elb_obj.connection, elb_obj.module, elb_obj.elb['LoadBalancerArn'])
for listener_to_delete in [i['ListenerArn'] for i in listeners_obj.current_listeners]:
listener_obj = ELBListener(elb_obj.connection, elb_obj.module, listener_to_delete, elb_obj.elb['LoadBalancerArn'])
listener_obj.delete()

elb_obj.delete()

else:

# Exit on check_mode - no changes
if elb_obj.module.check_mode:
elb_obj.module.exit_json(changed=False, msg='IN CHECK MODE - ELB already absent.')

elb_obj.module.exit_json(changed=elb_obj.changed)


Expand Down Expand Up @@ -648,7 +720,8 @@ def main():
],
required_together=[
['access_logs_enabled', 'access_logs_s3_bucket']
]
],
supports_check_mode=True,
)

# Quick check of listeners parameters
Expand All @@ -672,7 +745,7 @@ def main():

if state == 'present':
create_or_update_elb(elb)
else:
elif state == 'absent':
delete_elb(elb)


Expand Down
Loading