Skip to content
Open
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ dist-ssr
*.njsproj
*.sln
*.sw?
cdk.out/
dist/
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
## Task 2 Deployment

### Links

- CloudFront URL: https://ddiqx6yb3n1i1.cloudfront.net/
- S3 Website URL: https://shopspastack-shopspabucketdbbc81aa-nxlouka9tkuc.s3.eu-central-1.amazonaws.com/index.html

### Notes

- Application is deployed to S3.
- CloudFront distribution is configured.
- Direct S3 bucket access returns 403 Access Denied.
- Deployment is automated with AWS CDK.

# React-shop-cloudfront

This is frontend starter project for nodejs-aws mentoring program. It uses the following technologies:
Expand Down
3 changes: 3 additions & 0 deletions cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"app": "node cdk/bin/app.cjs"
}
12 changes: 12 additions & 0 deletions cdk/bin/app.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env node

const cdk = require('aws-cdk-lib');
const { ShopSpaStack } = require('../lib/shop-spa-stack.cjs');

const app = new cdk.App();

new ShopSpaStack(app, 'ShopSpaStack', {
env: {
region: 'eu-central-1',
},
});
60 changes: 60 additions & 0 deletions cdk/lib/shop-spa-stack.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const path = require('path');
const cdk = require('aws-cdk-lib');
const { Stack, RemovalPolicy, Duration } = cdk;
const { Construct } = require('constructs');
const { Bucket, BlockPublicAccess } = require('aws-cdk-lib/aws-s3');
const {
Distribution,
ViewerProtocolPolicy,
OriginAccessIdentity,
} = require('aws-cdk-lib/aws-cloudfront');
const { S3Origin } = require('aws-cdk-lib/aws-cloudfront-origins');
const { BucketDeployment, Source } = require('aws-cdk-lib/aws-s3-deployment');

class ShopSpaStack extends Stack {
constructor(scope, id, props) {
super(scope, id, props);

const bucket = new Bucket(this, 'ShopSpaBucket', {
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
removalPolicy: RemovalPolicy.DESTROY,
autoDeleteObjects: true,
});

const originAccessIdentity = new OriginAccessIdentity(this, 'ShopSpaOAI');
bucket.grantRead(originAccessIdentity);

const distribution = new Distribution(this, 'ShopSpaDistribution', {
defaultRootObject: 'index.html',
defaultBehavior: {
origin: new S3Origin(bucket, {
originAccessIdentity,
}),
viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
},
errorResponses: [
{
httpStatus: 403,
responseHttpStatus: 200,
responsePagePath: '/index.html',
ttl: Duration.minutes(0),
},
{
httpStatus: 404,
responseHttpStatus: 200,
responsePagePath: '/index.html',
ttl: Duration.minutes(0),
},
],
});

new BucketDeployment(this, 'ShopSpaDeployment', {
sources: [Source.asset(path.join(__dirname, '../../dist'))],
destinationBucket: bucket,
distribution,
distributionPaths: ['/*'],
});
}
}

module.exports = { ShopSpaStack };
Loading