This is how the https://hedgerules.micahrl.com documentation site is deployed.
These resources live in a dedicated AWS sub-account. The DNS zone for micahrl.com is in a separate account; DNS records are created out of band.
See Deployment for background on the stage model.
Configuration files:
- Hugo configs
_default/hugo.tomlproduction/hugo.toml(overrides for the production environment)
hedgerules.tomlGNUmakefile
See Demonstration for examples of Hedgerules features on this site.
Prerequisites#
- AWS CLI configured with credentials for the site sub-account
- All stacks must be deployed in us-east-1 (required for ACM certificates used by CloudFront)
- Access to the DNS account or provider to create records for micahrl.com
Initial deployment#
In the initial deployment, we have to handle some things manually related to DNS, so this is broken into 5 stages.
Stage 1: base infrastructure#
Deploy base.cfn.yml.
This creates the S3 bucket, OAC, ACM certificate, KVS stores, and IAM group.
make cfn-baseOn the first deployment, the stack will pause waiting for ACM certificate validation. In a second terminal, find the validation CNAME:
# Get the validation CNAME record
aws acm describe-certificate \
--region us-east-1 \
--certificate-arn "$(aws acm list-certificates --region us-east-1 --query "CertificateSummaryList[?DomainName=='hedgerules.micahrl.com'].CertificateArn" --output text)" \
--query 'Certificate.DomainValidationOptions[0].ResourceRecord'Switch to the DNS account (or your external DNS provider) and create the CNAME record returned above. Once DNS propagates, ACM validates the certificate and the CloudFormation stack completes.
Once complete, make saves the stack outputs to dist/base.outputs.json.
These are used automatically by the stage 4 target.
It also displays these values.
Copy the ContentBucketName into the Hugo configuration for hugo deploy.
Stage 2: build#
make hugo-buildThis calls hugo with the appropriate configuration.
Stage 3: hedgerules deploy#
make hedgerules-deployOn the first run this creates the CloudFront Functions. On subsequent runs it updates their code and syncs KVS entries.
Stage 4: distribution#
Deploy distribution.cfn.yml.
The make target reads stage 1 outputs from dist/base.outputs.json
and passes them as parameters automatically.
make cfn-distributionIf base.cfn.yml has changed since the last deploy,
make will re-deploy the base stack first.
It will show output like this:
{
"WebsiteURL": "https://hedgerules.micahrl.com",
"DistributionId": "ET01CEXG1S3P9",
"DistributionDomainName": "d447g1zqgagy6.cloudfront.net"
}Switch to the DNS account and CNAME hedgerules.micahrl.com
to the distribution domain name (d447g1zqgagy6.cloudfront.net in this case).
The DistributionId value is also in the outputs file.
You need it for the cloudFrontDistributionID setting in hugo.toml.
Stage 5: upload content#
make hugo-deploySubsequent deployments#
After the initial deployment, we can use a single make target to handle all stages:
make deployUnless something about the AWS resources needs to change, only stages 2, 3, and 5 need to be run. You could invoke this explicitly to avoid regenerating the CloudFormation outputs if you want (maybe useful in CI):
make hugo-build hedgerules-deploy hugo-deployCI/CD#
Hedgerules uses GitHub actions to deploy the AWS infrastructure and the site content.
IAM setup#
To enable this, there is a third CloudFormation template that provisions an IAM group.
Members of this group can deploy CloudFormation stacks and run make deploy.
This stack is deployed once, manually.
Template: infra/ci/ci.cfn.yml
Deploy it with:
aws cloudformation deploy \
--region us-east-1 \
--template-file infra/ci/ci.cfn.yml \
--stack-name hedgerules-ci \
--capabilities CAPABILITY_NAMED_IAMThen, create an IAM user, add it to the group, and generate its access keys.
# Create the user and add to the CI group
aws iam create-user --user-name hedgerules-ci | cat
aws iam add-user-to-group \
--user-name hedgerules-ci \
--group-name hedgerules-ci-ci
# Generate access keys
aws iam create-access-key --user-name hedgerules-ciNote that these access keys are shown only once, so make sure to save them for the next step.
GitHub Actions#
Add the AccessKeyId and SecretAccessKey from the output as repository secrets
AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in your GitHub Actions settings.
The workflow that deploys this site is found here:
It isn’t related to deploying the site, but for completeness we can also link to the workflow that builds the Go binary and uploads it to GitHub releases: