def create_records(self): """ Setup route53 entries At a minimum: A Record: subdomain.example.com Optional: A Record: example.com AAAA Record: example.com AAAA Record: subdomain.example.com """ self.cloudfront_site_target = route53.RecordTarget.from_alias( route53_targets.CloudFrontTarget( self.site_distribution ) ) if self.config.get("redirect_apex", True): apex_target = route53.RecordTarget.from_alias( route53_targets.CloudFrontTarget( self.redirect_distribution ) ) else: apex_target = self.cloudfront_site_target self.create_site_records() self.create_apex_records(apex_target)
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 generate_record_in_hosted_zone(scope, hosted_zone: route53.HostedZone, cloudfront_distribution): a_record = route53.ARecord( scope, "CloudfrontTier1Route53ARecord", zone=hosted_zone, target=route53.RecordTarget.from_alias( targets.CloudFrontTarget(cloudfront_distribution)), record_name="jvsantos-tier1.apperdevops.com") return a_record
def __init__(self, scope: core.Construct, id: str, domain: DomainInfo, **kwargs) -> None: super().__init__(scope, id, **kwargs) if domain.stage == 'prod': self.final_domain = domain.domain_name else: self.final_domain = f'{domain.stage}.{domain.domain_name}' self.domain = domain # Create the static site website bucket bucket = s3.Bucket(self, "sitebucket", bucket_name=self.final_domain, public_read_access=True, website_index_document="index.html") core.CfnOutput(self, 'site_bucket_name', value=bucket.bucket_name) core.CfnOutput(self, 'site_bucket_website', value=bucket.bucket_website_url) #create Cloudfront distribution return dist ID alias_configuration = cf.AliasConfiguration( acm_cert_ref=self.domain.cert_arn, names=[self.final_domain], ) source_configuration = cf.SourceConfiguration( s3_origin_source=cf.S3OriginConfig(s3_bucket_source=bucket, ), behaviors=[cf.Behavior(is_default_behavior=True)]) dist = cf.CloudFrontWebDistribution( self, 'staticsitecf', alias_configuration=alias_configuration, origin_configs=[source_configuration], ) core.CfnOutput(self, 'static_site_cf_dist_id', value=dist.distribution_id) core.CfnOutput(self, 'static_site_cf_domain', value=dist.domain_name) #route53 logic if self.domain.stage == 'prod': zone = route53.HostedZone.from_hosted_zone_attributes( self, id="HostedZoneID", hosted_zone_id=self.domain.hosted_zone_id, zone_name=self.domain.domain_name) route53.ARecord(self, 'SiteAliasRecord', record_name=self.final_domain, target=route53.AddressRecordTarget.from_alias( targets.CloudFrontTarget(dist)), zone=zone)
def __init__(self, parent: core.Construct, name: str, props: StaticSiteProps) -> None: super().__init__(parent, name) site_domain = props.site_sub_domain + '.' + props.domain_name # Content bucket site_bucket = s3.Bucket(self, "SiteBucket", bucket_name=site_domain, website_index_document="index.html", website_error_document="error.html", public_read_access=True, removal_policy=core.RemovalPolicy.DESTROY) core.CfnOutput(self, 'Bucket', value=site_bucket.bucket_name) #cloudfront distribution that provies HTTPS distribution = cfront.CloudFrontWebDistribution( self, 'SiteDistribution', origin_configs=[ cfront.SourceConfiguration( behaviors=[cfront.Behavior(is_default_behavior=True)], s3_origin_source=cfront.S3OriginConfig( s3_bucket_source=site_bucket)) ], alias_configuration=cfront.AliasConfiguration( acm_cert_ref=props.certificate_arn, names=[site_domain], ssl_method=cfront.SSLMethod.SNI, security_policy=cfront.SecurityPolicyProtocol.TLS_V1_1_2016)) core.CfnOutput(self, 'DistributionID', value=distribution.distribution_id) # Route 53 alias record for the CloudFront distribution zone = route53.HostedZone.from_lookup(self, 'MyHostedZone', domain_name=props.domain_name) # Add a A record to the hosted zone route53.ARecord( self, 'SiteAliasRecord', zone=zone, record_name=site_domain, target=route53.AddressRecordTarget.from_alias( aws_route53_targets.CloudFrontTarget(distribution)))
def __init__(self, app: core.App, id: str, **kwargs) -> None: super().__init__(app, id) #create an S3 bucket domainName = 'accelerate.dev' myBucket = s3.Bucket(self, 'accelerate.dev-s3bucket', bucket_name='accelerate-website', public_read_access=True, website_index_document='index.html', website_error_document='404.html', removal_policy=core.RemovalPolicy.DESTROY) myBucket.grant_public_access myBucket.add_to_resource_policy( #Grant read access to everyone in your account iam.PolicyStatement( actions=['s3:GetObject'], resources=[myBucket.arn_for_objects('*')], principals=[ iam.AccountPrincipal(account_id=core.Aws.ACCOUNT_ID) ])) myUser = iam.User(self, 'deploy_' + domainName) #Grant write access to a specific user myBucket.grant_write(myUser) hostedZone = route53.HostedZone.from_hosted_zone_attributes( self, "HostedZone_" + domainName, hosted_zone_id='Z00154093I7THXRTRF8QB', zone_name=domainName) cert = certmgr.DnsValidatedCertificate(self, "cert_" + domainName, domain_name=domainName, hosted_zone=hostedZone) distribution = cloudfront.CloudFrontWebDistribution( self, "accelerate.dev-distribution", price_class=cloudfront.PriceClass.PRICE_CLASS_100, origin_configs=[ cloudfront.SourceConfiguration( s3_origin_source=cloudfront.S3OriginConfig( s3_bucket_source=myBucket), behaviors=[cloudfront.Behavior(is_default_behavior=True)]) ], viewer_certificate=cloudfront.ViewerCertificate. from_acm_certificate(cert, aliases=['accelerate.dev'])) route53.ARecord(self, "Alias_" + domainName, zone=hostedZone, target=route53.RecordTarget.from_alias( targets.CloudFrontTarget(distribution)))
def __create_route_53_record_group( self, route_53_hosted_zone: aws_route53.HostedZone, domain_name: str, alternative_domain_names: List[str], cloud_front_distribution: aws_cloudfront.Distribution ) -> List[aws_route53.ARecord]: domain_names = alternative_domain_names domain_names.append(domain_name) return [ aws_route53.RecordSet( self, domain_name.replace('.', '').upper(), record_type=aws_route53.RecordType.A, zone=route_53_hosted_zone, record_name=domain_name, target=aws_route53.RecordTarget.from_alias( alias_target=aws_route53_targets.CloudFrontTarget( distribution=cloud_front_distribution))) for domain_name in set(domain_names) ]
def __init__(self, scope: core.Construct, id: str, cdnid, **kwargs) -> None: super().__init__(scope, id, **kwargs) prj_name = self.node.try_get_context("project_name") env_name = self.node.try_get_context("env") hosted_zone = r53.HostedZone(self, 'hosted-zone', zone_name='cloudevangelist.ca') r53.ARecord(self, 'cdn-record', zone=hosted_zone, target=r53.RecordTarget.from_alias( alias_target=r53target.CloudFrontTarget(cdnid)), record_name='app') ssm.StringParameter(self, 'zone-id', parameter_name='/' + env_name + '/zone-id', string_value=hosted_zone.hosted_zone_id)
def __init__(self, scope: core.Construct, id: str, api: apigateway.RestApi, **kwargs) -> None: super().__init__(scope, id, **kwargs) stack = core.Stack.of(self) bucket = s3.Bucket(self, 'Storage') s3_deployment.BucketDeployment( self, 'Deployment', sources=[ s3_deployment.Source.asset('./src/html'), ], destination_bucket=bucket, ) origin_identity = cloudfront.OriginAccessIdentity(self, 'Identity') bucket.grant_read(origin_identity.grant_principal) s3_origin = cloudfront.SourceConfiguration( s3_origin_source=cloudfront.S3OriginConfig( s3_bucket_source=bucket, origin_access_identity=origin_identity, ), behaviors=[ cloudfront.Behavior( default_ttl=core.Duration.days(1), min_ttl=core.Duration.days(1), max_ttl=core.Duration.days(31), is_default_behavior=True, ) ]) api_origin = cloudfront.SourceConfiguration( origin_path='/{}'.format(api.deployment_stage.stage_name), custom_origin_source=cloudfront.CustomOriginConfig( domain_name='{}.execute-api.{}.{}'.format( api.rest_api_id, stack.region, stack.url_suffix), ), behaviors=[ cloudfront.Behavior(default_ttl=core.Duration.seconds(0), min_ttl=core.Duration.seconds(0), max_ttl=core.Duration.seconds(0), path_pattern='/stock/*', forwarded_values={ 'query_string': True, 'query_string_cache_keys': ['start', 'end'] }) ]) domain_name = 'demo.training' subdomain = 'finance.{}'.format(domain_name) zone = route53.HostedZone.from_lookup( self, 'Zone', domain_name=domain_name, ) certificate = acm.DnsValidatedCertificate( self, 'Certificate', domain_name=subdomain, hosted_zone=zone, region='us-east-1', ) distribution = cloudfront.CloudFrontWebDistribution( self, 'CDN', price_class=cloudfront.PriceClass.PRICE_CLASS_ALL, origin_configs=[ s3_origin, api_origin, ], alias_configuration=cloudfront.AliasConfiguration( acm_cert_ref=certificate.certificate_arn, names=[subdomain], )) route53.ARecord( self, 'DnsRecord', record_name=subdomain, target=route53.AddressRecordTarget.from_alias( alias_target=route53_targets.CloudFrontTarget(distribution)), zone=zone, )
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # Message timeout; used by SQS and Lambda message_timeout = core.Duration.seconds(15) # SQS queue that the Raspberry Pi will write to queue = sqs.Queue( self, 'Queue', visibility_timeout=message_timeout, receive_message_wait_time=core.Duration.seconds(20), retention_period=core.Duration.hours(1), ) # DynamoDB table that the web app will read from icao_address = dynamodb.Attribute( name='IcaoAddress', type=dynamodb.AttributeType.STRING, ) table = dynamodb.Table( self, 'Table', partition_key=icao_address, billing_mode=dynamodb.BillingMode.PAY_PER_REQUEST, removal_policy=core.RemovalPolicy.DESTROY, ) database = timestream.CfnDatabase( self, 'Database', database_name='aircraft-database', ) table2 = timestream.CfnTable(self, 'Table2', database_name=database.ref, table_name='aircraft-table', retention_properties={ 'MemoryStoreRetentionPeriodInHours': 1, 'MagneticStoreRetentionPeriodInDays': 1, }) # IAM user for the Raspberry Pi user = iam.User(self, 'RaspberryPi') queue.grant_send_messages(user) access_key = iam.CfnAccessKey( self, 'AccessKey', user_name=user.user_name, ) # IAM role for Lambda function, so it can write to DynamoDB lambda_role = iam.Role( self, 'LambdaRole', assumed_by=iam.ServicePrincipal('lambda.amazonaws.com'), managed_policies=[ iam.ManagedPolicy.from_aws_managed_policy_name( 'service-role/AWSLambdaBasicExecutionRole'), ], ) lambda_role.add_to_policy( iam.PolicyStatement( actions=[ 'timestream:CancelQuery', 'timestream:DescribeEndpoints', 'timestream:DescribeTable', 'timestream:ListMeasures', 'timestream:Select', 'timestream:WriteRecords' ], resources=['*'], # TODO: narrow down permissions )) table.grant_read_write_data(lambda_role) # Integration between SQS and Lambda event = lambda_event_sources.SqsEventSource( queue=queue, batch_size=10, ) # Lambda function that processes messages from SQS queue and updates DynamoDB table import_function = lambda_.Function( self, 'ImportFunction', description='Reads SQS messages and writes to DynamoDB', runtime=lambda_.Runtime.PYTHON_3_8, code=lambda_.Code.from_asset('lambda_import/'), timeout=message_timeout, handler='index.handler', role=lambda_role, events=[event], environment={ 'TABLE_NAME': table2.ref, }, ) # TODO: add custom log group # TODO: add metric filters for number of succesfull updates and failed updates # Lambda function that reads from DynamoDB and returns data to API Gateway api_function = lambda_.Function( self, 'ApiFunction', description='Reads from DynamoDB and returns to API GW', runtime=lambda_.Runtime.PYTHON_3_8, code=lambda_.Code.from_asset('lambda_api/'), timeout=message_timeout, handler='index.handler', role=lambda_role, environment={ 'TABLE_NAME': table.table_name, }, ) # API Gateway for requesting aircraft data api = apigateway.RestApi( self, 'Api', endpoint_types=[apigateway.EndpointType.REGIONAL], cloud_watch_role=False, ) aircraft_resource = api.root.add_resource('aircraft') aircraft_resource.add_method( http_method='GET', integration=apigateway.LambdaIntegration( api_function, proxy=True, ), ) # Static website bucket = s3.Bucket(self, 'StaticWebsite') s3_deployment.BucketDeployment( self, 'Deployment', sources=[ s3_deployment.Source.asset('html/'), ], destination_bucket=bucket, ) # Permissions between CloudFront and S3 origin_identity = cloudfront.OriginAccessIdentity(self, 'Identity') bucket.grant_read(origin_identity.grant_principal) # CloudFront distribution pointing to both S3 and API Gateway s3_origin = cloudfront.SourceConfiguration( s3_origin_source=cloudfront.S3OriginConfig( s3_bucket_source=bucket, origin_access_identity=origin_identity, ), behaviors=[ cloudfront.Behavior( default_ttl=core.Duration.days(0), min_ttl=core.Duration.days(0), max_ttl=core.Duration.days(31), is_default_behavior=True, ) ]) api_origin = cloudfront.SourceConfiguration( origin_path='/{}'.format(api.deployment_stage.stage_name), custom_origin_source=cloudfront.CustomOriginConfig( domain_name='{}.execute-api.{}.{}'.format( api.rest_api_id, self.region, self.url_suffix), ), behaviors=[ cloudfront.Behavior( default_ttl=core.Duration.seconds(0), min_ttl=core.Duration.seconds(0), max_ttl=core.Duration.seconds(0), path_pattern='/aircraft/*', ) ]) domain_name = self.node.try_get_context('domain_name') # If domain name is specified, create a certificate and alias configuration for CloudFront if domain_name is None: alias_configuration = None else: subdomain = 'aircraft.{}'.format(domain_name) zone = route53.HostedZone.from_lookup( self, 'Zone', domain_name=domain_name, ) certificate = acm.DnsValidatedCertificate( self, 'Certificate', domain_name=subdomain, hosted_zone=zone, region='us-east-1', ) alias_configuration = cloudfront.AliasConfiguration( acm_cert_ref=certificate.certificate_arn, names=[subdomain], ) distribution = cloudfront.CloudFrontWebDistribution( self, 'CDN', price_class=cloudfront.PriceClass.PRICE_CLASS_ALL, alias_configuration=alias_configuration, origin_configs=[ s3_origin, api_origin, ], ) # If domain name is specified, create a DNS record for CloudFront if domain_name is not None: route53.ARecord( self, 'DnsRecord', record_name=subdomain, target=route53.AddressRecordTarget.from_alias( alias_target=route53_targets.CloudFrontTarget( distribution)), zone=zone, ) # Outputs that are needed on the Raspberry Pi core.CfnOutput( self, 'QueueUrl', value=queue.queue_url, ) core.CfnOutput( self, 'AccessKeyId', value=access_key.ref, ) core.CfnOutput( self, 'SecretAccessKey', value=access_key.attr_secret_access_key, ) core.CfnOutput( self, 'Region', value=self.region, )
def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # certificate = certmgr.DnsValidatedCertificate(self, # 'HostedZoneCertificate', # hosted_zone=hosted_zone, # domain_name='untermuller.ch', # region='us-east-1', # subject_alternative_names=['resume.untermuller.ch','www.resume.untermuller.ch','www.untermuller.ch'] # ) # website_bucket_create = s3.Bucket(self, 'WebsiteBucketCDK', # bucket_name='BUCKET_NAME', # website_index_document='index.html', # website_error_document='error.html', # public_read_access=True) table = dynamo.Table(self, 'HitCounter', partition_key={ 'name': 'id', 'type': dynamo.AttributeType.STRING }) counter = lmb.Function( self, 'CounterHandler', runtime=lmb.Runtime.PYTHON_3_8, handler='counter.lambda_handler', code=lmb.Code.asset('resume_cdk/lambda'), environment={'TABLE_NAME': table.table_name}, ) lambdaapigw = apigw.LambdaRestApi(self, 'Endpoint', handler=counter) endpoint = core.CfnOutput(self, 'ApiEndpoint', value=lambdaapigw.url) table.grant_read_write_data(counter) website_bucket = s3.Bucket.from_bucket_name(self, 'BUCKET_NAME', bucket_name='BUCKET_NAME') deploy_website = s3_deploy.BucketDeployment( self, 'DeployWebsiteCDK', sources=[s3_deploy.Source.asset("./website")], destination_bucket=website_bucket) hosted_zone = route53.HostedZone.from_hosted_zone_attributes( self, 'HOST.CH', hosted_zone_id='HOST_ID', zone_name='HOST.CH') certificate = certmgr.Certificate.from_certificate_arn( self, 'CERT_HOST.CH', 'CERT_HOST.CH_ARN') cdf_OAI = cdf.OriginAccessIdentity(self, 'OAI-user-s3', comment='OAI') grant_access = website_bucket.grant_read(cdf_OAI.grant_principal) s3_origin = cdf.S3OriginConfig( s3_bucket_source=website_bucket, origin_access_identity=cdf_OAI, ) cdf_viewer_policy = cdf.ViewerProtocolPolicy('REDIRECT_TO_HTTPS') cdf_behavior = cdf.Behavior(is_default_behavior=True) cdf_source_config = cdf.SourceConfiguration( behaviors=[cdf_behavior], s3_origin_source=s3_origin, ) cdf_dist = cdf.CloudFrontWebDistribution( self, 'ResumeDistribution', origin_configs=[cdf_source_config], viewer_certificate=cdf.ViewerCertificate.from_acm_certificate( certificate, aliases=['HOST.CH', 'ALIAS_HOST.CH'], security_policy=cdf.SecurityPolicyProtocol.TLS_V1, ssl_method=cdf.SSLMethod.SNI), viewer_protocol_policy=cdf_viewer_policy) route_Aname = route53.ARecord( self, 'ANAME', record_name='HOST.CH', target=route53.RecordTarget.from_alias( route53_targets.CloudFrontTarget(cdf_dist)), zone=hosted_zone, comment="insert a record")
def __init__( self, scope: core.Construct, id: str, **kwargs, ) -> None: super().__init__(scope, id, **kwargs) s3_domain_prefix = scope.static_site_bucket.bucket_name s3_domain_suffix = ".s3-website-us-east-1.amazonaws.com" s3_website_domain_name = s3_domain_prefix + s3_domain_suffix path_patterns = ["/api/*", "/admin/*", "/flower*"] self.distribution = cloudfront.CloudFrontWebDistribution( self, "CloudFrontDistribution", origin_configs=[ cloudfront.SourceConfiguration( custom_origin_source=cloudfront.CustomOriginConfig( domain_name=scope.alb.load_balancer_dns_name, origin_protocol_policy=MATCH_VIEWER, ), behaviors=[ cloudfront.Behavior( allowed_methods=ALL_METHODS, path_pattern=path_pattern, forwarded_values={ "headers": ["*"], "cookies": { "forward": "all" }, "query_string": True, }, ) for path_pattern in path_patterns ], ), cloudfront.SourceConfiguration( custom_origin_source=cloudfront.CustomOriginConfig( domain_name=s3_website_domain_name, origin_protocol_policy=HTTP_ONLY, ), behaviors=[ cloudfront.Behavior( is_default_behavior=True, cached_methods=GET_HEAD, ) ], ), cloudfront.SourceConfiguration( s3_origin_source=cloudfront.S3OriginConfig( s3_bucket_source=scope.backend_assets_bucket), behaviors=[ cloudfront.Behavior( allowed_methods=ALL_METHODS, forwarded_values={"query_string": True}, path_pattern=path_pattern, min_ttl=core.Duration.seconds(0), default_ttl=core.Duration.seconds(0), max_ttl=core.Duration.seconds(0), ) for path_pattern in ["/static/*", "/media/*"] ], ), ], alias_configuration=cloudfront.AliasConfiguration( acm_cert_ref=scope.certificate.certificate_arn, names=[scope.full_domain_name], ), ) route53.ARecord( self, "AliasRecord", target=route53.AddressRecordTarget.from_alias( targets.CloudFrontTarget(self.distribution)), zone=scope.hosted_zone, record_name=f"{scope.full_domain_name}.", )
def __init__(self, scope: core.Construct, construct_id: str, origin, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # The code that defines your stack goes here # web_acl = waf.CfnWebACL(self, "WAF ACL", # default_action={"allow": {}}, # scope="GLOBAL", # visibility_config={ # "sampledRequestsEnabled": True, # "cloudWatchMetricsEnabled": True, # "metricName": "web-acl", # }, # rules=[ # { # "name": "rate_limit_500", # "priority": 0, # "action": { # "block": {} # }, # "visibilityConfig": { # "sampledRequestsEnabled": True, # "cloudWatchMetricsEnabled": True, # "metricName": "rate_limit_500" # }, # "statement": { # "rateBasedStatement": { # "limit": 500, # "aggregateKeyType": "IP" # } # } # }, # { # "priority": 1, # "overrideAction": {"none": {}}, # "visibilityConfig": { # "sampledRequestsEnabled": True, # "cloudWatchMetricsEnabled": True, # "metricName": "AWS-AWSManagedRulesAmazonIpReputationList", # }, # "name": "AWS-AWSManagedRulesAmazonIpReputationList", # "statement": { # "managedRuleGroupStatement": { # "vendorName": "AWS", # "name": "AWSManagedRulesAmazonIpReputationList", # }, # }, # }, # { # "priority": 2, # "overrideAction": {"none": {}}, # "visibilityConfig": { # "sampledRequestsEnabled": True, # "cloudWatchMetricsEnabled": True, # "metricName": "AWS-AWSManagedRulesCommonRuleSet", # }, # "name": "AWS-AWSManagedRulesCommonRuleSet", # "statement": { # "managedRuleGroupStatement": { # "vendorName": "AWS", # "name": "AWSManagedRulesCommonRuleSet", # }, # }, # }, # { # "priority": 3, # "overrideAction": {"none": {}}, # "visibilityConfig": { # "sampledRequestsEnabled": True, # "cloudWatchMetricsEnabled": True, # "metricName": "AWS-AWSManagedRulesKnownBadInputsRuleSet", # }, # "name": "AWS-AWSManagedRulesKnownBadInputsRuleSet", # "statement": { # "managedRuleGroupStatement": { # "vendorName": "AWS", # "name": "AWSManagedRulesKnownBadInputsRuleSet", # }, # }, # }, # { # "priority": 4, # "overrideAction": {"none": {}}, # "visibilityConfig": { # "sampledRequestsEnabled": True, # "cloudWatchMetricsEnabled": True, # "metricName": "AWS-AWSManagedRulesSQLiRuleSet", # }, # "name": "AWS-AWSManagedRulesSQLiRuleSet", # "statement": { # "managedRuleGroupStatement": { # "vendorName": "AWS", # "name": "AWSManagedRulesSQLiRuleSet", # }, # }, # } # ] # ) certificate = acm.Certificate.from_certificate_arn( self, "Certificate", acm_arn) distribution = cloudfront.Distribution(self, "myDist", default_behavior={ "origin": origins.LoadBalancerV2Origin(origin, protocol_policy=cloudfront.OriginProtocolPolicy.MATCH_VIEWER), "viewer_protocol_policy": cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, "cache_policy": cloudfront.CachePolicy(self, "myCachePolicy", cache_policy_name="MyPolicy", comment="A default policy", default_ttl=core.Duration.minutes( 0), min_ttl=core.Duration.minutes( 0), max_ttl=core.Duration.minutes( 5), ) }, domain_names=[f'www.{domain}'], certificate=certificate, # web_acl_id=web_acl.attr_arn ) hosted_zone = route53.HostedZone.from_hosted_zone_attributes(self, "MyZone", zone_name=domain, hosted_zone_id=hosted_zone_id ) route53.ARecord(self, "Alias", zone=hosted_zone, target=route53.RecordTarget.from_alias( targets.CloudFrontTarget(distribution)), record_name=f'www.{domain}', ttl=core.Duration.minutes(5) )
def create_static_site(scope: InfraStack, hosted_zone: route53.HostedZone): bucket = s3.Bucket( scope, id=scope.context.construct_id("s3"), bucket_name=f'{scope.context.construct_id("s3")}-bucket', versioned=True, block_public_access=s3.BlockPublicAccess( restrict_public_buckets=True, block_public_policy=True, block_public_acls=True, ), removal_policy=RemovalPolicy.RETAIN, auto_delete_objects=False, lifecycle_rules=[ s3.LifecycleRule(noncurrent_version_expiration=Duration.days(7)) ], ) prod_domain_name = "gingerbeans.tech" lower_domain_name = f"{scope.context.env_name}.gingerbeans.tech" domain_name = (prod_domain_name if scope.context.env_name == PRODUCTION else lower_domain_name) my_certificate = acm.DnsValidatedCertificate( scope, scope.context.construct_id("certificate"), domain_name=domain_name, hosted_zone=hosted_zone, region="us-east-1", ) origin_access_identity = cloudfront.OriginAccessIdentity( scope, scope.context.construct_id("cfOriginAccessIdentity")) cf_s3_access = iam.PolicyStatement() cf_s3_access.add_actions("s3:GetBucket*") cf_s3_access.add_actions("s3:GetObject*") cf_s3_access.add_actions("s3:List*") cf_s3_access.add_resources(bucket.bucket_arn) cf_s3_access.add_resources(f"{bucket.bucket_arn}/*") cf_s3_access.add_canonical_user_principal( origin_access_identity. cloud_front_origin_access_identity_s3_canonical_user_id) bucket.add_to_resource_policy(cf_s3_access) distro = cloudfront.Distribution( scope, scope.context.construct_id("dist"), default_behavior=cloudfront.BehaviorOptions(origin=origins.S3Origin( bucket=bucket, origin_access_identity=origin_access_identity)), default_root_object="index.html", domain_names=[domain_name], certificate=my_certificate, ) route53.AaaaRecord( scope, scope.context.construct_id("AAAA"), record_name=domain_name, target=route53.RecordTarget.from_alias( targets.CloudFrontTarget(distro)), zone=hosted_zone, ) route53.ARecord( scope, scope.context.construct_id("A"), record_name=domain_name, target=route53.RecordTarget.from_alias( targets.CloudFrontTarget(distro)), zone=hosted_zone, ) s3_deployment.BucketDeployment( scope, scope.context.construct_id("s3_deployment"), sources=[s3_deployment.Source.asset("../gb-ui/build")], destination_key_prefix="/", destination_bucket=bucket, distribution=distro, distribution_paths=["/*"], )
def __init__(self, scope: core.Construct, id: str, props: StaticSiteProps) -> None: super().__init__(scope, id) site_domain: str = "{sub_domain}.{domain_name}".format( sub_domain=props.site_sub_domain, domain_name=props.domain_name) # Content Bucket site_bucket = s3.Bucket( self, "SiteBucket", bucket_name=site_domain, website_index_document="index.html", website_error_document="error.html", public_read_access=True, ) core.CfnOutput(self, "Bucket", value=site_bucket.bucket_name) # Pre-existing ACM Certificate, with ARN stored in an SSM Parameter certificate_arn: str = ssm.StringParameter.from_string_parameter_attributes( self, "MYCertArnString", parameter_name="CertificateArn-{}".format(props.domain_name), ).string_value # CloudFront distribution that provides HTTPS alias_configuration = cloudfront.AliasConfiguration( acm_cert_ref=certificate_arn, names=[site_domain], ssl_method=cloudfront.SSLMethod.SNI, security_policy=cloudfront.SecurityPolicyProtocol.TLS_V1_1_2016, ) source_configuration = cloudfront.SourceConfiguration( s3_origin_source=cloudfront.S3OriginConfig( s3_bucket_source=site_bucket), behaviors=[cloudfront.Behavior(is_default_behavior=True)], ) distribution = cloudfront.CloudFrontWebDistribution( self, "SiteDistribution", alias_configuration=alias_configuration, origin_configs=[source_configuration], ) core.CfnOutput(self, "DistributionId", value=distribution.distribution_id) # Route53 alias record for the CloudFront Distribution zone = route53.HostedZone.from_hosted_zone_attributes( self, id="HostedZoneID", hosted_zone_id=props.hosted_zone_id, zone_name=props.domain_name, ) route53.ARecord( self, "SiteAliasRecord", record_name=site_domain, target=route53.AddressRecordTarget.from_alias( targets.CloudFrontTarget(distribution)), zone=zone, )
class TsWwwStack(core.Stack): def __init__(self, scope: core.Construct, id: str,domain_name:str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # Materialize existing AWS Hosted DNS Zone dns_zone = r53_.HostedZone.from_lookup(self,"dns_zone",domain_name = domain_name) # Compose site name for AWS Certificate site_fqdn = "www." + dns_zone.zone_name # Create a DNS Certificate certificate = cm_.DnsValidatedCertificate (self,"certificate", domain_name=site_fqdn, hosted_zone=dns_zone, region="us-east-1") # Define Bucket to store Site Contents ts_www_bucket = s3_.Bucket(self,"truesys-static-website", bucket_name = site_fqdn, website_index_document = "index.html", website_error_document = "404/index.html", public_read_access = True ) #Cria lambda function para fazr URL Rewriting de default document url_rewrite_lambda = _lambda.Function(self,'URLRewriteLambdaEdge', handler='url_rewrite_handler.handler', runtime=_lambda.Runtime.PYTHON_3_7, code=_lambda.Code.asset('lambda_edge'), ) // A numbered version to give to cloudfront const myOriginRequestHandlerVersion = new lambda.Version(this, "OriginRequestHandlerVersion", { lambda: myOriginRequestHandler, }); lea = clf_.AlambdaFunctionAssociation(event_type = cfl_AlambdaEdgeEventType.ORIGIN_REQUEST, myOriginRequestHandlerVersion) #Define Cloud Front distribution s3_origin_config = clf_.S3OriginConfig(s3_bucket_source = ts_www_bucket) behaviour = clf_.Behavior(is_default_behavior=True, lambda_function_associations = [lea]) source_config = clf_.SourceConfiguration(s3_origin_source=s3_origin_config, behaviors = [behaviour]) clf_alias_config = clf_.AliasConfiguration(acm_cert_ref = certificate.certificate_arn, names=[site_fqdn], ssl_method = clf_.SSLMethod.SNI, security_policy = clf_.SecurityPolicyProtocol.TLS_V1_1_2016) cf_distribution = clf_.CloudFrontWebDistribution(self,"TsDistribution", origin_configs=[source_config], alias_configuration=clf_alias_config, price_class = clf_.PriceClass.PRICE_CLASS_ALL ) #Define Route 53 Alias aka endereco do site cloud_front_target = r53tgs_.CloudFrontTarget(distribution = cf_distribution) r53_target = r53_.RecordTarget.from_alias(alias_target = cloud_front_target) r53_.ARecord(self,"EnderecoDosite",record_name = site_fqdn, target = r53_target, zone = dns_zone) #Faz deploy do conteudo do site para o S3 e invalida distribution site_assets = s3deploy_.Source.asset("./true-systems-static-site/public") s3deploy_.BucketDeployment(self,"truesys-website-content-deployment", sources = [site_assets], destination_bucket=ts_www_bucket, distribution=cf_distribution, distribution_paths = [ "/*"]) core.CfnOutput(self,"Site",value = site_fqdn)
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # define fully qualified domain name for website site_domain = '{sub}.{zone}'.format(sub=WEBSITE_SUBDOMAIN, zone=DNS_ZONE_NAME) # create an s3 bucket to hold the static site bucket = s3.Bucket( self, 'RootBucket', bucket_name=site_domain, website_index_document='index.html', website_error_document='404.html', public_read_access=True, versioned=False, removal_policy=core.RemovalPolicy. DESTROY, # this refers to the case where a stack is destroyed, where we # want to destroy the static site bucket as well ) # establish the route53 domain name dns_zone = r53.HostedZone.from_lookup(self, 'WebsiteZone', domain_name='jeichenhofer.com') core.CfnOutput(self, 'site_address', value='https://' + site_domain) # output the address to cloudformation # create a tls certificate cert_arn = acm.DnsValidatedCertificate( self, 'SiteCertificate', domain_name=site_domain, hosted_zone=dns_zone, ).certificate_arn core.CfnOutput(self, 'site_cert', value=cert_arn) # create CloudFront distro for https and caching dist = cloudfront.CloudFrontWebDistribution( self, 'SiteDistribution', alias_configuration={ "acmCertRef": cert_arn, "names": [site_domain], "sslMethod": cloudfront.SSLMethod.SNI, "securityPolicy": cloudfront.SecurityPolicyProtocol.TLS_V1_2_2018 }, origin_configs=[{ "s3OriginSource": { "s3BucketSource": bucket }, "behaviors": [{ "isDefaultBehavior": True }], }]) core.CfnOutput(self, 'distribution_id', value=dist.distribution_id) # point the domain name to the cloudfront distribution r53.ARecord(self, 'SiteAliasRecord', zone=dns_zone, record_name=site_domain, target=r53.AddressRecordTarget.from_alias( r53_targets.CloudFrontTarget(dist))) # deploy the static files to the bucket s3deploy.BucketDeployment( self, 'DeployWithInvalidation', sources=[s3deploy.Source.asset('./site-contents')], destination_bucket=bucket, distribution=dist, distribution_paths=['/*'], )
def __init__(self, scope: core.Construct, id: str, props: StaticSiteProps) -> None: super().__init__(scope, id) fqdn = props.fqdn certificate_arn = props.certificate_arn error_configuration = props.error_configuration if len(error_configuration) == 0: error_codes = None else: error_codes = [] for error_config in error_configuration: error_codes.append( cloudfront.CfnDistribution.CustomErrorResponseProperty( error_code=error_config["error_code"], error_caching_min_ttl=error_config[ "error_caching_min_ttl"], response_code=error_config["response_code"], response_page_path=error_config["response_page_path"], )) # Content Bucket site_bucket = s3.Bucket( self, "SiteBucket", bucket_name=fqdn + "-static-site", website_index_document="index.html", website_error_document="index.html", block_public_access=s3.BlockPublicAccess(block_public_policy=True), removal_policy=core.RemovalPolicy.DESTROY, ) self.bucket_name = fqdn + "-static-site" self.bucket_resource = site_bucket origin_access_identity = cloudfront.CfnCloudFrontOriginAccessIdentity( self, "OriginIdentity", cloud_front_origin_access_identity_config={ "comment": "Allow CloudFront to access web site" }, ) # Create IAM policy for S3 Canonical User policy_statement = iam.PolicyStatement() policy_statement.add_actions("s3:GetBucket*") policy_statement.add_actions("s3:GetObject*") policy_statement.add_actions("s3:List**") policy_statement.add_resources(site_bucket.bucket_arn) policy_statement.add_resources(f"{site_bucket.bucket_arn}/*") policy_statement.add_canonical_user_principal( origin_access_identity.attr_s3_canonical_user_id) site_bucket.add_to_resource_policy(policy_statement) core.CfnOutput(self, "Bucket", value=site_bucket.bucket_name) # CloudFront distribution with or without certificate source_configuration = cloudfront.SourceConfiguration( s3_origin_source=cloudfront.S3OriginConfig( s3_bucket_source=site_bucket, origin_access_identity_id=origin_access_identity.ref, ), behaviors=[cloudfront.Behavior(is_default_behavior=True)], ) # Use ACM Certificate if provided, otherwise no-SSL if certificate_arn: # CloudFront distribution that provides HTTPS alias_configuration = cloudfront.AliasConfiguration( acm_cert_ref=certificate_arn, names=[fqdn], ssl_method=cloudfront.SSLMethod.SNI, security_policy=cloudfront.SecurityPolicyProtocol. TLS_V1_1_2016, ) distribution = cloudfront.CloudFrontWebDistribution( self, "SiteDistribution", alias_configuration=alias_configuration, error_configurations=error_codes, origin_configs=[source_configuration], viewer_protocol_policy=cloudfront.ViewerProtocolPolicy. REDIRECT_TO_HTTPS, ) else: distribution = cloudfront.CloudFrontWebDistribution( self, "SiteDistribution", origin_configs=[source_configuration], error_configurations=error_codes, ) core.CfnOutput( self, "DistributionId", value=distribution.distribution_id, export_name=props.output_name, ) # Route53 alias record for the CloudFront Distribution zone = route53.HostedZone.from_hosted_zone_attributes( self, id="HostedZoneID", hosted_zone_id=props.hosted_zone_id, zone_name=props.fqdn, ) route53.ARecord( self, "SiteAliasRecord", record_name=fqdn, target=route53.AddressRecordTarget.from_alias( targets.CloudFrontTarget(distribution)), zone=zone, )
def web(self): zone = route53.HostedZone.from_hosted_zone_attributes( self, 'hosted_zone', hosted_zone_id=HOSTED_ZONE_ID, zone_name=self.zone) cert = cert_manager.DnsValidatedCertificate( self, 'domain_cert', domain_name=self.zone, subject_alternative_names=[ self.web_domain ], hosted_zone=zone, validation_method=cert_manager.ValidationMethod.DNS) # cert = cert_manager.Certificate.from_certificate_arn(self, 'certificateDomainForAll', # "arn:aws:acm:us-east-1:134764946504:certificate/f74613d7-8cc5-4de1-a2ed-467d5321839d") site_bucket = s3.Bucket(self, 'site_bucket', bucket_name=self.web_domain, website_index_document='index.html', website_error_document='404.html', public_read_access=True) core.CfnOutput(self, 'bucket_name', value=site_bucket.bucket_name) source_behavior = cloudfront.Behavior( is_default_behavior=True, cached_methods=cloudfront.CloudFrontAllowedCachedMethods.GET_HEAD_OPTIONS, allowed_methods=cloudfront.CloudFrontAllowedMethods.GET_HEAD_OPTIONS, compress=True) s3_origin_source = cloudfront.S3OriginConfig(s3_bucket_source=site_bucket) origin_source_config = cloudfront.SourceConfiguration( s3_origin_source=s3_origin_source, behaviors=[source_behavior]) alias_configuration = cloudfront.AliasConfiguration( acm_cert_ref=cert.certificate_arn, names=[self.zone], ssl_method=cloudfront.SSLMethod.SNI, security_policy=cloudfront.SecurityPolicyProtocol.TLS_V1_2_2019) distribution = cloudfront.CloudFrontWebDistribution( self, 'cf-web-distro', alias_configuration=alias_configuration, origin_configs=[origin_source_config], error_configurations=[ cloudfront.CfnDistribution.CustomErrorResponseProperty( error_code=404, response_code=404, response_page_path='/404.html' ), cloudfront.CfnDistribution.CustomErrorResponseProperty( error_code=403, response_code=404, response_page_path='/404.html', ) ], http_version=cloudfront.HttpVersion.HTTP2, viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS ) core.CfnOutput(self, 'Distribution ID', value=distribution.distribution_id) core.CfnOutput(self, 'Distribution domain name', value=distribution.domain_name) core.CfnOutput(self, 'SiteBucketWebsiteDomain', value=site_bucket.bucket_website_domain_name) # noinspection PyTypeChecker target_alias = route53.RecordTarget.from_alias(targets.CloudFrontTarget(distribution)) route53.ARecord(self, 'arecord-web', record_name=self.zone, target=target_alias, zone=zone, ttl=core.Duration.minutes(60)) s3_deployment.BucketDeployment(self, "deploy-with-invalidation", sources=[ s3_deployment.Source.asset('./../website') ], destination_bucket=site_bucket, distribution=distribution, content_language='en-US', distribution_paths=['/*'])
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # set variables for site s3 bucket bucket_name = DOMAIN_WEBSITE['bucket_name'] website_index = DOMAIN_WEBSITE['website_index'] website_error = DOMAIN_WEBSITE['website_error'] website_code_folder = DOMAIN_WEBSITE['website_code_folder'] site_domain = DOMAIN_WEBSITE['site_domain'] certificate_domain = DOMAIN_WEBSITE['certificate_domain'] api_domain = DOMAIN_WEBSITE['api_domain'] hosted_zone_name = DOMAIN_WEBSITE['hosted_zone_name'] hosted_zone_id = DOMAIN_WEBSITE['hosted_zone_id'] #self.lambda_code = aws_lambda.Code.from_cfn_parameters() # retrieve hosted zone hosted_zone = aws_route53.HostedZone.from_hosted_zone_attributes( self, 'hostedZone', hosted_zone_id=hosted_zone_id, zone_name=hosted_zone_name) # set variables for backend lambda_code_location = "jukebike/backend/" # Construct code goes here CfnOutput(self, "Site", value=f"https://{site_domain}") # Content bucket site_bucket = aws_s3.Bucket(self, "websitebucket", bucket_name=bucket_name, website_index_document=website_index, website_error_document=website_error, public_read_access=True, removal_policy=RemovalPolicy.DESTROY) CfnOutput(self, "BucketArn", value=site_bucket.bucket_arn) CfnOutput(self, "WebsiteUrl", value=site_bucket.bucket_website_url) # Certificate cert = aws_certificatemanager.DnsValidatedCertificate( self, "certificate_website", domain_name=site_domain, hosted_zone=hosted_zone, region="us-east-1") CfnOutput(self, 'CertificateArn', value=cert.certificate_arn) distr = CloudFrontWebDistribution( self, "SiteDistribution", alias_configuration=AliasConfiguration( acm_cert_ref=cert.certificate_arn, names=[site_domain], ssl_method=aws_cloudfront.SSLMethod.SNI, security_policy=aws_cloudfront.SecurityPolicyProtocol. TLS_V1_1_2016, ), origin_configs=[ SourceConfiguration( s3_origin_source=aws_cloudfront.S3OriginConfig( s3_bucket_source=site_bucket), behaviors=[ aws_cloudfront.Behavior(is_default_behavior=True) ]) ]) CfnOutput(self, "DistributionId", value=distr.distribution_id) # # Route 53 alias record for the cloudfront distribution aws_route53.ARecord(self, "SiteAliasRecord", zone=hosted_zone, target=aws_route53.AddressRecordTarget.from_alias( aws_route53_targets.CloudFrontTarget(distr)), record_name=site_domain) aws_s3_deployment.BucketDeployment( self, "DeployWithInvalidation", sources=[aws_s3_deployment.Source.asset(website_code_folder)], destination_bucket=site_bucket, distribution=distr, distribution_paths=["/*"]) ########################### Backend ################# certificate = aws_certificatemanager.DnsValidatedCertificate( self, "domaincertificate", hosted_zone=hosted_zone, region='us-east-1', domain_name=certificate_domain, validation_method=aws_certificatemanager.ValidationMethod.DNS) ############# Search API ################### search_lambda = aws_lambda.Function( self, "SearchLambda", code=aws_lambda.Code.from_asset(lambda_code_location), handler="search.handler", runtime=aws_lambda.Runtime.PYTHON_3_7) CfnOutput(self, "SearchLambda_", value=search_lambda.function_arn) search_api = aws_apigateway.LambdaRestApi( self, 'SearchSpotifyEndpoint', handler=search_lambda, ) ############# Whats-Next API ################### whats_next_lambda = aws_lambda.Function( self, "WhatsNextLambda", code=aws_lambda.Code.from_asset(lambda_code_location), handler="whats_next.handler", runtime=aws_lambda.Runtime.PYTHON_3_7) CfnOutput(self, "WhatsNextLambda_", value=whats_next_lambda.function_arn) whats_next_api = aws_apigateway.LambdaRestApi( self, 'WhatsNextEndpoint', handler=whats_next_lambda, ) ############# Whats-Next API ################### wish_track_lambda = aws_lambda.Function( self, "WishTrackLambda", code=aws_lambda.Code.from_asset(lambda_code_location), handler="wish_track.handler", runtime=aws_lambda.Runtime.PYTHON_3_7) CfnOutput(self, "WishTrackLambda_", value=wish_track_lambda.function_arn) wish_track_api = aws_apigateway.LambdaRestApi( self, 'WishTrackEndpoint', handler=wish_track_lambda, ) ################## Publish APIS with custom domain name ############## # Pre-Requirements: # [Manual] 1) Registered Domain with Route 53 (e.g. jacubasch.com) # 2) Certificate in North Virgina for domain (e.g. api.jacubasch.com) -> AWS Certification Manager # 3) API Gateway Custom Domain with Edge # 4) Alias-Record in Route53 forwarding to Cloudfront Target Domain Name (can be found in API Gateway) # TODO: in separaten Base-Stack auslagern? # https://medium.com/@maciejtreder/custom-domain-in-aws-api-gateway-a2b7feaf9c74 domain = aws_apigateway.DomainName( self, 'searchDomain', certificate=certificate, endpoint_type=aws_apigateway.EndpointType.EDGE, domain_name=api_domain) domain.add_base_path_mapping(target_api=search_api, base_path="search") domain.add_base_path_mapping(target_api=whats_next_api, base_path="whats-next") domain.add_base_path_mapping(target_api=wish_track_api, base_path="wish-track") target = aws_route53_targets.ApiGatewayDomain(domain) record_target = aws_route53.RecordTarget.from_alias(target) alias_record = aws_route53.ARecord(self, 'aliasRecord', target=record_target, record_name=api_domain, zone=hosted_zone) CfnOutput(self, "AliasRecord_", value=alias_record.to_string()) ################## Dynamo DB ############## # create dynamo table track_table = aws_dynamodb.Table( self, "track_table", partition_key=aws_dynamodb.Attribute( name="track_uri", type=aws_dynamodb.AttributeType.STRING)) # grant permission to lambda & provide environment variable track_table.grant_write_data(wish_track_lambda) wish_track_lambda.add_environment("TRACK_TABLE_NAME", track_table.table_name) track_table.grant_read_write_data(whats_next_lambda) whats_next_lambda.add_environment("TRACK_TABLE_NAME", track_table.table_name)
def __init__(self, scope: core.Construct, id: str, sub_domain: str, domain: str, **kwargs) -> None: """ StaticSiteStack creates the CloudFormation Stack that creates the resources necessary to host a static web site from an S3 Bucket with a CloudFormation CDN and a custom domain name. arguments: sub_domain -- sub domain name used for the dashboard url, acg-covid-challenge domain -- custom domain name owned by user, e.g. my-domain.com """ super().__init__(scope, id, **kwargs) # In the GitHub Actions Workflow, the Certificate is created using the CertificateStack and its arn is set as an environment variable self.certificate_arn = self.node.try_get_context("certificate_arn") bucket = s3.Bucket(self, f"{sub_domain}-bucket", website_index_document="index.html", removal_policy=core.RemovalPolicy.DESTROY, block_public_access=s3.BlockPublicAccess.BLOCK_ALL ) core.CfnOutput(self, "sitebucketname", value=bucket.bucket_name) oai = cf.OriginAccessIdentity( self, f"OriginIdentity-{sub_domain}", ) alias_configuration = cf.AliasConfiguration( acm_cert_ref=self.certificate_arn, names=[f"{sub_domain}.{domain}"], ssl_method=cf.SSLMethod.SNI, security_policy=cf.SecurityPolicyProtocol.TLS_V1_1_2016 ) source_config = cf.SourceConfiguration( s3_origin_source=cf.S3OriginConfig( s3_bucket_source=bucket, origin_access_identity=oai ), behaviors=[cf.Behavior(is_default_behavior=True)] ) cf_dist = cf.CloudFrontWebDistribution( self, f"{sub_domain}-static-site-distribution", alias_configuration=alias_configuration, origin_configs=[source_config], viewer_protocol_policy=cf.ViewerProtocolPolicy.REDIRECT_TO_HTTPS ) core.CfnOutput(self, "distid", value=cf_dist.distribution_id) # Route53 alias record for the CloudFront Distribution hosted_zone = route53.HostedZone.from_lookup( self, f"{sub_domain}-hosted-zone-id", domain_name=domain) route53.ARecord( self, f'{sub_domain}-alias-record', record_name=f"{sub_domain}.{domain}", target=route53.AddressRecordTarget.from_alias( targets.CloudFrontTarget(cf_dist)), zone=hosted_zone )
def __init__(self, scope: core.Construct, id: str, domain: DomainProps, website: WebsiteConstruct, **kwargs) -> None: super().__init__(scope, id, **kwargs) zone = route53.HostedZone(self, 'Zone', zone_name=domain.domain_name, comment='Managed by CDK') root_record_name = domain.domain_name wildcard_record_name = '*.{}'.format(root_record_name) website_target = route53.AddressRecordTarget.from_alias( alias_target=route53_targets.CloudFrontTarget( website.distribution)) route53.ARecord( self, 'RootIpv4', record_name=root_record_name, zone=zone, target=website_target, ) route53.AaaaRecord( self, 'RootIpv6', record_name=root_record_name, zone=zone, target=website_target, ) route53.ARecord( self, 'WildcardIpv4', record_name=wildcard_record_name, zone=zone, target=website_target, ) route53.AaaaRecord( self, 'WildcardIpv6', record_name=wildcard_record_name, zone=zone, target=website_target, ) route53.MxRecord( self, 'Email', record_name=root_record_name, zone=zone, values=domain.mx_record_values, ) route53.TxtRecord( self, 'Text', record_name=root_record_name, zone=zone, values=domain.txt_record_values, )
def __init__(self, scope: core.Construct, id: str, hosted_zone_id: str, hosted_zone_name: str, website_domain_name: str, certificate_in_us_east_1_arn: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # Raise an exception if we get a certificate that doesn't live in us-east-1 check_us_east_1_cert(certificate_in_us_east_1_arn) # The S3 Bucket that will store our website website_bucket = s3.Bucket(self, "WebsiteBucket") # The Origin Access Identity is a way to allow CloudFront Access to the Website Bucket origin_access_identity = cloudfront.OriginAccessIdentity( self, "OriginAccessIdentity", comment="Allows Read-Access from CloudFront") # We tell the website bucket to allow access from CloudFront website_bucket.grant_read(origin_access_identity) # Import the cert from the arn we get as a parameter tls_cert = certificatemanager.Certificate.from_certificate_arn( self, "Certificate", certificate_arn=certificate_in_us_east_1_arn) # We set up the CloudFront Distribution with the S3 Bucket as the origin and our certificate cloudfront_distribution = cloudfront.CloudFrontWebDistribution( self, "WebsiteDistribution", origin_configs=[ cloudfront.SourceConfiguration( s3_origin_source=cloudfront.S3OriginConfig( s3_bucket_source=website_bucket, origin_access_identity=origin_access_identity), behaviors=[ cloudfront.Behavior(is_default_behavior=True, default_ttl=core.Duration.hours(1)) ], ) ], error_configurations=[ # Point CloudFront to our custom 404 error page when a 404 occurs cloudfront.CfnDistribution.CustomErrorResponseProperty( error_code=404, response_code=404, response_page_path="/404.html") ], viewer_certificate=cloudfront.ViewerCertificate. from_acm_certificate(certificate=tls_cert, aliases=[website_domain_name])) # Set the DNS Alias for CloudFront hosted_zone = route53.HostedZone.from_hosted_zone_attributes( self, "HostedZone", hosted_zone_id=hosted_zone_id, zone_name=hosted_zone_name) cloudfront_alias_record = route53.ARecord( self, "DNSAliasForCloudFront", zone=hosted_zone, target=route53.RecordTarget.from_alias( route53_targets.CloudFrontTarget(cloudfront_distribution)), record_name=website_domain_name, ) # Repo for the website repository = codecommit.Repository( self, "Repository", repository_name=website_domain_name, description=f"Repository for the website {website_domain_name}") website_build_project = codebuild.PipelineProject( self, "WebsiteBuild", build_spec=codebuild.BuildSpec.from_source_filename( "buildspec.yml"), environment=codebuild.BuildEnvironment( build_image=codebuild.LinuxBuildImage.STANDARD_4_0), environment_variables={ "baseurl": codebuild.BuildEnvironmentVariable( value=f"https://{website_domain_name}/"), "bucket": codebuild.BuildEnvironmentVariable( value=website_bucket.bucket_name) }) website_bucket.grant_read_write(website_build_project.grant_principal) source_output = codepipeline.Artifact() website_build_pipeline = codepipeline.Pipeline( self, "WebsiteBuildPipeline", stages=[ # Check Out the Code From the Repo codepipeline.StageProps( stage_name="Source", actions=[ codepipeline_actions.CodeCommitSourceAction( action_name="CheckoutCode", repository=repository, output=source_output) ]), # Build and deploy the Website to S3 (this uses the sync command with the delete option, which the codebuild action to deploy to S3 doesn't support) codepipeline.StageProps( stage_name="BuildAndDeploy", actions=[ codepipeline_actions.CodeBuildAction( action_name="BuildAndDeployWebsite", project=website_build_project, input=source_output) ]) ]) # Display the Repo Clone URLs as the Stack Output core.CfnOutput(self, "RepositoryCloneUrlSSH", value=repository.repository_clone_url_ssh) core.CfnOutput(self, "RepositoryCloneUrlHTTPS", value=repository.repository_clone_url_http) # Display the website URL as the stack output core.CfnOutput(self, "WebsiteUrl", value=f"https://{website_domain_name}/")
def __init__(self, scope: core.Construct, id: str, props: StaticSiteProps) -> None: super().__init__(scope, id) fqdn = props.fqdn certificate_arn = props.certificate_arn error_configuration = props.error_configuration if len(error_configuration) == 0: error_codes = None else: error_codes = [] for error_config in error_configuration: error_codes.append( cloudfront.CfnDistribution.CustomErrorResponseProperty( error_code=error_config["error_code"], error_caching_min_ttl=error_config[ "error_caching_min_ttl"], response_code=error_config["response_code"], response_page_path=error_config["response_page_path"], )) # Content Bucket site_bucket = s3.Bucket( self, "SiteBucket", bucket_name=fqdn + "-static-site", website_index_document="index.html", website_error_document="index.html", block_public_access=s3.BlockPublicAccess(block_public_policy=True), removal_policy=core.RemovalPolicy.DESTROY, ) self.bucket_name = fqdn + "-static-site" self.bucket_resource = site_bucket # Uses new method for OAI (still breaking changes) - https://github.com/aws/aws-cdk/pull/4491 origin_access_identity = cloudfront.OriginAccessIdentity( self, "OriginIdentity") # Add CloudFront Origin Access Identity to the bucket site_bucket.grant_read(origin_access_identity) core.CfnOutput(self, "Bucket", value=site_bucket.bucket_name) # CloudFront distribution with or without certificate source_configuration = cloudfront.SourceConfiguration( s3_origin_source=cloudfront.S3OriginConfig( s3_bucket_source=site_bucket, origin_access_identity=origin_access_identity, ), behaviors=[cloudfront.Behavior(is_default_behavior=True)], ) # Use ACM Certificate if provided, otherwise no-SSL if certificate_arn: # CloudFront distribution that provides HTTPS alias_configuration = cloudfront.AliasConfiguration( acm_cert_ref=certificate_arn, names=[fqdn], ssl_method=cloudfront.SSLMethod.SNI, security_policy=cloudfront.SecurityPolicyProtocol. TLS_V1_1_2016, ) distribution = cloudfront.CloudFrontWebDistribution( self, "SiteDistribution", alias_configuration=alias_configuration, error_configurations=error_codes, origin_configs=[source_configuration], viewer_protocol_policy=cloudfront.ViewerProtocolPolicy. REDIRECT_TO_HTTPS, ) else: distribution = cloudfront.CloudFrontWebDistribution( self, "SiteDistribution", origin_configs=[source_configuration], error_configurations=error_codes, ) core.CfnOutput( self, "DistributionId", value=distribution.distribution_id, export_name=props.output_name, ) # Route53 alias record for the CloudFront Distribution zone = route53.HostedZone.from_hosted_zone_attributes( self, id="HostedZoneID", hosted_zone_id=props.hosted_zone_id, zone_name=props.fqdn, ) route53.ARecord( self, "SiteAliasRecord", record_name=fqdn, target=route53.RecordTarget.from_alias( alias_target=targets.CloudFrontTarget(distribution)), zone=zone, )
def __init__(self, scope: core.Construct, id: str, **kwargs): super().__init__(scope, id, **kwargs) # note assumption zone is named after domain hosted_zone = route53.HostedZone.from_hosted_zone_attributes( self, "HostedZone", hosted_zone_id=startuptoolbag_config.hosted_zone_id, zone_name=startuptoolbag_config.website_domain_name) # SSL/TLS Certificate # https://github.com/aws/aws-cdk/pull/8552 # Experimental vs 'Certificate' (which requires validation in the console) tls_cert = certificatemanager.DnsValidatedCertificate( self, "SiteCertificate", hosted_zone=hosted_zone, domain_name=f'*.{startuptoolbag_config.website_domain_name}', subject_alternative_names=[ startuptoolbag_config.website_domain_name ], region='us-east-1', ) # Import the bucket that was created outside the stack self.www_site_bucket = s3.Bucket.from_bucket_name( self, 'SiteBucket', core.Fn.import_value("WWWSITEBUCKETNAME")) # CloudFront distribution that provides HTTPS - for www www_alias_configuration = cloudfront.AliasConfiguration( acm_cert_ref=tls_cert.certificate_arn, names=[f'www.{startuptoolbag_config.website_domain_name}'], ssl_method=cloudfront.SSLMethod.SNI, security_policy=cloudfront.SecurityPolicyProtocol.TLS_V1_1_2016) www_source_configuration = cloudfront.SourceConfiguration( s3_origin_source=cloudfront.S3OriginConfig( s3_bucket_source=self.www_site_bucket), behaviors=[cloudfront.Behavior(is_default_behavior=True)]) www_distribution = cloudfront.CloudFrontWebDistribution( self, 'SiteDistribution', alias_configuration=www_alias_configuration, origin_configs=[www_source_configuration]) route53.ARecord( self, 'CloudFrontARecord', zone=hosted_zone, record_name= f'www.{startuptoolbag_config.website_domain_name}', #site domain target=aws_route53.RecordTarget.from_alias( aws_route53_targets.CloudFrontTarget(www_distribution))) # NAKED site bucket which redirects to naked to www redirect = aws_route53_patterns.HttpsRedirect( self, 'NakedRedirect', record_names=[startuptoolbag_config.website_domain_name], target_domain=f'www.{startuptoolbag_config.website_domain_name}', zone=hosted_zone, certificate=tls_cert) # Create the API Gateway self.rest_api = aws_apigateway.RestApi(self, 'RestApiGateway', deploy=False) api_domain_name = f'api.{startuptoolbag_config.website_domain_name}' domain = self.rest_api.add_domain_name('APIDomain', certificate=tls_cert, domain_name=api_domain_name) route53.ARecord( self, 'APIGWAliasRecord', zone=hosted_zone, record_name=api_domain_name, #site domain target=aws_route53.RecordTarget.from_alias( aws_route53_targets.ApiGatewayDomain(domain)))
def __init__( self, scope: core.Construct, id: str, certificate_arn: str, hosted_zone_id, domain_name, **kwargs ) -> None: super().__init__(scope, id, **kwargs) hosted_zone = route53.HostedZone.from_hosted_zone_attributes( self, "HostedZone", hosted_zone_id=hosted_zone_id, zone_name=domain_name ) # since the bucket has already been created from previous deployments # we build the bucket object from attributes here rather than creating a # new bucket. # This change is required since we had to re-create this entire stack # after the bucket had been originally created. site_bucket = s3.Bucket.from_bucket_attributes( self, "SiteBucket", bucket_name=domain_name ) oai = cloudfront.OriginAccessIdentity(self, "OriginAccessIdentity") distribution = cloudfront.CloudFrontWebDistribution( self, "SiteDistribution", alias_configuration=cloudfront.AliasConfiguration( acm_cert_ref=certificate_arn, names=[domain_name], ), origin_configs=[ cloudfront.SourceConfiguration( s3_origin_source=cloudfront.S3OriginConfig( s3_bucket_source=site_bucket, origin_access_identity=oai ), behaviors=[cloudfront.Behavior(is_default_behavior=True)], ), ], ) # noinspection PyTypeChecker route53.ARecord( self, "SiteAliasRecord", record_name=domain_name, target=route53.AddressRecordTarget.from_alias( route53_targets.CloudFrontTarget(distribution) ), zone=hosted_zone, ) s3_deployment.BucketDeployment( self, "DeployWithInvalidation", sources=[s3_deployment.Source.asset("assets/elm/dst")], destination_bucket=site_bucket, distribution=distribution, distribution_paths=["/*"], )
def __init__(self, scope: Construct, id: str, *, sources: str, hosted_zone: HostedZone = None, site_domain: str = None, website_index: str = "index.html", website_error: str = "error.html"): """ This constructs creates: - S3 bucket - DNS Validated certificate - CloudFront web distribution - Route53 A record :param scope: The scope in which to define this construct. :param id: The scoped construct ID. Must be unique amongst siblings. If the ID includes a path separator (``/``), then it will be replaced by double dash ``--``. :param hosted_zone: A route53 hosted zone :param site_domain: The domain or subdomain you want to use for the website :param sources: A path to the location of the code :param website_index: Name of the index page, defaults to "index.html" :param website_error: Name of the error page, defaults to "error.html" """ super().__init__(scope, id) # Construct code goes here if site_domain: CfnOutput(self, "Site", value=f"https://{site_domain}") # Content bucket self.site_bucket = aws_s3.Bucket(self, "SiteBucket", bucket_name=site_domain, website_index_document=website_index, website_error_document=website_error, public_read_access=True, removal_policy=RemovalPolicy.DESTROY) CfnOutput(self, "BucketArn", value=self.site_bucket.bucket_arn) CfnOutput(self, "BucketWebsiteUrl", value=self.site_bucket.bucket_website_url) CfnOutput(self, "BucketWebsiteDomainName", value=self.site_bucket.bucket_website_domain_name) # Certificate alias_config = None if hosted_zone: self.cert = DnsValidatedCertificate(self, f"{id}-bucket", domain_name=site_domain, hosted_zone=hosted_zone) CfnOutput(self, 'CertificateArn', value=self.cert.certificate_arn) alias_config = AliasConfiguration( acm_cert_ref=self.cert.certificate_arn, names=[site_domain], ssl_method=aws_cloudfront.SSLMethod.SNI, security_policy=aws_cloudfront.SecurityPolicyProtocol. TLS_V1_1_2016, ) self.distr = CloudFrontWebDistribution( self, "SiteDistribution", alias_configuration=alias_config, origin_configs=[ SourceConfiguration( s3_origin_source=aws_cloudfront.S3OriginConfig( s3_bucket_source=self.site_bucket), behaviors=[ aws_cloudfront.Behavior(is_default_behavior=True) ]) ]) CfnOutput(self, "DistributionId", value=self.distr.distribution_id) # Route 53 alias record for the cloudfront distribution if hosted_zone: aws_route53.ARecord( self, "SiteAliasRecord", zone=hosted_zone, target=aws_route53.AddressRecordTarget.from_alias( aws_route53_targets.CloudFrontTarget(self.distr)), record_name=site_domain) aws_s3_deployment.BucketDeployment( self, "DeployWithInvalidation", sources=[aws_s3_deployment.Source.asset(sources)], destination_bucket=self.site_bucket, distribution=self.distr, distribution_paths=["/*"])
def __init__(self, scope: core.Construct, id: str, environment: str, domain: str, **kwargs) -> None: """ StaticSiteStack creates the CloudFormation Stack that creates the resources necessary to host a static web site from an S3 Bucket with a CloudFormation CDN and a custom domain name. Three separate stacks are created based on the environment variable ('dev', 'stg', 'prod') arguments: environment -- Deployment Environment, e.g. one of ('dev', 'stg', 'prod') domain -- custom domain name owned by user, e.g. my-domain.com """ super().__init__(scope, id, **kwargs) # In the GitHub Actions Workflow, the Certificate is created using the CertificateStack and its arn is set as an environment variable self.certificate_arn = self.node.try_get_context("certificate_arn") bucket = s3.Bucket(self, f"{environment}bucket", website_index_document="index.html", removal_policy=core.RemovalPolicy.DESTROY, block_public_access=s3.BlockPublicAccess.BLOCK_ALL) core.CfnOutput(self, "sitebucketname", value=bucket.bucket_name) oai = cf.OriginAccessIdentity( self, f"OriginIdentity-{environment}-{domain}", ) alias_configuration = cf.AliasConfiguration( acm_cert_ref=self.certificate_arn, names=[f"{environment}.{domain}"], ssl_method=cf.SSLMethod.SNI, security_policy=cf.SecurityPolicyProtocol.TLS_V1_1_2016) # Config dictionary for CloudFront distributions, no caching takes place in dev # The assumption is that it will be changed frequently and those changes will be tested # To use alternative sub-domains, change the keys of this dictionary to match the sub-domains used in certificate_stack.py cf_behavior_dict = { "dev": cf.Behavior(is_default_behavior=True, min_ttl=core.Duration.seconds(0), max_ttl=core.Duration.seconds(0), default_ttl=core.Duration.seconds(0)), "stg": cf.Behavior(is_default_behavior=True), "prod": cf.Behavior(is_default_behavior=True) } source_config = cf.SourceConfiguration( s3_origin_source=cf.S3OriginConfig(s3_bucket_source=bucket, origin_access_identity=oai), behaviors=[cf_behavior_dict[environment]]) cf_dist = cf.CloudFrontWebDistribution( self, f"{environment}-static-site-distribution", alias_configuration=alias_configuration, origin_configs=[source_config], viewer_protocol_policy=cf.ViewerProtocolPolicy.REDIRECT_TO_HTTPS) core.CfnOutput(self, "distid", value=cf_dist.distribution_id) # Route53 alias record for the CloudFront Distribution hosted_zone = route53.HostedZone.from_lookup( self, "static-site-hosted-zone-id", domain_name=domain) route53.ARecord(self, 'static-site-alias-record', record_name=f"{environment}.{domain}", target=route53.AddressRecordTarget.from_alias( targets.CloudFrontTarget(cf_dist)), zone=hosted_zone)
def add_static_site(stack: CDKMasterStack, domain: str, bucket_name: str, prefix: str = ""): # Construct code goes here core.CfnOutput(stack, f"{prefix}Site", value=f"https://{domain}") # Content bucket kix.info("Bucket Name: " + bucket_name) site_bucket = aws_s3.Bucket( stack, f"{prefix}SiteBucket", bucket_name=bucket_name, website_index_document="index.html", website_error_document="index.html", public_read_access=True, removal_policy=core.RemovalPolicy.DESTROY) core.CfnOutput(stack, f"{prefix}BucketArn", value=site_bucket.bucket_arn) # Certificate kix.info("Creating Certificate") cert = aws_certificatemanager.DnsValidatedCertificate( stack, f"{prefix}ValidatedCert", domain_name=domain, hosted_zone=stack.zone) core.CfnOutput(stack, f"{prefix}CertificateArn", value=cert.certificate_arn) kix.info("Creating Distribution") distribution = aws_cloudfront.CloudFrontWebDistribution( stack, f"{prefix}SiteDistribution", alias_configuration=aws_cloudfront.AliasConfiguration( acm_cert_ref=cert.certificate_arn, names=[domain], ssl_method=aws_cloudfront.SSLMethod.SNI, security_policy=aws_cloudfront.SecurityPolicyProtocol.TLS_V1_1_2016, ), origin_configs=[ aws_cloudfront.SourceConfiguration( s3_origin_source=aws_cloudfront.S3OriginConfig(s3_bucket_source=site_bucket), behaviors=[aws_cloudfront.Behavior(is_default_behavior=True)] )], error_configurations=[ aws_cloudfront.CfnDistribution.CustomErrorResponseProperty( error_code=403, response_code=200, response_page_path="/index.html" ), aws_cloudfront.CfnDistribution.CustomErrorResponseProperty( error_code=404, response_code=200, response_page_path="/index.html" ) ] ) core.CfnOutput(stack, f"{prefix}DistributionId", value=distribution.distribution_id) a_record_target = aws_route53.AddressRecordTarget.from_alias(aws_route53_targets.CloudFrontTarget(distribution)) # Route 53 alias record for the CloudFront distribution kix.info("Routing A-Record Alias") aws_route53.ARecord( stack, f"{prefix}SiteAliasRecord", zone=stack.zone, target=a_record_target, record_name=domain)
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # super().__init__(scope, id, context, outdir) print() # Common Stack Tags for k, v in constants.COMMON_TAGS.items(): core.Tag.add(self, key=k, value=v) # Hosted Zone if constants.HOSTED_ZONE["id"]: hosted_zone = aws_route53.HostedZone.from_hosted_zone_attributes( self, "ImportedHostedZone", hosted_zone_id=constants.HOSTED_ZONE["id"], zone_name=constants.HOSTED_ZONE["name"]) else: hosted_zone = aws_route53.HostedZone( self, "MainHostedZone", zone_name=constants.HOSTED_ZONE["name"], comment="Hosted Zone for {}".format( constants.HOSTED_ZONE["name"]), ) # ACM Certificate if constants.CERTIFICATE["arn"]: acm_certificate = aws_certificatemanager.Certificate.from_certificate_arn( self, "ImportedCertificate", certificate_arn=constants.CERTIFICATE["arn"]) else: acm_certificate = aws_certificatemanager.DnsValidatedCertificate( self, "CloudFrontCertificate", hosted_zone=hosted_zone, region=constants.CERTIFICATE["region"], domain_name=constants.HOSTED_ZONE["domain"], subject_alternative_names=constants.CERTIFICATE["alt_domains"], validation_method=aws_certificatemanager.ValidationMethod.DNS) acm_certificate.node.add_dependency(hosted_zone) # Website Bucket website_bucket = aws_s3.Bucket( self, "WebsiteBucket", encryption=aws_s3.BucketEncryption.S3_MANAGED, removal_policy=core.RemovalPolicy.DESTROY) # Cloudfront Origin Access Identity (OAI) website_bucket_oai = aws_cloudfront.CfnCloudFrontOriginAccessIdentity( self, "CloudfrontOAI", cloud_front_origin_access_identity_config=aws_cloudfront. CfnCloudFrontOriginAccessIdentity. CloudFrontOriginAccessIdentityConfigProperty( comment="CloudFrontOAIFor{}".format( constants.PROJECT_CODE.capitalize()))) # Canonical User Principal of OAI oai_canonical_user_principal = aws_iam.CanonicalUserPrincipal( website_bucket_oai.attr_s3_canonical_user_id) # Website Bucket Policy website_bucket.add_to_resource_policy( aws_iam.PolicyStatement( actions=["s3:GetObject"], resources=[website_bucket.arn_for_objects("*")], principals=[oai_canonical_user_principal], effect=aws_iam.Effect.ALLOW)) # Adopt Lambda Function lambda_function = aws_lambda.Function.from_function_arn( self, "UrlRewriteFunction", function_arn=constants.URL_REWRITE_FUNCTION_ARN) lambda_function_version_arn = aws_lambda.Version.from_version_arn( self, "LambdaFunctionArn", version_arn=constants.URL_REWRITE_FUNCTION_VERSION_ARN) # CloudFront Web Distribution cloudfront_distribution = aws_cloudfront.CloudFrontWebDistribution( self, "CloudFrontDistribution", comment="waqqas.tech", default_root_object="index.html", viewer_protocol_policy=aws_cloudfront.ViewerProtocolPolicy. REDIRECT_TO_HTTPS, alias_configuration=aws_cloudfront.AliasConfiguration( acm_cert_ref=acm_certificate.certificate_arn, security_policy=aws_cloudfront.SecurityPolicyProtocol. TLS_V1_2_2018, names=constants.CLOUDFRONT["alt_domains"]), origin_configs=[ aws_cloudfront.SourceConfiguration( s3_origin_source=aws_cloudfront.S3OriginConfig( s3_bucket_source=website_bucket, origin_access_identity_id=website_bucket_oai.ref), behaviors=[ aws_cloudfront.Behavior( allowed_methods=aws_cloudfront. CloudFrontAllowedMethods.GET_HEAD_OPTIONS, cached_methods=aws_cloudfront. CloudFrontAllowedCachedMethods.GET_HEAD, compress=True, is_default_behavior=True, path_pattern="*", default_ttl=core.Duration.seconds( amount=constants.CLOUDFRONT['default_ttl']), lambda_function_associations=[ aws_cloudfront.LambdaFunctionAssociation( event_type=aws_cloudfront. LambdaEdgeEventType.ORIGIN_REQUEST, lambda_function=lambda_function_version_arn ) ]) ]) ]) # CloudFront Route53 Record primary_dns_record = aws_route53.ARecord( self, "PrimaryDNSRecord", zone=hosted_zone, comment="{} CloudFront Dist Alias Record".format( constants.PROJECT_CODE), record_name="{}.".format(constants.HOSTED_ZONE["domain"]), target=aws_route53.RecordTarget.from_alias( aws_route53_targets.CloudFrontTarget(cloudfront_distribution)), ttl=core.Duration.seconds( amount=constants.CLOUDFRONT["default_ttl"]), ) # Artifact Bucket artifact_bucket = aws_s3.Bucket( self, "ArtifactBucket", encryption=aws_s3.BucketEncryption.S3_MANAGED, removal_policy=core.RemovalPolicy.DESTROY) # CodeBuild codebuild_environment_variables = aws_codebuild.BuildEnvironmentVariable( value=website_bucket.bucket_name) codebuild_environment = aws_codebuild.BuildEnvironment( build_image=aws_codebuild.LinuxBuildImage. UBUNTU_14_04_PYTHON_3_7_1, compute_type=aws_codebuild.ComputeType.SMALL) codebuild_buildspec = aws_codebuild.BuildSpec.from_object( value=buildspec.BUILDSPEC) codebuild_project = aws_codebuild.PipelineProject( self, "CodeBuildProject", environment_variables={ "BUCKET_NAME": codebuild_environment_variables }, environment=codebuild_environment, build_spec=codebuild_buildspec, description="CodeBuild Project for {} Content".format( constants.PROJECT_CODE), timeout=core.Duration.seconds(amount=300)) # TODO: Lock down permissions for buckets codebuild_project.add_to_role_policy( aws_iam.PolicyStatement(actions=["s3:*"], effect=aws_iam.Effect.ALLOW, resources=[ website_bucket.arn_for_objects("*"), artifact_bucket.arn_for_objects("*"), website_bucket.bucket_arn, artifact_bucket.bucket_arn, ])) # Codepipeline codepipeline = aws_codepipeline.Pipeline( self, "CodePipelineWebsiteContent", artifact_bucket=artifact_bucket, stages=[ aws_codepipeline.StageProps( stage_name="Source", actions=[ aws_codepipeline_actions.GitHubSourceAction( oauth_token=core.SecretValue( value=constants.GITHUB_OAUTH_TOKEN), output=aws_codepipeline.Artifact( artifact_name="source"), owner=constants.GITHUB_USER_NAME, repo=constants.GITHUB_REPO_NAME, branch=constants.BRANCH_NAME, action_name="GithubSource", trigger=aws_codepipeline_actions.GitHubTrigger. WEBHOOK) ]), aws_codepipeline.StageProps( stage_name="Build", actions=[ aws_codepipeline_actions.CodeBuildAction( input=aws_codepipeline.Artifact( artifact_name="source"), project=codebuild_project, type=aws_codepipeline_actions.CodeBuildActionType. BUILD, action_name="HugoBuild") ]) ]) # TODO: Lock down permissions for buckets codepipeline.add_to_role_policy( aws_iam.PolicyStatement(actions=["s3:*"], effect=aws_iam.Effect.ALLOW, resources=[ website_bucket.arn_for_objects("*"), artifact_bucket.arn_for_objects("*"), website_bucket.bucket_arn, artifact_bucket.bucket_arn, ]))