Skip to content
This repository was archived by the owner on Oct 7, 2025. It is now read-only.
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: 2 additions & 2 deletions docs/roles/aws/aws_acm.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Creates AWS certificate requests. Allows for passing a validation domain. From t

Additionally, this role attempts to be idempotent by running `aws acm list-certificates` and ensuring that the domain of the cert being requested is not included in the current list of certificates.

Whenever this role runs it will set the `aws_acm_certificate_arn` variable so you have the ARN of the certificate, whether it exists already or it is newly created.
Whenever this role runs it will set the `aws_acm_certificate_arn` variable so you have the ARN of the certificate, whether it exists already or it is newly created. If applicable it will *also* set the `aws_acm_obsolete_certificate_arn` variable, so you can choose to use that to automatically delete a certificate that has been replaced later.

<!--TOC-->
<!--ENDTOC-->
Expand All @@ -27,7 +27,7 @@ aws_acm:
# zone: example.com
# aws_profile: us-east-1
validate: true # you need to set this to false if the validation zone is not in Route 53 or you do not have CLI access
export: true
export: false
route_53:
aws_profile: "{{ _aws_profile }}" # the zone might not be in the same account as the certificate
zone: example.com
Expand Down
2 changes: 1 addition & 1 deletion docs/roles/aws/aws_ec2_autoscale_cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ aws_ec2_autoscale_cluster:
extra_domains: [] # list of Subject Alternative Name domains and zones
# - domain: www2.example.com
# zone: example.com
# aws_profile: us-east-1
# aws_profile: "{{ _aws_profile }}"
route_53:
aws_profile: another # the zone might not be in the same account as the certificate
zone: example.com
Expand Down
4 changes: 2 additions & 2 deletions roles/aws/aws_acm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Creates AWS certificate requests. Allows for passing a validation domain. From t

Additionally, this role attempts to be idempotent by running `aws acm list-certificates` and ensuring that the domain of the cert being requested is not included in the current list of certificates.

Whenever this role runs it will set the `aws_acm_certificate_arn` variable so you have the ARN of the certificate, whether it exists already or it is newly created.
Whenever this role runs it will set the `aws_acm_certificate_arn` variable so you have the ARN of the certificate, whether it exists already or it is newly created. If applicable it will *also* set the `aws_acm_obsolete_certificate_arn` variable, so you can choose to use that to automatically delete a certificate that has been replaced later.

<!--TOC-->
<!--ENDTOC-->
Expand All @@ -27,7 +27,7 @@ aws_acm:
# zone: example.com
# aws_profile: us-east-1
validate: true # you need to set this to false if the validation zone is not in Route 53 or you do not have CLI access
export: true
export: false
route_53:
aws_profile: "{{ _aws_profile }}" # the zone might not be in the same account as the certificate
zone: example.com
Expand Down
2 changes: 1 addition & 1 deletion roles/aws/aws_acm/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ aws_acm:
# zone: example.com
# aws_profile: us-east-1
validate: true # you need to set this to false if the validation zone is not in Route 53 or you do not have CLI access
export: true
export: false
route_53:
aws_profile: "{{ _aws_profile }}" # the zone might not be in the same account as the certificate
zone: example.com
210 changes: 111 additions & 99 deletions roles/aws/aws_acm/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@
ansible.builtin.set_fact:
aws_acm_certificate_arn: ""
_aws_acm_domain_in_cert_list: false
_aws_acm_extra_domains_in_cert_list: true

- name: Iterate through the certificate list checking for domain.
ansible.builtin.set_fact:
aws_acm_certificate_arn: "{{ item.CertificateArn }}"
aws_acm_certificate: "{{ item }}"
_aws_acm_domain_in_cert_list: true
when: item.DomainName == aws_acm.domain_name
with_items: "{{ _aws_acm_cert_list }}"
when: item.DomainName == aws_acm.domain_name

- ansible.builtin.set_fact:
_aws_tags_list: []
Expand Down Expand Up @@ -68,6 +70,15 @@
loop: "{{ aws_acm.extra_domains }}"
when: aws_acm.extra_domains | length > 0

- name: Check if we have all our domains in a SAN cert.
ansible.builtin.set_fact:
_aws_acm_extra_domains_in_cert_list: false
with_items: "{{ _acm_san_domains }}"
when:
- _acm_san_domains is defined
- item not in aws_acm_certificate.SubjectAlternativeNameSummaries
- aws_acm.extra_domains | length > 0

- name: Send ACM request for a SAN cert if needed.
ansible.builtin.command: |
aws --profile "{{ aws_acm.aws_profile }}" --region "{{ aws_acm.region }}" \
Expand All @@ -78,7 +89,7 @@
--tags {{ _aws_tags_string }}
register: _aws_acm_new_san_certificate
when:
- not _aws_acm_domain_in_cert_list
- not _aws_acm_extra_domains_in_cert_list
- aws_acm.extra_domains | length > 0

