示例#1
0
        internal AuthlambdaStack(Construct scope, string id, AuthlambdaStackProps props = null) : base(scope, id, props)
        {
            functionsStack = props.functionsStack;

            Bucket websiteBucket = new Bucket(this, "websiteBucket", new BucketProps()
            {
                BlockPublicAccess = BlockPublicAccess.BLOCK_ALL,
                PublicReadAccess  = false,
                //WebsiteIndexDocument = "index.html",
                RemovalPolicy = RemovalPolicy.DESTROY,
                Cors          = new ICorsRule[] {
                    new CorsRule()
                    {
                        AllowedHeaders = new string[] { "Authorization", "Content-Type", "Origin" },
                        AllowedMethods = new HttpMethods[] { HttpMethods.GET, HttpMethods.HEAD },
                        AllowedOrigins = new string[] { "*" }
                    }
                }
            });

            Bucket privateBucket = new Bucket(this, "privateBucket", new BucketProps()
            {
                BlockPublicAccess = BlockPublicAccess.BLOCK_ALL,
                PublicReadAccess  = false,
                RemovalPolicy     = RemovalPolicy.DESTROY,
                Cors = new ICorsRule[] {
                    new CorsRule()
                    {
                        AllowedHeaders = new string[] { "Authorization", "Content-Type", "Origin" },
                        AllowedMethods = new HttpMethods[] { HttpMethods.GET, HttpMethods.HEAD },
                        AllowedOrigins = new string[] { "*" }
                    }
                }
            });

            // The S3 bucket deployment for the website
            var websiteDeployment = new BucketDeployment(this, "TestStaticWebsiteDeployment", new BucketDeploymentProps()
            {
                Sources           = new [] { Source.Asset("./src/website") },
                DestinationBucket = websiteBucket,
                RetainOnDelete    = false
            });

            var privateDeployment = new BucketDeployment(this, "TestPrivateDeployment", new BucketDeploymentProps()
            {
                Sources           = new [] { Source.Asset("./src/private") },
                DestinationBucket = privateBucket,
                RetainOnDelete    = false
            });

            var cloudfrontOAI = OriginAccessIdentity.FromOriginAccessIdentityName(this, "CloudfrontOAIName", cloudfrontOAIName);

            websiteBucket.GrantRead(cloudfrontOAI.GrantPrincipal);
            privateBucket.GrantRead(cloudfrontOAI.GrantPrincipal);

            var cachePolicy = new CachePolicy(this, "TestCachePolicy", new CachePolicyProps()
            {
                CachePolicyName = "TestCachePolicy",
                Comment         = "Cache policy for Testing",
                DefaultTtl      = Duration.Seconds(0),
                CookieBehavior  = CacheCookieBehavior.All(),
                HeaderBehavior  = CacheHeaderBehavior.AllowList(
                    "Authorization",
                    "Content-Type",
                    "Origin"
                    ),
                QueryStringBehavior        = CacheQueryStringBehavior.All(),
                EnableAcceptEncodingBrotli = false,
                EnableAcceptEncodingGzip   = false
            });

            var websiteOrigin = new S3Origin(websiteBucket, new S3OriginProps()
            {
                OriginAccessIdentity = cloudfrontOAI
            });
            var privateOrigin = new S3Origin(privateBucket, new S3OriginProps()
            {
                OriginAccessIdentity = cloudfrontOAI
            });

            var dummyOrigin = new HttpOrigin("example.com", new HttpOriginProps()
            {
                ProtocolPolicy = OriginProtocolPolicy.HTTPS_ONLY
            });

            // default behavior is for the privateOrigin
            var defaultPrivateBehavior = new BehaviorOptions {
                AllowedMethods       = AllowedMethods.ALLOW_ALL,
                CachePolicy          = cachePolicy,
                OriginRequestPolicy  = OriginRequestPolicy.CORS_S3_ORIGIN,
                ViewerProtocolPolicy = ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
                Origin      = privateOrigin,
                EdgeLambdas = new IEdgeLambda[] {
                    new EdgeLambda()
                    {
                        EventType       = LambdaEdgeEventType.VIEWER_REQUEST,
                        FunctionVersion = functionsStack.checkAuthHandler.CurrentVersion,
                    },
                    new EdgeLambda()
                    {
                        EventType       = LambdaEdgeEventType.ORIGIN_RESPONSE,
                        FunctionVersion = functionsStack.httpHeadersHandler.CurrentVersion
                    }
                }
            };

            // this behavior is for dummy origin
            var parseAuthBehavior = new BehaviorOptions {
                AllowedMethods       = AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
                CachePolicy          = cachePolicy,
                OriginRequestPolicy  = OriginRequestPolicy.CORS_S3_ORIGIN,
                ViewerProtocolPolicy = ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
                Origin      = dummyOrigin,
                EdgeLambdas = new IEdgeLambda[] {
                    new EdgeLambda()
                    {
                        EventType       = LambdaEdgeEventType.VIEWER_REQUEST,
                        FunctionVersion = functionsStack.parseAuthHandler.CurrentVersion,
                    }
                }
            };

            var refreshAuthBehavior = new BehaviorOptions {
                AllowedMethods       = AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
                CachePolicy          = cachePolicy,
                OriginRequestPolicy  = OriginRequestPolicy.CORS_S3_ORIGIN,
                ViewerProtocolPolicy = ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
                Origin      = dummyOrigin,
                EdgeLambdas = new IEdgeLambda[] {
                    new EdgeLambda()
                    {
                        EventType       = LambdaEdgeEventType.VIEWER_REQUEST,
                        FunctionVersion = functionsStack.refreshAuthHandler.CurrentVersion,
                    }
                }
            };

            var signOutBehavior = new BehaviorOptions {
                AllowedMethods       = AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
                CachePolicy          = cachePolicy,
                OriginRequestPolicy  = OriginRequestPolicy.CORS_S3_ORIGIN,
                ViewerProtocolPolicy = ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
                Origin      = dummyOrigin,
                EdgeLambdas = new IEdgeLambda[] {
                    new EdgeLambda()
                    {
                        EventType       = LambdaEdgeEventType.VIEWER_REQUEST,
                        FunctionVersion = functionsStack.signOutHandler.CurrentVersion,
                    }
                }
            };

            Distribution distribution = new Distribution(this, "TestCloudfrontDistribution", new DistributionProps()
            {
                Comment           = "Test Website Distribution",
                DefaultRootObject = "index.html",
                PriceClass        = PriceClass.PRICE_CLASS_ALL,
                GeoRestriction    = GeoRestriction.Whitelist(new [] {
                    "IN"
                }),
                DefaultBehavior = defaultPrivateBehavior,
            });

            distribution.AddBehavior("/parseauth", dummyOrigin, parseAuthBehavior);
            distribution.AddBehavior("/refreshauth", dummyOrigin, refreshAuthBehavior);
            distribution.AddBehavior("/signout", dummyOrigin, signOutBehavior);

            var domainNameOutput = new CfnOutput(this, "TestWebsiteDistributionDomainName", new CfnOutputProps()
            {
                Value = distribution.DistributionDomainName
            });
        }
示例#2
0
        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?
        }