private CloudFrontWebDistribution generateCloudFront(RestApi api, string name) { var dist = new CloudFrontWebDistribution(this, name + "Distribution", new CloudFrontWebDistributionProps { PriceClass = PriceClass.PRICE_CLASS_ALL, Comment = name, OriginConfigs = new[] { new SourceConfiguration { Behaviors = new IBehavior[] { new Behavior { Compress = true, IsDefaultBehavior = true, DefaultTtl = Duration.Seconds(0) } }, CustomOriginSource = new CustomOriginConfig { DomainName = api.RestApiId + ".execute-api.us-east-1.amazonaws.com", // lazy but quick OriginPath = "/prod", } } } }); new CfnOutput(this, name + "distId", new CfnOutputProps { Value = dist.DistributionDomainName }); return(dist); }
public StaticSiteOnS3WithCloudFront(Stack scope, string id, StaticSiteConstructProps props) : base(scope, id) { var fullDomain = $"{props.SiteSubDomain}.{props.DomainName}"; var siteBucket = new Bucket(this, $"SiteBucket_{id}", new BucketProps { BucketName = $"static-content-{fullDomain}", WebsiteIndexDocument = props.WebsiteIndexDocument, WebsiteErrorDocument = "error.html", PublicReadAccess = true, RemovalPolicy = RemovalPolicy.DESTROY }); var distribution = new CloudFrontWebDistribution(this, $"SiteDistribution_{id}", new CloudFrontWebDistributionProps { AliasConfiguration = new AliasConfiguration() { Names = new string[] { fullDomain }, AcmCertRef = props.CertificateArn, SecurityPolicy = SecurityPolicyProtocol.TLS_V1_2_2019 }, //ViewerCertificate = ViewerCertificate.FromAcmCertificate(certificate), // this syntax doesn't seem to be quite ready for use yet OriginConfigs = new ISourceConfiguration[] { new SourceConfiguration { S3OriginSource = new S3OriginConfig { S3BucketSource = siteBucket }, Behaviors = new Behavior[] { new Behavior() { IsDefaultBehavior = true } } } } }); new ARecord(this, $"SiteAliasRecord_{id}", new ARecordProps { RecordName = fullDomain, Target = RecordTarget.FromAlias(new CloudFrontTarget(distribution)), Zone = props.Zone }); new BucketDeployment(this, $"DeployWithInvalidation_{id}", new BucketDeploymentProps { Sources = new ISource[] { Source.Asset(props.WebsiteFilesPath) }, DestinationBucket = siteBucket, Distribution = distribution, DistributionPaths = new string[] { "/*" } }); scope.Log($"CloudFrontSite_{props.DomainName}", $"https://{fullDomain}"); scope.Log($"StaticWebsiteBucket_{props.DomainName}", siteBucket.BucketName); }
public WebApplicationStack(Construct parent, string id) : base(parent, id) { // Create a S3 bucket, with the given name and define the web index document as 'index.html' var bucket = new Bucket(this, "Bucket", new BucketProps { WebsiteIndexDocument = "index.html" }); // Obtain the cloudfront origin access identity so that the s3 bucket may be restricted to it. var origin = new CfnCloudFrontOriginAccessIdentity(this, "BucketOrigin", new CfnCloudFrontOriginAccessIdentityProps { CloudFrontOriginAccessIdentityConfig = new { comment = "mysfits-workshop" } }); // Restrict the S3 bucket via a bucket policy that only allows our CloudFront distribution bucket.GrantRead(new CanonicalUserPrincipal( origin.AttrS3CanonicalUserId )); // Definition for a new CloudFront web distribution, which enforces traffic over HTTPS var cdn = new CloudFrontWebDistribution(this, "CloudFront", new CloudFrontWebDistributionProps { ViewerProtocolPolicy = ViewerProtocolPolicy.ALLOW_ALL, PriceClass = PriceClass.PRICE_CLASS_ALL, OriginConfigs = new SourceConfiguration[] { new SourceConfiguration { Behaviors = new Behavior[] { new Behavior { IsDefaultBehavior = true, MaxTtl = null, AllowedMethods = CloudFrontAllowedMethods.GET_HEAD_OPTIONS } }, OriginPath = "/web", S3OriginSource = new S3OriginConfig { S3BucketSource = bucket, OriginAccessIdentityId = origin.Ref } } } } ); string currentPath = Directory.GetCurrentDirectory(); // A CDK helper that takes the defined source directory, compresses it, and uploads it to the destination s3 bucket. new BucketDeployment(this, "DeployWebsite", new BucketDeploymentProps { Sources = new ISource[] { Source.Asset(Path.Combine(currentPath, "../Web")) }, DestinationBucket = bucket, DestinationKeyPrefix = "web/", Distribution = cdn, RetainOnDelete = false, }); // Create a CDK Output which details the URL for the CloudFront Distribtion URL. new CfnOutput(this, "CloudFrontURL", new CfnOutputProps { Description = "The CloudFront distribution URL", Value = "http://" + cdn.DomainName }); }
// A simple construct that contains a collection of AWS S3 buckets. public StaticSiteConstruct(Construct scope, string id, StaticSiteConstructProps props) : base(scope, id) { var zone = HostedZone.FromLookup(this, "Zone", new HostedZoneProviderProps { DomainName = props.DomainName }); var siteDomain = (string)($"{props.SiteSubDomain}.{props.DomainName}"); new CfnOutput(this, "Site", new CfnOutputProps { Value = $"https://{siteDomain}" }); var siteBucket = new Bucket(this, "SiteBucket", new BucketProps { BucketName = siteDomain, WebsiteIndexDocument = "index.html", WebsiteErrorDocument = "error.html", PublicReadAccess = true, // 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 // NOT recommended for production code }); new CfnOutput(this, "Bucket", new CfnOutputProps { Value = siteBucket.BucketName }); var certificateArn = new DnsValidatedCertificate(this, "SiteCertificate", new DnsValidatedCertificateProps { DomainName = siteDomain, HostedZone = zone }).CertificateArn; new CfnOutput(this, "Certificate", new CfnOutputProps { Value = certificateArn }); var behavior = new Behavior(); behavior.IsDefaultBehavior = true; var distribution = new CloudFrontWebDistribution(this, "SiteDistribution", new CloudFrontWebDistributionProps { AliasConfiguration = new AliasConfiguration { AcmCertRef = certificateArn, Names = new string[] { siteDomain }, SslMethod = SSLMethod.SNI, SecurityPolicy = SecurityPolicyProtocol.TLS_V1_2016 }, OriginConfigs = new ISourceConfiguration[] { new SourceConfiguration { S3OriginSource = new S3OriginConfig { S3BucketSource = siteBucket }, Behaviors = new Behavior[] { behavior } } } }); new CfnOutput(this, "DistributionId", new CfnOutputProps { Value = distribution.DistributionId }); new ARecord(this, "SiteAliasRecord", new ARecordProps { RecordName = siteDomain, Target = RecordTarget.FromAlias(new CloudFrontTarget(distribution)), Zone = zone }); new BucketDeployment(this, "DeployWithInvalidation", new BucketDeploymentProps { Sources = new ISource[] { Source.Asset("./site-contents") }, DestinationBucket = siteBucket, Distribution = distribution, DistributionPaths = new string[] { "/*" } }); }
public SpaStack(Construct scope, string id, SpaStackProps props) : base(scope, id, props) { //s3 bucket var bucket = new Bucket(this, $"{props.ServiceName}-bucket", new BucketProps { WebsiteIndexDocument = "index.html", Versioned = true, BucketName = props.ServiceName, RemovalPolicy = RemovalPolicy.DESTROY }); //cloudfront distribution var cloudFrontOai = new OriginAccessIdentity(this, $"{props.ServiceName}-oai", new OriginAccessIdentityProps { Comment = $"OAI for {props.ServiceName}." }); var cloudfrontDist = new CloudFrontWebDistribution(this, $"{props.ServiceName}-cfd", new CloudFrontWebDistributionProps { ViewerCertificate = ViewerCertificate.FromAcmCertificate( props.CloudFrontCert, new ViewerCertificateOptions { Aliases = new [] { $"{props.SubDomain}.{props.HostedZoneName}" }, SslMethod = SSLMethod.SNI }), OriginConfigs = new ISourceConfiguration[] { new SourceConfiguration { S3OriginSource = new S3OriginConfig { S3BucketSource = bucket, OriginAccessIdentity = cloudFrontOai }, Behaviors = new IBehavior[] { new Behavior { IsDefaultBehavior = true, } } } } }); var cnameRecord = new CnameRecord(this, $"{props.ServiceName}CloudFrontCname", new CnameRecordProps { Zone = HostedZone.FromHostedZoneAttributes(this, "HostedZone", new HostedZoneAttributes { ZoneName = props.HostedZoneName, HostedZoneId = props.HostedZoneId }), RecordName = props.SubDomain, DomainName = cloudfrontDist.DistributionDomainName }); var cloudfrontS3Access = new PolicyStatement(); cloudfrontS3Access.AddActions("s3:GetBucket*", "s3:GetObject*", "s3:List*"); cloudfrontS3Access.AddResources(bucket.BucketArn); cloudfrontS3Access.AddResources($"{bucket.BucketArn}/*"); cloudfrontS3Access.AddCanonicalUserPrincipal(cloudFrontOai.CloudFrontOriginAccessIdentityS3CanonicalUserId); bucket.AddToResourcePolicy(cloudfrontS3Access); //codebuild project var codeBuildProject = new Project(this, $"{props.ServiceName}-codeBuild-project", new ProjectProps { Vpc = props.Vpc, ProjectName = props.ServiceName, Environment = new BuildEnvironment { BuildImage = LinuxBuildImage.STANDARD_4_0, }, Source = Source.GitHub(props.GitHubSourceProps), BuildSpec = BuildSpec.FromSourceFilename(props.BuildSpecFile), EnvironmentVariables = new Dictionary <string, IBuildEnvironmentVariable> { { "SPA_DIRECTORY", new BuildEnvironmentVariable { Value = props.SpaDirectory } }, { "S3_BUCKET", new BuildEnvironmentVariable { Value = bucket.BucketName } }, { "CLOUDFRONT_ID", new BuildEnvironmentVariable { Value = cloudfrontDist.DistributionId } }, { "API_URL", new BuildEnvironmentVariable { Value = props.ApiUrl } } } }); // iam policy to push your build to S3 codeBuildProject.AddToRolePolicy( new PolicyStatement(new PolicyStatementProps { Effect = Effect.ALLOW, Resources = new[] { bucket.BucketArn, $"{bucket.BucketArn}/*" }, Actions = new[] { "s3:GetBucket*", "s3:List*", "s3:GetObject*", "s3:DeleteObject", "s3:PutObject" } })); codeBuildProject.AddToRolePolicy( new PolicyStatement(new PolicyStatementProps { Effect = Effect.ALLOW, Resources = new [] { "*" }, Actions = new [] { "cloudfront:CreateInvalidation", "cloudfront:GetDistribution*", "cloudfront:GetInvalidation", "cloudfront:ListInvalidations", "cloudfront:ListDistributions" } })); //codepipeline? }