- name: Parse returned certificate simple certificate output.
Expand All @@ -92,102 +103,103 @@
ansible.builtin.set_fact:
_aws_acm_new_certificate: "{{ _aws_acm_new_san_certificate.stdout | from_json }}"
when:
- not _aws_acm_domain_in_cert_list
- not _aws_acm_extra_domains_in_cert_list
- aws_acm.extra_domains | length > 0

- name: Fetch the new certificate's ARN.
ansible.builtin.set_fact:
aws_acm_certificate_arn: "{{ _aws_acm_new_certificate.CertificateArn }}"
when: not _aws_acm_domain_in_cert_list

# Not currently possible to do this with the API, so we just pause 5 seconds - this is usually enough time.
- name: Wait until the new certificate is properly issued.
ansible.builtin.pause:
seconds: 5
when:
- not _aws_acm_domain_in_cert_list
- aws_acm.validate

- name: Obtain all information for a the new ACM certificate.
community.aws.acm_certificate_info:
region: "{{ aws_acm.region }}"
profile: "{{ aws_acm.aws_profile }}"
domain_name: "{{ aws_acm.domain_name }}"
register: _aws_acm_new_certificate
when:
- not _aws_acm_domain_in_cert_list
- aws_acm.validate

- name: Initialise the DNS loop var with main domain entry DNS settings.
ansible.builtin.set_fact:
_acm_dns_all_domains:
- domain: "{{ aws_acm.domain_name }}"
zone: "{{ aws_acm.route_53.zone }}"
aws_profile: "{{ aws_acm.route_53.aws_profile }}"
when:
- aws_acm.route_53.zone is defined
- aws_acm.route_53.zone | length > 0
- not _aws_acm_domain_in_cert_list
- aws_acm.validate

- name: Add extra_domains so we can loop through DNS records.
ansible.builtin.set_fact:
_acm_dns_all_domains: "{{ _acm_dns_all_domains + [{'domain': item.domain, 'zone': item.zone, 'aws_profile': item.aws_profile}] }}"
loop: "{{ aws_acm.extra_domains }}"
when:
- aws_acm.extra_domains | length > 0
- not _aws_acm_domain_in_cert_list
- aws_acm.validate

- name: Add a DNS records in Route 53 for validation.
amazon.aws.route53:
state: present
profile: "{{ item.aws_profile }}"
zone: "{{ item.zone }}"
record: "{{ (_aws_acm_new_certificate.certificates[0].domain_validation_options | selectattr('domain_name', 'search', item.domain))[0].resource_record.name }}"
type: CNAME
value: "{{ (_aws_acm_new_certificate.certificates[0].domain_validation_options | selectattr('domain_name', 'search', item.domain))[0].resource_record.value }}"
overwrite: true
loop: "{{ _acm_dns_all_domains }}"
when:
- aws_acm.route_53.zone is defined
- aws_acm.route_53.zone | length > 0
- not _aws_acm_domain_in_cert_list
- aws_acm.validate

- name: Wait for ACM certificate validation to complete.
ansible.builtin.command: |
aws --profile "{{ aws_acm.aws_profile }}" --region "{{ aws_acm.region }}" \
acm wait certificate-validated \
--certificate-arn "{{ aws_acm_certificate_arn }}"
when:
- not _aws_acm_domain_in_cert_list
- aws_acm.validate

# Even though we wait for validation, it's still too quick.
- name: Wait to allow status cache time to update.
ansible.builtin.pause:
seconds: 5
when:
- not _aws_acm_domain_in_cert_list
- aws_acm.export
- aws_acm.validate

- name: Fetch certificate for later use.
ansible.builtin.command: |
aws --profile "{{ aws_acm.aws_profile }}" --region "{{ aws_acm.region }}" \
acm get-certificate \
--certificate-arn "{{ aws_acm_certificate_arn }}"
register: _aws_acm_exported_certificate_json
when:
- not _aws_acm_domain_in_cert_list
- aws_acm.export
- aws_acm.validate

- name: Replace JSON certificate output with parsed results.
ansible.builtin.set_fact:
aws_acm_exported_certificate: "{{ _aws_acm_exported_certificate_json.stdout | from_json }}"
when:
- not _aws_acm_domain_in_cert_list
- aws_acm.export
- aws_acm.validate
# Set of tasks to run if a certificate is created.
- name: Handle new certificate actions.
when: not _aws_acm_domain_in_cert_list or not _aws_acm_extra_domains_in_cert_list
block:
- name: Stash the old certificate ARN in case we want to delete it later.
ansible.builtin.set_fact:
aws_acm_obsolete_certificate_arn: "{{ aws_acm_certificate_arn }}"
when:
- aws_acm_certificate_arn | length > 0
- aws_acm_certificate_arn != _aws_acm_new_certificate.CertificateArn

- name: Fetch the new certificate's ARN.
ansible.builtin.set_fact:
aws_acm_certificate_arn: "{{ _aws_acm_new_certificate.CertificateArn }}"

# Not currently possible to do this with the API, so we just pause 5 seconds - this is usually enough time.
- name: Wait until the new certificate is properly issued.
ansible.builtin.pause:
seconds: 5
when:
- aws_acm.validate

