Pulumi Typescript Project to deploy static website content and infrastructure via IAC (infrastructure-as-code).
Infrastructure components: S3 Buckets, Cloudfront, Cloudfront Functions ACM SSL Certs, AWS Route 53 DNS, WebACL
Content: A Website to publish blog posts
hint: Beware of potential costs that the WebACL causes. Should be a fixed amount arround $6 per month without the usage based price component.
Prerequs:
- Some Pulumi KnowHow
- Basic Typescript Node Knowledge
- An AWS account with AdministratorAccess or similar permissionSet
- AWS knowledge, alternative knowledge in some other hyperscaler (Azure, GCP) should be sufficient
Dependencies:
Login to your AWS account with your terminal. I highly recommend using AWS SSO in combination with a configured AWS profile. More details on different options to sign in here.
Test that you are logged into the right account:
aws sts get-caller-identity --profile <your-profile>
Choose a name for your Pulumi Backend export it as env var to your terminal...
export PULUMI_BACKEND=<your-pulumi-backend-name>
...and create the s3 bucket holding later holding the remote state of the IAC project by doing the following. Only execute this command once at inital setup of the project:
aws s3 mb s3://$PULUMI_BACKEND
Login to Pulumi Backend:
pulumi login s3://$PULUMI_BACKEND
Build the project using yarn:
yarn
Choose a name for your Pulumi Stack and create the stack:
export PULUMI_STACK_NAME=<your-stack-name>
pulumi stack init $PULUMI_STACK_NAME
For now we simple go with passphrase as secrets provider. Just choose a proper one and enter it to the prompt
Static content gets picked up from the folder ./public
. So put all your HTML, CSS, etc. in there.
E.g. to just test the deployment, create a new file called index.html
in the public folder
<html>
<head>
<title>Hello Static Website</title><meta charset="UTF-8">
</head>
<body>
<p>Hello, world! Still under construction. 🏗 </p>
</body>
</html>
pulumi preview
Pulumi might prompt you for missing configs. In the end it should create a stack .yaml
-file containing all pulumi configs. You can think of them as environment variables for your infrastructure project:
./Pulumi.my-cool-blog-prod.yaml
encryptionsalt: v1:abcDEF123XZW=:v1:ABC123//:12345678xxxxxxxxxxxx
config:
static-website:pathToWebsiteContents: public
static-website:targetDomain: blog.mycooldomain.com
static-website:author: JonDoe
static-website:organization: JonDoesOrg
Hint: Dont worry about commiting the
encryptionsalt
. It's the encryption salt of your PULUMI_PASSPHRASE and NOT a secret.
pulumi up
(will deploy all infrastructure needed to host the static content and sync the content in the local ./public
folder with the s3 bucket.)
Add the .yaml
-file with the configs to your source code version control similar to ensure smooth login next time you want to conduct a change. The PULUMI_PASSPHRASE you should keep secret though. I'd recommend to share within your infrastructure team in your favorite seretmanager.
Congrats! 🥳 You successfully deployed a static edge optimized website via IAC.
TODOs:
- Solution for uncommenting bucketPublicAccessBlock before deploying to the bucket
- Add a on/off switch to WebACL
Refs:
- Special thanks to the creators of My Starting Example: Github - Pulumi Examples
- Pulumi Docs - Starting Sample
- Github - Starting sample with outdated code
- WebACL to block direct access to cloudfront.net URL
- AWS Docs - Cloudfront Origin access control
- Cloudfront Functions
- AWS Docs - Troubleshooting Cloudfront
- Discussion on CF Function vs. Lambda@Edge
- AWS Cloudfront Sample Functions
- AWS Docs - Example Function Add Index
- Github - CF Functions for Pulumi