diff --git a/java/static-site/README.md b/java/static-site/README.md deleted file mode 100644 index 549e90fa27..0000000000 --- a/java/static-site/README.md +++ /dev/null @@ -1,54 +0,0 @@ - -# Static site - ---- - -![Stability: Experimental](https://img.shields.io/badge/stability-Experimental-important.svg?style=for-the-badge) - -> **This is an experimental example. It may not build out of the box** -> -> This examples is built on Construct Libraries marked "Experimental" and may not be updated for latest breaking changes. -> -> If build is unsuccessful, please create an [issue](https://github.com/aws-samples/aws-cdk-examples/issues/new) so that we may debug the problem - ---- - - -This example creates the infrastructure for a static site, which uses an S3 bucket for storing the content. The site contents (located in the 'site-contents' sub-directory) are deployed to the bucket. - -The site redirects from HTTP to HTTPS, using a CloudFront distribution, Route53 alias record, and ACM certificate. - -## Prep - -The domain for the static site (i.e. mystaticsite.com) must be configured as a hosted zone in Route53 prior to deploying this example. For instructions on configuring Route53 as the DNS service for your domain, see the [Route53 documentation](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-configuring.html). - - -## Building - -To build this app, run `mvn compile`. This will download the required -dependencies to compile the Java code. - -You can use your IDE to write code and unit tests, but you will need to use the -CDK toolkit if you wish to synthesize/deploy stacks. - -## CDK Toolkit - -The [`cdk.json`](./cdk.json) file in the root of this repository includes -instructions for the CDK toolkit on how to execute this program. - -Specifically, it will tell the toolkit to use the `mvn exec:java` command as the -entry point of your application. After changing your Java code, you will be able -to run the CDK toolkit commands as usual (Maven will recompile as needed): - - $ cdk ls - - - $ cdk synth -c domain=mystaticsite.com -c subdomain=www - - - $ cdk deploy -c domain=mystaticsite.com -c subdomain=www - - - $ cdk diff -c domain=mystaticsite.com -c subdomain=www - - diff --git a/java/static-site/cdk.json b/java/static-site/cdk.json deleted file mode 100644 index c4c9a53ae0..0000000000 --- a/java/static-site/cdk.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "app": "mvn exec:java -Dexec.mainClass=software.amazon.awscdk.examples.StaticSiteApp" -} diff --git a/java/static-site/pom.xml b/java/static-site/pom.xml deleted file mode 100644 index 53e00dd17d..0000000000 --- a/java/static-site/pom.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - 4.0.0 - - com.amazonaws.cdk - static-site - 1.0.0 - - - UTF-8 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.7.0 - - 1.8 - 1.8 - - - - - org.apache.maven.plugins - maven-assembly-plugin - 3.1.0 - - - jar-with-dependencies - - - - com.amazonaws.cdk.examples.StaticSiteApp - - - - - - make-assembly - package - - single - - - - - - - - - - - software.amazon.awscdk - aws-cdk-lib - [2.0.0,) - - - - software.constructs - constructs - [10.0.0,) - - - - - junit - junit - 4.13.1 - test - - - diff --git a/java/static-site/site-contents/error.html b/java/static-site/site-contents/error.html deleted file mode 100644 index 0240c8288b..0000000000 --- a/java/static-site/site-contents/error.html +++ /dev/null @@ -1,6 +0,0 @@ - -
Hello world: Error
- -Uh oh, you reached the error page! - - diff --git a/java/static-site/site-contents/index.html b/java/static-site/site-contents/index.html deleted file mode 100644 index 139707c92c..0000000000 --- a/java/static-site/site-contents/index.html +++ /dev/null @@ -1,6 +0,0 @@ - -
Hello world
- -Hello, world! - - diff --git a/java/static-site/src/main/java/software/amazon/awscdk/examples/StaticSiteApp.java b/java/static-site/src/main/java/software/amazon/awscdk/examples/StaticSiteApp.java deleted file mode 100644 index 135ee4187c..0000000000 --- a/java/static-site/src/main/java/software/amazon/awscdk/examples/StaticSiteApp.java +++ /dev/null @@ -1,48 +0,0 @@ -package software.amazon.awscdk.examples; - -import java.util.HashMap; -import java.util.Map; -import software.amazon.awscdk.App; -import software.amazon.awscdk.Environment; -import software.amazon.awscdk.Stack; -import software.amazon.awscdk.StackProps; - -public class StaticSiteApp extends Stack { - - /** - * This stack relies on getting the domain name from CDK context. Use 'cdk synth -c - * domain=mystaticsite.com -c subdomain=www' Or add the following to cdk.json: { "context": { - * "domain": "mystaticsite.com", "subdomain": "www" } } - */ - public StaticSiteApp(App scope, String id, StackProps props) { - super(scope, id, props); - - // Getting domain and subdomain values from Context - - Map domainValues = new HashMap(); - domainValues.put("domainName", this.getNode().tryGetContext("domain")); - domainValues.put("siteSubDomain", this.getNode().tryGetContext("subdomain")); - - // Call StaticSiteStack to create the stack - new StaticSiteStack(this, "MyStaticSite", domainValues); - } - - public static void main(final String argv[]) { - - App app = new App(); - - // Stack must be in us-east-1, because the ACM certificate for a - // global CloudFront distribution must be requested in us-east-1. - StackProps pr = - new StackProps.Builder() - .env( - Environment.builder() - .region("us-east-1") - .account(System.getenv("CDK_DEFAULT_ACCOUNT")) - .build()) - .build(); - - new StaticSiteApp(app, "MyStaticSite", pr); - app.synth(); - } -} diff --git a/java/static-site/src/main/java/software/amazon/awscdk/examples/StaticSiteStack.java b/java/static-site/src/main/java/software/amazon/awscdk/examples/StaticSiteStack.java deleted file mode 100644 index 162e0699c6..0000000000 --- a/java/static-site/src/main/java/software/amazon/awscdk/examples/StaticSiteStack.java +++ /dev/null @@ -1,147 +0,0 @@ -package software.amazon.awscdk.examples; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import software.amazon.awscdk.CfnOutput; -import software.constructs.Construct; -import software.amazon.awscdk.RemovalPolicy; -import software.amazon.awscdk.Stack; -import software.amazon.awscdk.services.certificatemanager.DnsValidatedCertificate; -import software.amazon.awscdk.services.certificatemanager.ICertificate; -import software.amazon.awscdk.services.cloudfront.Behavior; -import software.amazon.awscdk.services.cloudfront.CloudFrontWebDistribution; -import software.amazon.awscdk.services.cloudfront.S3OriginConfig; -import software.amazon.awscdk.services.cloudfront.SSLMethod; -import software.amazon.awscdk.services.cloudfront.SecurityPolicyProtocol; -import software.amazon.awscdk.services.cloudfront.SourceConfiguration; -import software.amazon.awscdk.services.cloudfront.ViewerCertificate; -import software.amazon.awscdk.services.cloudfront.ViewerCertificateOptions; -import software.amazon.awscdk.services.route53.ARecord; -import software.amazon.awscdk.services.route53.HostedZone; -import software.amazon.awscdk.services.route53.HostedZoneProviderProps; -import software.amazon.awscdk.services.route53.IHostedZone; -import software.amazon.awscdk.services.route53.RecordTarget; -import software.amazon.awscdk.services.route53.targets.CloudFrontTarget; -import software.amazon.awscdk.services.s3.Bucket; -import software.amazon.awscdk.services.s3.deployment.BucketDeployment; -import software.amazon.awscdk.services.s3.deployment.ISource; -import software.amazon.awscdk.services.s3.deployment.Source; - -public class StaticSiteStack extends Stack { - - /** - * Static site infrastructure, which deploys site content to an S3 bucket. - * - *

The site redirects from HTTP to HTTPS, using a CloudFront distribution, Route53 alias - * record, and ACM certificate. - */ - public StaticSiteStack(Construct scope, String id, Map props) { - super(scope, id); - - try { - - final IHostedZone zone = - HostedZone.fromLookup( - this, - "Zone", - HostedZoneProviderProps.builder() - .domainName(props.get("domainName").toString()) - .build()); - - final String siteDomain = - props.get("siteSubDomain").toString() + '.' + props.get("domainName").toString(); - List siteDomainList = new ArrayList<>(1); - siteDomainList.add(siteDomain); - - // Site URL CfnOutput variable - CfnOutput.Builder.create(this, "Site") - .description("Site Domain Url") - .value("https://" + siteDomain) - .build(); - - // S3 Bucket resource and Content - Bucket siteBucket = - Bucket.Builder.create(this, "SiteBucket") - .bucketName(siteDomain) - .websiteIndexDocument("index.html") - .websiteErrorDocument("error.html") - .publicReadAccess(false) - // The default removal policy is RETAIN, which means that cdk destroy will not attempt - // to delete - // the new bucket, and it will remain in your account until manually deleted. By - // setting the policy to - // DESTROY, cdk destroy will attempt to delete the bucket, but will error if the - // bucket is not empty. - .removalPolicy(RemovalPolicy.DESTROY) - .build(); - - CfnOutput.Builder.create(this, "Bucket") - .description("Bucket Name") - .value(siteBucket.getBucketName()) - .build(); - - // TLS certificate - final ICertificate certificate = - DnsValidatedCertificate.Builder.create(this, "SiteCertificate") - .domainName(siteDomain) - .hostedZone(zone) - .build(); - - CfnOutput.Builder.create(this, "Certificate") - .description("Certificate ARN") - .value(certificate.getCertificateArn()) - .build(); - - // CloudFront distribution that provides HTTPS - - List behavioursList = new ArrayList<>(1); - behavioursList.add(Behavior.builder().isDefaultBehavior(true).build()); - - List sourceConfigurationsList = new ArrayList<>(1); - sourceConfigurationsList.add( - SourceConfiguration.builder() - .s3OriginSource(S3OriginConfig.builder().s3BucketSource(siteBucket).build()) - .behaviors(behavioursList) - .build()); - - CloudFrontWebDistribution distribution = - CloudFrontWebDistribution.Builder.create(this, "SiteDistribution") - .viewerCertificate(ViewerCertificate.fromAcmCertificate(certificate, ViewerCertificateOptions - .builder() - .aliases(siteDomainList) - .sslMethod(SSLMethod.SNI) - .securityPolicy(SecurityPolicyProtocol.TLS_V1_1_2016) - .build() - )) - .originConfigs(sourceConfigurationsList) - .build(); - - CfnOutput.Builder.create(this, "DistributionId") - .description("CloudFront Distribution Id") - .value(distribution.getDistributionId()) - .build(); - - // Route53 alias record for the CloudFront distribution - - ARecord.Builder.create(this, "SiteAliasRecord") - .recordName(siteDomain) - .target(RecordTarget.fromAlias(new CloudFrontTarget(distribution))) - .zone(zone) - .build(); - - // Deploy site contents to S3 bucket - List sources = new ArrayList<>(1); - sources.add(Source.asset("./site-contents")); - - BucketDeployment.Builder.create(this, "DeployWithInvalidation") - .sources(sources) - .destinationBucket(siteBucket) - .distribution(distribution) - .build(); - - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/python/static-site/README.md b/python/static-site/README.md deleted file mode 100644 index 6bd6c7d8fa..0000000000 --- a/python/static-site/README.md +++ /dev/null @@ -1,102 +0,0 @@ -# Static Site with AWS CDK -This sample project uses S3, CloudFront and Route53 to create a stack for -hosting static web sites. - -![Architecture](static-site.png) - -## Prerequisites -- A registered domain in Route53. -- If using a public S3 bucket, a secret phrase needs to be created in the parameter store. The name of the parameter to be passed in the context as `origin_custom_header_parameter_name`. Make sure to create the parameter in the same region as the static site. This parameter will be set in both CloudFront and S3 Bucket Policy to make sure only traffic from CloudFront can access the S3 objects. -- If using an existing certificate, make sure it's in the `us-east-1` region otherwise the deployment fails. [See this link](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cnames-and-https-requirements.html#https-requirements-aws-region) - -## Install, Build, Deploy and Clean up -### CDK -Install AWS CDK Toolkit -```sh -npm install -g aws-cdk -``` -Verify the installation -```sh -cdk --version -``` -Bootstrap the AWS environment -``` -cdk bootstrap aws://123456789012/us-east-1 -``` - -### Python Setup -Create a python virtual environment in the root directory of the example. - -```sh -python3 -m venv .env -``` -Activate the virtual environment and install the dependencies. -```sh -source .env/bin/activate -pip install -r requirements -``` - -Synthesize the CloudFromation template. -```sh -cdk synth -``` -Deploy the stack. -> Make sure your aws profile has sufficient permissions to create the resources. Update the `cdk.json` according to your settings. See the [Context Values](#context-values) down below. -```sh -cdk deploy -``` -Clean up and remove the stack. -```sh -cdk destroy -``` - - - - - -## Context Values -Context values are key-value pairs that can be provided to the cdk app. It can be done in [multiple ways](https://docs.aws.amazon.com/cdk/latest/guide/context.html) such as `--context` option to the `cdk` command, or `cdk.json` file. - -- **namespace**: Use as a prefix for the resource names -- **domain_name**: domain name. e.g. example.com -- **sub_domain_name**: If provided, the site will be hosted under the sub domain name (e.g. blog.example.com) -- **enable_s3_website_endpoint**: If `true` it creates a public S3 bucket with website endpoint enabled. Otherwise it creates a private S3 bucket. -- **origin_custom_header_parameter_name**: In case of using a public S3 bucket with website enabled, we can use a custom header (e.g. referer) to block all traffic S3 except from the CloudFront. This parameter is the reference to the parameter in *parameter store* where we keep the secret phrase. -- **domain_certificate_arn**: If provided, CloudFront uses this certificate for the domain. Otherwise, it creates a new certificate. -- **hosted_zone_id**: Route53 Hosted Zone ID for the domain -- **hosted_zone_name**: Route53 Hosted Zone Name for the domain - -### cdk.json examples - -A site with a public S3 bucket. Bucket policy limits the access to s3 objects by using `referer` header. -```json -... - "namespace": "static-site", - "domain_name": "example.com", - "enable_s3_website_endpoint": true, - "origin_custom_header_parameter_name": "/prod/static-site/origin-custom-header/referer", - "hosted_zone_id": "ZABCDE12345", - "hosted_zone_name": "example.com." -... -``` -Above example with a subdomain setup. It hosts the site under `blog.example.com` -```json -... - "namespace": "static-site", - "domain_name": "example.com", - "sub_domain_name": "blog", - "enable_s3_website_endpoint": true, - "origin_custom_header_parameter_name": "/prod/static-site/origin-custom-header/referer", - "hosted_zone_id": "ZABCDE12345", - "hosted_zone_name": "example.com." -... -``` -A site with a private S3 bucket origin. -```json -... - "namespace": "static-site", - "domain_name": "example.com", - "hosted_zone_id": "ZABCDE12345", - "hosted_zone_name": "example.com." -... -``` diff --git a/python/static-site/app.py b/python/static-site/app.py deleted file mode 100644 index fe6e9c8cd8..0000000000 --- a/python/static-site/app.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python3 - -import os -from aws_cdk import App, Environment -from site_stack import StaticSiteStack - - -app = App() -props = { - "namespace": app.node.try_get_context("namespace"), - "domain_name": app.node.try_get_context("domain_name"), - "sub_domain_name": app.node.try_get_context("sub_domain_name"), - "domain_certificate_arn": app.node.try_get_context( - "domain_certificate_arn" - ), - "enable_s3_website_endpoint": app.node.try_get_context( - "enable_s3_website_endpoint" - ), - "origin_custom_header_parameter_name": app.node.try_get_context( - "origin_custom_header_parameter_name" - ), - "hosted_zone_id": app.node.try_get_context("hosted_zone_id"), - "hosted_zone_name": app.node.try_get_context("hosted_zone_name"), -} - -env = Environment( - account=os.environ.get( - "CDK_DEPLOY_ACCOUNT", os.environ.get("CDK_DEFAULT_ACCOUNT") - ), - region=os.environ.get( - "CDK_DEPLOY_REGION", os.environ.get("CDK_DEFAULT_REGION") - ), -) - -StaticSite = StaticSiteStack( - scope=app, - construct_id=f"{props['namespace']}-stack", - props=props, - env=env, - description="Static Site using S3, CloudFront and Route53", -) - -app.synth() diff --git a/python/static-site/cdk.json b/python/static-site/cdk.json deleted file mode 100644 index b149f9cfa6..0000000000 --- a/python/static-site/cdk.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "app": "python3 app.py", - "context": { - "namespace": "static-site", - "domain_name": "example.com", - "enable_s3_website_endpoint": true, - "origin_custom_header_parameter_name": "/prod/static-site/origin-custom-header/referer", - "hosted_zone_id": "ZABCDE12345", - "hosted_zone_name": "example.com." - } -} diff --git a/python/static-site/requirements.txt b/python/static-site/requirements.txt deleted file mode 100644 index 2c27c97005..0000000000 --- a/python/static-site/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -aws-cdk-lib>=2.0.0 -constructs>=10.0.0 -pytest diff --git a/python/static-site/site_stack.py b/python/static-site/site_stack.py deleted file mode 100644 index 34a56a0cea..0000000000 --- a/python/static-site/site_stack.py +++ /dev/null @@ -1,55 +0,0 @@ -from aws_cdk import CfnOutput, Stack -from static_site import StaticSitePublicS3, StaticSitePrivateS3 - - -class StaticSiteStack(Stack): - def __init__(self, scope, construct_id, props, **kwargs): - super().__init__(scope, construct_id, **kwargs) - - site_domain_name = props["domain_name"] - if props["sub_domain_name"]: - site_domain_name = ( - f'{props["sub_domain_name"]}.{props["domain_name"]}' - ) - - # If S3 website endpoint enabled, it creates the static site using a - # public S3 as the origin. Otherwise, it creates a private S3 as the - # origin. - if props["enable_s3_website_endpoint"]: - site = StaticSitePublicS3( - self, - f"{props['namespace']}-construct", - site_domain_name=site_domain_name, - domain_certificate_arn=props["domain_certificate_arn"], - origin_referer_header_parameter_name=props[ - "origin_custom_header_parameter_name" - ], - hosted_zone_id=props["hosted_zone_id"], - hosted_zone_name=props["hosted_zone_name"], - ) - else: - site = StaticSitePrivateS3( - self, - f"{props['namespace']}-construct", - site_domain_name=site_domain_name, - domain_certificate_arn=props["domain_certificate_arn"], - hosted_zone_id=props["hosted_zone_id"], - hosted_zone_name=props["hosted_zone_name"], - ) - - # Add stack outputs - CfnOutput( - self, - "SiteBucketName", - value=site.bucket.bucket_name, - ) - CfnOutput( - self, - "DistributionId", - value=site.distribution.distribution_id, - ) - CfnOutput( - self, - "CertificateArn", - value=site.certificate.certificate_arn, - ) diff --git a/python/static-site/static-site.png b/python/static-site/static-site.png deleted file mode 100644 index 807bf16ec8..0000000000 Binary files a/python/static-site/static-site.png and /dev/null differ diff --git a/python/static-site/static_site.py b/python/static-site/static_site.py deleted file mode 100644 index 81d1ca003a..0000000000 --- a/python/static-site/static_site.py +++ /dev/null @@ -1,229 +0,0 @@ -""" -Two constructs to host static sites in aws using S3, cloudfront and Route53. - -StaticSitePrivateS3 creates a private S3 bucket and uses S3 API endpoint as -an origin in cloudfront and Origin Access Identity (OAI) to access the s3 objects. - -StaticSitePublicS3 creates a public S3 bucket with website enabled and -uses Origin Custom Header (referer) to limit the access of s3 objects to the -CloudFront only. -""" -from aws_cdk import ( - aws_s3 as s3, - aws_cloudfront as cloudfront, - aws_cloudfront_origins as origins, - aws_certificatemanager as acm, - aws_route53 as route53, - aws_route53_targets as targets, - aws_iam as iam, - aws_ssm as ssm, - RemovalPolicy -) -from constructs import Construct - -class StaticSite(Construct): - """The base class for StaticSite constructs""" - - def __init__( - self, - scope, - construct_id, - site_domain_name, - hosted_zone_id, - hosted_zone_name, - domain_certificate_arn=None, - **kwargs, - ): - super().__init__(scope, construct_id, **kwargs) - - # Public variables - self.bucket = None - self.certificate = None - self.distribution = None - - # Internal variables - self._site_domain_name = site_domain_name - - # Instance Variables - self.__domain_certificate_arn = domain_certificate_arn - self.__hosted_zone_id = hosted_zone_id - self.__hosted_zone_name = hosted_zone_name - - def _build_site(self): - """The Template Method for building the site. - - It uses hook functions which are implemented in the sub classes - """ - # Create the S3 bucket for the site contents - self._create_site_bucket() - - # Get the hosted zone based on the provided domain name - hosted_zone = self.__get_hosted_zone() - - # Get an existing or create a new certificate for the site domain - self.__create_certificate(hosted_zone) - - # create the cloud front distribution - self._create_cloudfront_distribution() - - # Create a Route53 record - self.__create_route53_record(hosted_zone) - - def _create_site_bucket(self): - """a virtual function to be implemented by the sub classes""" - - def _create_cloudfront_distribution(self): - """a virtual function to be implemented by the sub classes""" - - def __get_hosted_zone(self): - return route53.HostedZone.from_hosted_zone_attributes( - self, - "hosted_zone", - zone_name=self.__hosted_zone_name, - hosted_zone_id=self.__hosted_zone_id, - ) - - def __create_route53_record(self, hosted_zone): - route53.ARecord( - self, - "site-alias-record", - record_name=self._site_domain_name, - zone=hosted_zone, - target=route53.RecordTarget.from_alias( - targets.CloudFrontTarget(self.distribution) - ), - ) - - def __create_certificate(self, hosted_zone): - if self.__domain_certificate_arn: - # If certificate arn is provided, import the certificate - self.certificate = acm.Certificate.from_certificate_arn( - self, - "site_certificate", - certificate_arn=self.__domain_certificate_arn, - ) - else: - # If certificate arn is not provided, create a new one. - # ACM certificates that are used with CloudFront must be in - # the us-east-1 region. - self.certificate = acm.DnsValidatedCertificate( - self, - "site_certificate", - domain_name=self._site_domain_name, - hosted_zone=hosted_zone, - region="us-east-1", - ) - - -class StaticSitePrivateS3(StaticSite): - def __init__( - self, - scope, - construct_id, - **kwargs, - ): - super().__init__(scope, construct_id, **kwargs) - - self._build_site() - - def _create_site_bucket(self): - """Creates a private S3 bucket for the static site construct""" - self.bucket = s3.Bucket( - self, - "site_bucket", - bucket_name=self._site_domain_name, - encryption=s3.BucketEncryption.S3_MANAGED, - block_public_access=s3.BlockPublicAccess.BLOCK_ALL, - removal_policy=RemovalPolicy.DESTROY, - auto_delete_objects=True, - ) - - def _create_cloudfront_distribution(self): - """Create a cloudfront distribution with a private bucket as the origin""" - self.distribution = cloudfront.Distribution( - self, - "cloudfront_distribution", - default_behavior=cloudfront.BehaviorOptions( - origin=origins.S3Origin(self.bucket), - viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, - ), - domain_names=[self._site_domain_name], - certificate=self.certificate, - default_root_object="index.html", - ) - - -class StaticSitePublicS3(StaticSite): - def __init__( - self, - scope, - construct_id, - origin_referer_header_parameter_name, - **kwargs, - ): - super().__init__(scope, construct_id, **kwargs) - - # Get the origin referer header value - self.__origin_referer_header = self.__get_referer_header( - origin_referer_header_parameter_name, - ) - - self._build_site() - - def __get_referer_header(self, parameter_name): - return ssm.StringParameter.from_string_parameter_attributes( - self, "custom_header", parameter_name=parameter_name - ).string_value - - def _create_site_bucket(self): - """Creates a public S3 bucket for the static site construct""" - self.bucket = s3.Bucket( - self, - "site_bucket", - bucket_name=self._site_domain_name, - website_index_document="index.html", - website_error_document="404.html", - removal_policy=RemovalPolicy.DESTROY, - auto_delete_objects=True, - ) - bucket_policy = iam.PolicyStatement( - actions=["s3:GetObject"], - resources=[self.bucket.arn_for_objects("*")], - principals=[iam.AnyPrincipal()], - ) - bucket_policy.add_condition( - "StringEquals", - {"aws:Referer": self.__origin_referer_header}, - ) - - self.bucket.add_to_resource_policy(bucket_policy) - - def _create_cloudfront_distribution(self): - """Create a cloudfront distribution with a public bucket as the origin""" - origin_source = cloudfront.CustomOriginConfig( - domain_name=self.bucket.bucket_website_domain_name, - origin_protocol_policy=cloudfront.OriginProtocolPolicy.HTTP_ONLY, - origin_headers={"Referer": self.__origin_referer_header}, - ) - - self.distribution = cloudfront.CloudFrontWebDistribution( - self, - "cloudfront_distribution", - viewer_certificate = cloudfront.ViewerCertificate.from_acm_certificate(self.certificate, - aliases=[self._site_domain_name], - security_policy=cloudfront.SecurityPolicyProtocol.TLS_V1_2_2019, - ssl_method=cloudfront.SSLMethod.SNI - ), - origin_configs=[ - cloudfront.SourceConfiguration( - custom_origin_source=origin_source, - behaviors=[ - cloudfront.Behavior( - is_default_behavior=True, - ) - ], - ) - ], - viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, - price_class=cloudfront.PriceClass.PRICE_CLASS_ALL, - ) diff --git a/python/static-site/tests/__init__.py b/python/static-site/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/python/static-site/tests/test_stacks.py b/python/static-site/tests/test_stacks.py deleted file mode 100644 index 559833c999..0000000000 --- a/python/static-site/tests/test_stacks.py +++ /dev/null @@ -1,61 +0,0 @@ -import pytest - -from aws_cdk import App -from site_stack import StaticSiteStack - - -@pytest.fixture(scope="session") -def synth(): - - app = App( - context={ - "namespace": "static-site", - "domain_name": "example.com", - "domain_certificate_arn": "arn:aws:acm:us-east-1:123456789012:certificate/abc", - "sub_domain_name": "blog", - "origin_custom_header_parameter_name": "/prod/static-site/referer", - "hosted_zone_id": "ZABCEF12345", - "hosted_zone_name": "example.com.", - } - ) - props = { - "namespace": app.node.try_get_context("namespace"), - "domain_name": app.node.try_get_context("domain_name"), - "sub_domain_name": app.node.try_get_context("sub_domain_name"), - "domain_certificate_arn": app.node.try_get_context( - "domain_certificate_arn" - ), - "enable_s3_website_endpoint": app.node.try_get_context( - "enable_s3_website_endpoint" - ), - "origin_custom_header_parameter_name": app.node.try_get_context( - "origin_custom_header_parameter_name" - ), - "hosted_zone_id": app.node.try_get_context("hosted_zone_id"), - "hosted_zone_name": app.node.try_get_context("hosted_zone_name"), - } - StaticSiteStack( - scope=app, - construct_id=props["namespace"], - props=props, - env={"account": "123456789012", "region": "us-east-1"}, - ) - return app.synth() - - -def get_buckets(stack): - return [ - v - for k, v in stack.template["Resources"].items() - if v["Type"] == "AWS::S3::Bucket" - ] - - -def test_created_stacks(synth): - assert {"static-site"} == {x.id for x in synth.stacks} - - -def test_site_bucket(synth): - stack = [x for x in synth.stacks if x.id == "static-site"][0] - buckets = get_buckets(stack) - assert buckets[0]["Properties"]["BucketName"] == "blog.example.com"