- name: Obtain all information for a the new ACM certificate.
community.aws.acm_certificate_info:
region: "{{ aws_acm.region }}"
profile: "{{ aws_acm.aws_profile }}"
certificate_arn: "{{ aws_acm_certificate_arn }}"
register: _aws_acm_new_certificate
when:
- aws_acm.validate

- name: Initialise the DNS loop var with main domain entry DNS settings.
ansible.builtin.set_fact:
_acm_dns_all_domains:
- domain: "{{ aws_acm.domain_name }}"
zone: "{{ aws_acm.route_53.zone }}"
aws_profile: "{{ aws_acm.route_53.aws_profile }}"
when:
- aws_acm.route_53.zone is defined
- aws_acm.route_53.zone | length > 0
- aws_acm.validate

- name: Add extra_domains so we can loop through DNS records.
ansible.builtin.set_fact:
_acm_dns_all_domains: "{{ _acm_dns_all_domains + [{'domain': item.domain, 'zone': item.zone, 'aws_profile': item.aws_profile}] }}"
loop: "{{ aws_acm.extra_domains }}"
when:
- aws_acm.extra_domains | length > 0
- aws_acm.validate

- name: Add a DNS records in Route 53 for validation.
amazon.aws.route53:
state: present
profile: "{{ item.aws_profile }}"
zone: "{{ item.zone }}"
record: "{{ (_aws_acm_new_certificate.certificates[0].domain_validation_options | selectattr('domain_name', 'search', item.domain))[0].resource_record.name }}"
type: CNAME
value: "{{ (_aws_acm_new_certificate.certificates[0].domain_validation_options | selectattr('domain_name', 'search', item.domain))[0].resource_record.value }}"
overwrite: true
loop: "{{ _acm_dns_all_domains }}"
when:
- aws_acm.route_53.zone is defined
- aws_acm.route_53.zone | length > 0
- aws_acm.validate

- name: Wait for ACM certificate validation to complete.
ansible.builtin.command: |
aws --profile "{{ aws_acm.aws_profile }}" --region "{{ aws_acm.region }}" \
acm wait certificate-validated \
--certificate-arn "{{ aws_acm_certificate_arn }}"
when:
- aws_acm.validate

# Even though we wait for validation, it's still too quick.
- name: Wait to allow status cache time to update.
ansible.builtin.pause:
seconds: 5
when:
- aws_acm.export
- aws_acm.validate

- name: Fetch certificate for later use.
ansible.builtin.command: |
aws --profile "{{ aws_acm.aws_profile }}" --region "{{ aws_acm.region }}" \
acm get-certificate \
--certificate-arn "{{ aws_acm_certificate_arn }}"
register: _aws_acm_exported_certificate_json
when:
- aws_acm.export
- aws_acm.validate

- name: Replace JSON certificate output with parsed results.
ansible.builtin.set_fact:
aws_acm_exported_certificate: "{{ _aws_acm_exported_certificate_json.stdout | from_json }}"
when:
- aws_acm.export
- aws_acm.validate
2 changes: 1 addition & 1 deletion roles/aws/aws_ec2_autoscale_cluster/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ aws_ec2_autoscale_cluster:
extra_domains: [] # list of Subject Alternative Name domains and zones
# - domain: www2.example.com
# zone: example.com
# aws_profile: us-east-1
# aws_profile: "{{ _aws_profile }}"
route_53:
aws_profile: another # the zone might not be in the same account as the certificate
zone: example.com
Expand Down
2 changes: 1 addition & 1 deletion roles/aws/aws_ec2_autoscale_cluster/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ aws_ec2_autoscale_cluster:
extra_domains: [] # list of Subject Alternative Name domains and zones
# - domain: www2.example.com
# zone: example.com
# aws_profile: us-east-1
# aws_profile: "{{ _aws_profile }}"
route_53:
aws_profile: another # the zone might not be in the same account as the certificate
zone: example.com
Expand Down
4 changes: 4 additions & 0 deletions roles/aws/aws_ec2_autoscale_cluster/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@
TargetGroupName: "{{ aws_ec2_autoscale_cluster.name }}"
when: aws_ec2_autoscale_cluster.create_elb

# @TODO - we can use the aws_acm_obsolete_certificate_arn variable to tidy up previous ACM certs, if it is defined.

- name: Add HTTP listeners.
ansible.builtin.set_fact:
_aws_ec2_autoscale_cluster_listeners: "{{ [_aws_ec2_autoscale_cluster_listeners_http] }}"
Expand Down Expand Up @@ -720,6 +722,8 @@
- aws_ec2_autoscale_cluster.cloudfront.create_distribution
- _cf_certificate_ARN | length > 1

# @TODO - we can use the aws_acm_obsolete_certificate_arn variable to tidy up previous ACM certs, if it is defined.

- name: Add DNS records in Route 53.
amazon.aws.route53:
state: "{{ aws_ec2_autoscale_cluster.state }}"
Expand Down