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

elb_application_lb: add support for creating alb with listener having multiple certificates #1950

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
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
minor_changes:
- module_utils/elbv2 - Add support for adding listener with multiple certificates during ALB creation. Allows elb_application_elb module to handle mentioned use case. (https://github.com/ansible-collections/amazon.aws/pull/1950).
18 changes: 17 additions & 1 deletion plugins/module_utils/elbv2.py
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,23 @@ def add(self):
# Rules is not a valid parameter for create_listener
if "Rules" in self.listener:
self.listener.pop("Rules")
AWSRetry.jittered_backoff()(self.connection.create_listener)(LoadBalancerArn=self.elb_arn, **self.listener)

# handle multiple certs by adding only 1 cert during listener creation and make calls to add_listener_certificates to add other certs
listener_certificates = self.listener.get("Certificates", [])
first_certificate, other_certs = [], []
if len(listener_certificates) > 0:
first_certificate, other_certs = listener_certificates[0], listener_certificates[1:]
self.listener["Certificates"] = [first_certificate]
# create listener
create_listener_result = AWSRetry.jittered_backoff()(self.connection.create_listener)(
LoadBalancerArn=self.elb_arn, **self.listener
)
# only one cert can be specified per call to add_listener_certificates
for cert in other_certs:
AWSRetry.jittered_backoff()(self.connection.add_listener_certificates)(
ListenerArn=create_listener_result["Listeners"][0]["ListenerArn"], Certificates=[cert]
)

except (BotoCoreError, ClientError) as e:
self.module.fail_json_aws(e)

Expand Down
27 changes: 25 additions & 2 deletions plugins/modules/elb_application_lb.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@
Port: 80 # Required. The port on which the load balancer is listening.
# The security policy that defines which ciphers and protocols are supported. The default is the current predefined security policy.
SslPolicy: ELBSecurityPolicy-2015-05
Certificates: # The ARN of the certificate (only one certficate ARN should be provided)
Certificates: # The ARN of the certificate
- CertificateArn: arn:aws:iam::123456789012:server-certificate/test.domain.com
DefaultActions:
- Type: forward # Required.
Expand All @@ -260,7 +260,7 @@
Port: 80 # Required. The port on which the load balancer is listening.
# The security policy that defines which ciphers and protocols are supported. The default is the current predefined security policy.
SslPolicy: ELBSecurityPolicy-2015-05
Certificates: # The ARN of the certificate (only one certficate ARN should be provided)
Certificates: # The ARN of the certificate
- CertificateArn: arn:aws:iam::123456789012:server-certificate/test.domain.com
DefaultActions:
- Type: forward # Required.
Expand Down Expand Up @@ -330,6 +330,29 @@
Type: forward
state: present

# Create an ALB with a listener having multiple listener certificates
- amazon.aws.elb_application_lb:
name: myalb
security_groups:
- sg-12345678
- my-sec-group
subnets:
- subnet-012345678
- subnet-abcdef000
listeners:
- Protocol: HTTP # Required. The protocol for connections from clients to the load balancer (HTTP or HTTPS) (case-sensitive).
Port: 80 # Required. The port on which the load balancer is listening.
# The security policy that defines which ciphers and protocols are supported. The default is the current predefined security policy.
SslPolicy: ELBSecurityPolicy-2015-05
Certificates: # The ARN of the certificate (first certificate in the list will be set as default certificate)
- CertificateArn: arn:aws:iam::123456789012:server-certificate/test.domain.com
- CertificateArn: arn:aws:iam::123456789012:server-certificate/secondtest.domain.com
- CertificateArn: arn:aws:iam::123456789012:server-certificate/thirdtest.domain.com
DefaultActions:
- Type: forward # Required.
TargetGroupName: # Required. The name of the target group
state: present

# Remove an ALB
- amazon.aws.elb_application_lb:
name: myalb
Expand Down
13 changes: 13 additions & 0 deletions tests/integration/targets/elb_application_lb/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
resource_short: "{{ '%0.8x' % ((16**8) | random(seed=resource_prefix)) }}"
alb_name: alb-test-{{ resource_short }}
alb_2_name: alb-test-2-{{ resource_short }}
alb_name_multiple_listener_test: alb-test-{{ resource_short }}-lt
tg_name: alb-test-{{ resource_short }}
tg_2_name: alb-test-2-{{ resource_short }}
vpc_cidr: 10.{{ 256 | random(seed=resource_prefix) }}.0.0/16
Expand All @@ -26,3 +27,15 @@ elb_access_log_account_id_map:
us-gov-west-1: "048591011584"

elb_account_id: "{{ elb_access_log_account_id_map[aws_region] }}"

local_certs:
- priv_key: "{{ remote_tmp_dir }}/private-1.pem"
cert: "{{ remote_tmp_dir }}/public-1.pem"
csr: "{{ remote_tmp_dir }}/csr-1.csr"
domain: elb-classic.{{ tiny_prefix }}.ansible.test
name: "{{ resource_prefix }}_{{ resource_prefix }}_1"
- priv_key: "{{ remote_tmp_dir }}/private-2.pem"
cert: "{{ remote_tmp_dir }}/public-2.pem"
csr: "{{ remote_tmp_dir }}/csr-2.csr"
domain: elb-classic.{{ tiny_prefix }}.ansible.test
name: "{{ resource_prefix }}_{{ resource_prefix }}_2"
4 changes: 4 additions & 0 deletions tests/integration/targets/elb_application_lb/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
dependencies:
- setup_ec2_facts
- setup_remote_tmp_dir
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
- name: Run tests
block:
- name: Generate private key for local certs
community.crypto.openssl_privatekey:
path: "{{ item.priv_key }}"
type: RSA
size: 2048
with_items: "{{ local_certs }}"

- name: Generate an OpenSSL Certificate Signing Request for own certs
community.crypto.openssl_csr:
path: "{{ item.csr }}"
privatekey_path: "{{ item.priv_key }}"
common_name: "{{ item.domain }}"
with_items: "{{ local_certs }}"

- name: Generate a Self Signed OpenSSL certificate for own certs
community.crypto.x509_certificate:
provider: selfsigned
path: "{{ item.cert }}"
csr_path: "{{ item.csr }}"
privatekey_path: "{{ item.priv_key }}"
selfsigned_digest: sha256
register: cert_create_result
with_items: "{{ local_certs }}"

- name: upload certificates
community.aws.acm_certificate:
name_tag: "{{ item.name }}"
certificate: "{{ lookup('file', item.cert ) }}"
private_key: "{{ lookup('file', item.priv_key ) }}"
state: present
tags:
Application: search
Environment: development
purge_tags: false
register: upload
with_items: "{{ local_certs }}"
until: upload is succeeded
retries: 5
delay: 10

- ansible.builtin.set_fact:
cert_1_arn: "{{ upload.results[0].certificate.arn }}"
cert_2_arn: "{{ upload.results[1].certificate.arn }}"

- name: Create a target group for testing
community.aws.elb_target_group:
name: "{{ tg_name }}"
protocol: http
port: 80
vpc_id: "{{ vpc_id }}"
state: present

- name: Create an ALB with listener having multiple certificates
amazon.aws.elb_application_lb:
name: "{{ alb_name_multiple_listener_test }}"
subnets: "{{ public_subnets }}"
security_groups: "{{ sec_group.group_id }}"
state: present
purge_listeners: False
listeners:
- Protocol: HTTPS
Port: 446
SslPolicy: ELBSecurityPolicy-TLS13-1-2-2021-06
Certificates: # The ARN of the certificate
- CertificateArn: "{{ cert_1_arn }}"
- CertificateArn: "{{ cert_2_arn }}"
DefaultActions:
- Type: forward
TargetGroupName: "{{ tg_name }}"
register: alb

- name: Gather information about a particular ALB given its ARN #returns only default cert
amazon.aws.elb_application_lb_info:
load_balancer_arns:
- "{{ alb.load_balancer_arn }}"
register: alb_info

- name: obtain information about a certificate 1
community.aws.acm_certificate_info:
certificate_arn: "{{ cert_1_arn }}"
register: cert_1_info

- name: obtain information about a certificate 2
community.aws.acm_certificate_info:
certificate_arn: "{{ cert_2_arn }}"
register: cert_2_info

- name: Assert that both certificiates are in use by test load balancer
ansible.builtin.assert:
that:
- cert_1_info.certificates[0].in_use_by[0] == alb_info.load_balancers[0].load_balancer_arn
- cert_2_info.certificates[0].in_use_by[0] == alb_info.load_balancers[0].load_balancer_arn

always:
- name: Delete test ALB
amazon.aws.elb_application_lb:
name: "{{ alb_name_multiple_listener_test }}"
subnets: "{{ public_subnets }}"
security_groups: "{{ sec_group.group_id }}"
state: absent
purge_listeners: False
listeners:
- Protocol: HTTPS
Port: 446
SslPolicy: ELBSecurityPolicy-TLS13-1-2-2021-06
Certificates: # The ARN of the certificate
- CertificateArn: "{{ cert_1_arn }}"
- CertificateArn: "{{ cert_2_arn }}"
DefaultActions:
- Type: forward
TargetGroupName: "{{ tg_name }}"
ignore_errors: true

- name: delete a certificate with a particular ARN
community.aws.acm_certificate:
certificate_arn: "{{ item }}"
state: absent
register: delete_acm
with_items:
- "{{ cert_1_arn }}"
- "{{ cert_2_arn }}"
retries: 5
delay: 5
until: delete_acm is not failed
ignore_errors: true
4 changes: 4 additions & 0 deletions tests/integration/targets/elb_application_lb/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@
encryption: aws:kms
policy: "{{ lookup('template', 'policy.json') }}"


- name: Run tests for creating ALB with listener having multiple certificates
ansible.builtin.import_tasks: alb_with_multiple_listener_certs.yml

- name: Create an ALB (invalid - SslPolicy is required when Protocol == HTTPS)
amazon.aws.elb_application_lb:
name: "{{ alb_name }}"
Expand Down
Loading