Hosting Hugo on Aws Cloudfront and Route53 Using Ansible
It’s really easy to to set up a website on AWS’s s3 service, but if you want to use a certificate (you do), it’s just a bit more work.
With Ansible as my hammer, everything is a nail. Here’s a quick playbook I used to set up my site jxn.is to use cloudfront.
This playbook creates the bucket, sets up an s3 website in the bucket, creates a cloudfront distribution with reasonable parameters, enables an existing Certificate Manager certificate on the site, and points DNS records at the cloudfront distribution.
Before you do this, you need the following set up: 1. Ansible installed locally 2. AWS credentials with a profile (or environment vars, and remove the ‘profile: ‘ properties from the playbook 3. Your Domain and Nameservers set to a zone in Route53 4. A certificate with an ARN in AWS Certificate Manager. This is free and easy to verify if you’re already using Route53.
-
hosts: localhost
gather_facts: false
vars:
aws_profile: YOUR_AWS_PROFILE
aws_region: us-west-2
site_domains:
- jxn.is
- www.jxn.is
domain_zone: jxn.is
domain_zone_id: YOUR_DOMAIN_ZONE_ID_HERE
bucket: jxnis
cloudfront_error_responses:
- error_code: 404
response_page_path: /404.html
response_code: 404
error_caching_min_ttl: 30
cloudfront_cert:
acm_certificate_arn: YOUR_CERT_ARN_HERE
certificate_source: acm
minimum_protocol_version: TLSv1.2_2018
ssl_support_method: sni-only
tasks:
- name: create site bucket
s3_bucket:
name: "{{ bucket }}"
profile: "{{ aws_profile }}"
region: "{{ aws_region }}"
state: present
- name: create s3 website from bucket
s3_website:
name: "{{ bucket }}"
profile: "{{ aws_profile }}"
region: "{{ aws_region }}"
state: present
suffix: index.html
register: s3_website_result
- name: create cloudfront distribution
cloudfront_distribution:
aliases: "{{ site_domains }}"
comment: Static website for {{ domain_zone }}. This distribution is managed by ansible.
custom_error_responses: "{{ cloudfront_error_responses }}"
default_root_object: index.html
ipv6_enabled: true
# NOTE: use the "website" s3 url, not the bare bucket url
origins: ['domain_name': "{{ bucket }}.s3-website-{{ aws_region }}.amazonaws.com"]
price_class: PriceClass_100
profile: "{{ aws_profile }}"
purge_aliases: true
region: "{{ aws_region }}"
state: present
default_cache_behavior: # options for cloudfront cache lifetimes
min_ttl: 30
default_ttl: 900
max_ttl: 1500
viewer_certificate: "{{ cloudfront_cert }}"
register: cloudfront_result
- name: create r53 records pointing to cloudfront distribution
route53:
alias: true
alias_hosted_zone_id: "{{ domain_zone_id }}"
profile: "{{ aws_profile }}"
state: present
ttl: 300
type: A
record: "{{ item }}"
value: "{{ cloudfront_result.domain_name }}"
zone: "{{ domain_zone }}"
overwrite: true
with_items: "{{ site_domains }}"
You’ll definitely need to change the following parameters for your needs: aws_profile, site_domains, domain_zone, bucket, cloudfront_cert.acm_certificate_arn, domain_zone_id
. You’ll probably also want to change the region and some caching values.
Then, don’t forget to copy your site’s static html files into your new bucket.