constructor()

in lib/static-site-stack.ts [16:69]


  constructor(scope: cdk.Construct, id: string, props?: StaticSiteStackProps) {
    super(scope, id, props);

    this.bucket = new s3.Bucket(this, "StaticSiteBucket", {
      bucketName: props?.bucketName,
      removalPolicy: cdk.RemovalPolicy.DESTROY, // not for Production !
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
    });

    const originAccessIdentity = new cloudfront.OriginAccessIdentity(
      this,
      "StaticSiteOrigin"
    );

    this.distribution = new cloudfront.Distribution(this, "StaticSite", {
      defaultBehavior: {
        origin: new origins.S3Origin(this.bucket, {
          originAccessIdentity,
        }),
        viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
      },
      defaultRootObject: "index.html",
      errorResponses: [{ httpStatus: 404, responsePagePath: "/notfound.html" }],
      priceClass: PriceClass.PRICE_CLASS_100, // reduce cost by using only USA and EU edges nodes
    });

    // We'll allow the Origin Access Identity the ListBucket privilege,
    // so that accessing a non-existent object raises 404 instead of 403
    this.bucket.addToResourcePolicy(
      new iam.PolicyStatement({
        effect: iam.Effect.ALLOW,
        actions: ["s3:ListBucket"],
        principals: [originAccessIdentity.grantPrincipal],
        resources: [this.bucket.bucketArn],
      })
    );

    // Allow object access too
    // CDK would do this automatically if we did not manually allow s3:ListBucket above
    this.bucket.addToResourcePolicy(
      new iam.PolicyStatement({
        effect: iam.Effect.ALLOW,
        actions: ["s3:GetObject"],
        principals: [originAccessIdentity.grantPrincipal],
        resources: [this.bucket.arnForObjects("*")],
      })
    );

    new cdk.CfnOutput(this, "CloudFrontURL", {
      value: "https://" + this.distribution.distributionDomainName,
      description: "The path of the site",
      exportName: "CloudFrontURL",
    });
  }