@cnunciato/pulumi-jamstack-aws
v0.1.3
Published
A Pulumi component for managing static websites and serverless APIs on AWS.
Downloads
26
Maintainers
Readme
pulumi-jamstack-aws
A Pulumi component for managing JAMstack websites on AWS. (What's a JAMstack?)
Why do I need this component?
Making static websites is easy, but deploying them — into the cloud, on your own — is hard. This component aims to make that whole process a little less painful.
What does it do?
Given a folder containing a static website, an optional domain name, and an optional set of URL routes and accompanying functions, the component deploys the website on Amazon S3, gives it a domain name with Route 53, distributes it globally with CloudFront (including SSL/TLS), and deploys the functions as a set of serverless endpoints with AWS API Gateway.
Using the component
Step 0: Install Pulumi
If you haven't already, install Pulumi with your package manager of choice.
$ brew install pulumi
Step 1. Make a static website
If you don't already have a folder containing a static website, create an empty folder, then put a static website into it. The following snippet creates a new React app, runs an initial build, and places the built website into the build
folder.
$ npx create-react-app site
$ cd site
$ npm run build
$ cd ..
At this point, you'll have just the site
folder containing your static-website source and build:
$ ls
site
$ ls site/build
... index.html ...
Step 2. Create a Pulumi project and stack
Make a new folder alongside the site
folder for the Pulumi project and stack, change to that folder, and run the new-project wizard, following the prompts:
$ mkdir infra && cd infra
$ pulumi new aws-typescript
Step 3. Install this component from npm ✨
Still in the infra
folder, install this component:
$ npm install --save @cnunciato/pulumi-jamstack-aws
Step 4. Declare a website
Replace the contents of infra/index.ts
with the following program (for example), which deploys the ../site/build
folder as a static website on Amazon S3, distributes it globally with a CloudFront CDN, uses a custom domain name (via Route 53) with SSL/TLS, and adds a single serverless API endpoint using AWS Lambda:
import { Website } from "@cnunciato/pulumi-jamstack-aws";
const site = new Website("my-site", {
protocol: "https",
site: {
path: "../site/build",
},
domain: {
name: "nunciato.org",
host: "site-dev",
},
cdn: {
cacheTTL: 10 * 60,
logs: true,
},
api: {
prefix: "api",
routes: [
{
method: "GET",
path: "/hello/{name}",
eventHandler: async (event: any) => {
return {
statusCode: 200,
body: JSON.stringify({
message: `Hello, ${event.pathParameters?.name}!`,
}),
};
},
},
],
},
});
export const {
bucketName,
bucketWebsiteURL,
cdnDomainName,
cdnURL,
apiGatewayURL,
websiteURL,
websiteLogsBucketName,
} = site;
Step 5. Deploy!
Launch the website.
$ pulumi up
Previewing update (dev)
...
Updating (dev)
View Live: https://app.christian.pulumi-dev.io/cnunciato/pulumi-jamstack-aws-test-npm-infra/dev/updates/1
Type Name Status Info
+ pulumi:pulumi:Stack pulumi-jamstack-aws-test-npm-infra-dev created 1 warning; 2 messages
+ └─ pulumi-s3-static-website:index:Website my-site created
+ ├─ aws:apigateway:x:API website-api created
+ │ ├─ aws:iam:Role website-api6ec0544c created
+ │ ├─ aws:lambda:Function website-api6ec0544c created
+ │ ├─ aws:iam:RolePolicyAttachment website-api6ec0544c-4aaabb8e created
+ │ ├─ aws:iam:RolePolicyAttachment website-api6ec0544c-74d12784 created
+ │ ├─ aws:iam:RolePolicyAttachment website-api6ec0544c-a1de8170 created
+ │ ├─ aws:iam:RolePolicyAttachment website-api6ec0544c-b5aeb6b6 created
+ │ ├─ aws:iam:RolePolicyAttachment website-api6ec0544c-6c156834 created
+ │ ├─ aws:iam:RolePolicyAttachment website-api6ec0544c-7cd09230 created
+ │ ├─ aws:iam:RolePolicyAttachment website-api6ec0544c-e1a3786d created
+ │ ├─ aws:iam:RolePolicyAttachment website-api6ec0544c-019020e7 created
+ │ ├─ aws:iam:RolePolicyAttachment website-api6ec0544c-1b4caae3 created
+ │ ├─ aws:apigateway:RestApi website-api created
+ │ ├─ aws:apigateway:Deployment website-api created
+ │ ├─ aws:lambda:Permission website-api-c4bbce9d created
+ │ └─ aws:apigateway:Stage website-api created
+ ├─ pulumi:providers:aws website-cert-provider created
+ ├─ aws:s3:Bucket website-logs-bucket created
+ ├─ aws:s3:Bucket website-bucket created
+ ├─ aws:acm:Certificate website-cert created
+ ├─ aws:route53:Record website-cert-validation-record created
+ ├─ aws:cloudfront:Distribution website-cdn created
+ ├─ aws:acm:CertificateValidation website-cert-validation created
+ └─ aws:route53:Record site-dev.nunciato.org created
Diagnostics:
pulumi:pulumi:Stack (pulumi-jamstack-aws-test-npm-infra-dev):
warning: Default document "404.html" does not exist.
Uploading 19 files from ../site/build...
Uploaded 19 files.
Outputs:
apiGatewayURL : "https://u7kqxfecol.execute-api.us-west-2.amazonaws.com/api/"
bucketName : "website-bucket-bf3bb7b"
bucketWebsiteURL : "http://website-bucket-bf3bb7b.s3-website-us-west-2.amazonaws.com"
cdnDomainName : "d2kgpg37ae61cs.cloudfront.net"
cdnURL : "https://d2kgpg37ae61cs.cloudfront.net"
websiteLogsBucketName: "website-logs-bucket-cdddca9"
websiteURL : "https://site-dev.nunciato.org"
Resources:
+ 26 created
Duration: 4m8s
Step 6. Browse to the website and query the API endpoint
$ open $(pulumi stack output websiteURL)
$ curl -v $(pulumi stack output websiteURL)/api/hello/chris
{"message":"Hello, chris!"}
Step 7. (Optional) Tear it all down
$ pulumi destroy -y
...
Destroying (dev)
...
Resources:
- 26 deleted
Duration: 4m12s