def map_base_subdomain(self, subdomain: str, api: aws_apigateway.RestApi) -> str: """ Maps a sub-domain of aws.job4u.io to an API gateway :param subdomain: The sub-domain (e.g. "www") :param api: The API gateway endpoint :return: The base url (e.g. "https://www.aws.job4u.io") """ domain_name = subdomain + '.' + ZONE_NAME url = 'https://' + domain_name cert = aws_certificatemanager.Certificate.from_certificate_arn(self, 'DomainCertificate', ZONE_CERT) hosted_zone = aws_route53.HostedZone.from_hosted_zone_attributes(self, 'HostedZone', hosted_zone_id=ZONE_ID, zone_name=ZONE_NAME) # add the domain name to the api and the A record to our hosted zone domain = api.add_domain_name('Domain', certificate=cert, domain_name=domain_name) aws_route53.ARecord( self, 'UrlShortenerDomain', record_name=subdomain, zone=hosted_zone, target=aws_route53.RecordTarget.from_alias(aws_route53_targets.ApiGatewayDomain(domain))) return url
def __init__(self, scope: core.App, id: str, props: DomainStackProps, **kwargs) -> None: super().__init__(scope, id, **kwargs) domain = apigw.DomainName( self, "domain", domain_name=props.domain_name, certificate=acm.Certificate.from_certificate_arn( self, 'cert', props.certificate_arn), endpoint_type=apigw.EndpointType.REGIONAL, ) self.domain = domain route53.ARecord(self, "AliasRecord", zone=route53.HostedZone.from_lookup( self, 'zone', domain_name=props.domain_name), target=route53.RecordTarget.from_alias( route53_targets.ApiGatewayDomain(domain)))
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, cert_arn, **kwargs) -> None: super().__init__(scope, id, **kwargs) # The code that defines your stack goes here # -- Lambda function my_function = _lambda.Function( self, "MyFunction", code=_lambda.Code.from_asset("dist"), handler="myfunction", runtime=_lambda.Runtime.GO_1_X, log_retention=aws_logs.RetentionDays.ONE_WEEK, memory_size=128, events=[], ) # -- API Gateway my_api = apigateway.RestApi(self, "MyApi") myfunction_integration = apigateway.LambdaIntegration(my_function) test_resource = my_api.root.add_resource("test") test_resource.add_method("GET", myfunction_integration) # -- DNS Configuration # Get the Route53 Zone dns_zone = route53.HostedZone.from_lookup(self, "ApiZone", private_zone=False, domain_name="zoolite.eu") # Get the certificate api_domain_cert = certificatemanager.Certificate.from_certificate_arn( self, "DomainCertificate", cert_arn) # Create the Custom Domain api_dns_name = apigateway.DomainName( self, "ApiDomainName", domain_name="my-api.zoolite.eu", endpoint_type=apigateway.EndpointType.REGIONAL, certificate=api_domain_cert, security_policy=apigateway.SecurityPolicy.TLS_1_2) #api_dns_name.add_base_path_mapping(my_api, base_path="test") api_dns_name.add_base_path_mapping(my_api) # Create the Route53 record api_dns_record = route53.ARecord( self, "MyAPiDNSRecord", target=route53.RecordTarget.from_alias( route53_targets.ApiGatewayDomain(api_dns_name)), record_name="my-api", zone=dns_zone) # Configure latency based routing on record recordset = api_dns_record.node.default_child recordset.region = self.region recordset.set_identifier = api_dns_record.node.unique_id
def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) core.Tags.of(self).add("Project", "Blog") core_layer = lambda_.LayerVersion( self, "blog-core-layer", code=lambda_.Code.from_asset("lambda/core_layer"), compatible_runtimes=[lambda_.Runtime.PYTHON_3_8] ) proxy_fn = lambda_.Function( self, "blog-proxy-fn", runtime=lambda_.Runtime.PYTHON_3_8, handler="lambda_function.handler", code=lambda_.Code.from_asset("lambda/proxy"), layers=[core_layer] ) proxy_fn_integration = apigw.LambdaIntegration(proxy_fn) domain_name = apigw.DomainName( self, "blog-api-domain-name", domain_name="api.juliuskrahn.com", certificate=cm.Certificate.from_certificate_arn( self, "blog-domain-name-certificate", "arn:aws:acm:us-east-1:473883619336:certificate/1ad12871-4b46-44ef-a24d-7af5ac43972b" ), endpoint_type=apigw.EndpointType.EDGE ) api = apigw.RestApi( self, "blog-api", default_cors_preflight_options=apigw.CorsOptions( allow_origins=apigw.Cors.ALL_ORIGINS, allow_methods=apigw.Cors.ALL_METHODS ), default_integration=proxy_fn_integration ) domain_name.add_base_path_mapping(api) route53.ARecord( self, "blog-api-a-record", record_name="api", target=route53.RecordTarget.from_alias(route53_targets.ApiGatewayDomain(domain_name)), zone=route53.HostedZone.from_lookup(self, "blog-hosted-zone", domain_name="juliuskrahn.com") ) api.root.add_proxy() article_table = dynamodb.Table( self, "blog-article-table", table_name="blog-article", partition_key=dynamodb.Attribute(name="urlTitle", type=dynamodb.AttributeType.STRING), billing_mode=dynamodb.BillingMode.PAY_PER_REQUEST, point_in_time_recovery=True ) article_table.add_global_secondary_index( index_name="tagIndex", partition_key=dynamodb.Attribute(name="tag", type=dynamodb.AttributeType.STRING), sort_key=dynamodb.Attribute(name="published", type=dynamodb.AttributeType.STRING), projection_type=dynamodb.ProjectionType.INCLUDE, non_key_attributes=["urlTitle", "title", "description"] ) article_table.grant_read_write_data(proxy_fn) comment_table = dynamodb.Table( self, "blog-comment-table", table_name="blog-comment", partition_key=dynamodb.Attribute(name="articleUrlTitle", type=dynamodb.AttributeType.STRING), sort_key=dynamodb.Attribute(name="id", type=dynamodb.AttributeType.STRING), billing_mode=dynamodb.BillingMode.PAY_PER_REQUEST ) comment_table.grant_read_write_data(proxy_fn) admin_key_secret = sm.Secret( self, "blog-admin-key", secret_name="blog-admin-key" ) admin_key_secret.grant_read(proxy_fn)
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, redirect_handler, create_handler, **kwargs) -> None: super().__init__(scope, id, **kwargs) base_api = api_gw.RestApi( scope=self, id='ShortenURLAPI', rest_api_name='dev-url-shortener-api', deploy=True, deploy_options=api_gw.StageOptions(stage_name='devShortenURL') ) # shortenUrl shorten_url = base_api.root.add_resource('shortenUrl') shorten_url_responses = [ api_gw.MethodResponse( status_code='200', response_models={"application/json": api_gw.Model.EMPTY_MODEL}, response_parameters={'method.response.header.Access-Control-Allow-Origin': True} ), api_gw.MethodResponse( status_code='500', response_models={"application/json": api_gw.Model.ERROR_MODEL}, ) ] shorten_url_lambda_integration = api_gw.LambdaIntegration( handler=create_handler, request_templates={"application/json": '{ "statusCode": "200" }'}, integration_responses=[ api_gw.IntegrationResponse( status_code='200', response_templates={'application/json': ''} ) ] ) shorten_url.add_method( http_method='POST', api_key_required=False, integration=shorten_url_lambda_integration, method_responses=shorten_url_responses ) shorten_url_integration_mock = api_gw.MockIntegration( request_templates={"application/json": json.dumps({"statusCode": 200})}, integration_responses=[ api_gw.IntegrationResponse( status_code='200', response_templates={'application/json': ''}, response_parameters={ "method.response.header.Access-Control-Allow-Methods": "'OPTIONS,POST'", "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", "method.response.header.Access-Control-Allow-Origin": "'*'", }, ) ], passthrough_behavior=api_gw.PassthroughBehavior.WHEN_NO_MATCH ) shorten_url_mock_reponses = api_gw.MethodResponse( status_code='200', response_models={ "application/json": api_gw.Model.EMPTY_MODEL }, response_parameters={ "method.response.header.Access-Control-Allow-Methods": True, "method.response.header.Access-Control-Allow-Headers": True, "method.response.header.Access-Control-Allow-Origin": True } ) shorten_url.add_method( http_method='OPTIONS', integration=shorten_url_integration_mock, method_responses=[shorten_url_mock_reponses] ) # {id} id_url = base_api.root.add_resource("{id}") id_url_responses = [ api_gw.MethodResponse( status_code='200', response_models={"application/json": api_gw.Model.EMPTY_MODEL}, response_parameters={'method.response.header.Access-Control-Allow-Origin': True} ) ] id_url_lambda_integration = api_gw.LambdaIntegration( handler=redirect_handler, request_templates={"application/json": '{ "statusCode": "200" }'}, integration_responses=[ api_gw.IntegrationResponse( status_code='200', response_templates={'application/json': ''} ) ] ) id_url.add_method( http_method='GET', integration=id_url_lambda_integration, method_responses=id_url_responses, request_parameters={'method.request.path.proxy': True} ) id_url_integration_mock = api_gw.MockIntegration( request_templates={"application/json": json.dumps({"statusCode": 200})}, integration_responses=[ api_gw.IntegrationResponse( status_code='200', response_templates={'application/json': ''}, response_parameters={ "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", "method.response.header.Access-Control-Allow-Origin": "'*'", }, ) ], passthrough_behavior=api_gw.PassthroughBehavior.WHEN_NO_MATCH ) id_url_mock_responses = api_gw.MethodResponse( status_code='200', response_models={ "application/json": api_gw.Model.EMPTY_MODEL }, response_parameters={ "method.response.header.Access-Control-Allow-Methods": True, "method.response.header.Access-Control-Allow-Headers": True, "method.response.header.Access-Control-Allow-Origin": True } ) id_url.add_method( http_method='OPTIONS', integration=id_url_integration_mock, method_responses=[id_url_mock_responses] ) # Create custom domain mapping API sel_cert_arn = "arn:aws:acm:ap-northeast-2:111111111111:certificate/b1111bf5-ae1b-1f61-a111-f1d839428f5f" apigw_domain = base_api.add_domain_name( id='ShortenURLIDCustomDomain', certificate=_acm.Certificate.from_certificate_arn( scope=self, id="ShortenURLIDCert", certificate_arn=sel_cert_arn ), security_policy=api_gw.SecurityPolicy.TLS_1_2, domain_name='s.cloudopz.co' ) dev_hosted_zone = 'A11AA1A1A1AAAA' hz_dev = _route53.HostedZone.from_hosted_zone_attributes( self, id="ShortenURLHostedZoneDev", hosted_zone_id=dev_hosted_zone, zone_name='cloudopz.co') _route53.ARecord( self, 'ShortenURLRoute53', record_name='s', zone=hz_dev, target=_route53.RecordTarget.from_alias(_route53_target.ApiGatewayDomain(apigw_domain)) )
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # Setting up a salck bot Lambda function bot_handler = aws_lambda.Function( self, "HitterBot", runtime=aws_lambda.Runtime.GO_1_X, handler="main", timeout=core.Duration.seconds(900), memory_size=2048, code=aws_lambda.AssetCode(path="./lambda")) # Creating Mutex Table in DynamoDB mutex_table = aws_dynamodb.Table( self, "HitterMutexTable", partition_key=aws_dynamodb.Attribute( name="ID", type=aws_dynamodb.AttributeType.STRING), billing_mode=aws_dynamodb.BillingMode.PAY_PER_REQUEST, time_to_live_attribute="TTL", removal_policy=core.RemovalPolicy.DESTROY, ) # Creating URL Table in DynamoDB url_table = aws_dynamodb.Table( self, "HitterURLTable", partition_key=aws_dynamodb.Attribute( name="ID", type=aws_dynamodb.AttributeType.STRING), billing_mode=aws_dynamodb.BillingMode.PAY_PER_REQUEST, time_to_live_attribute="TTL", removal_policy=core.RemovalPolicy.DESTROY, ) # Creating a bucket to be used in a Pre-Signed URL bucket = aws_s3.Bucket( self, "HitterS3", removal_policy=core.RemovalPolicy.RETAIN, block_public_access=aws_s3.BlockPublicAccess.BLOCK_ALL, ) # Configuring the S3 Lifecycle bucket.add_lifecycle_rule(expiration=core.Duration.days(2)) # Setting permission to the salck bot Lambda function mutex_table.grant_read_write_data(bot_handler) url_table.grant_read_write_data(bot_handler) bucket.grant_put(bot_handler) bucket.grant_read(bot_handler) bot_handler.add_to_role_policy( aws_iam.PolicyStatement( resources=["*"], actions=[ "comprehend:BatchDetectDominantLanguage", "translate:TranslateText" ])) # Setting environment variables to the salck bot Lambda function bot_handler.add_environment('SLACK_OAUTH_ACCESS_TOKEN', SLACK_OAUTH_ACCESS_TOKEN) bot_handler.add_environment('SLACK_VERIFICATION_TOKEN', SLACK_VERIFICATION_TOKEN) bot_handler.add_environment('MUTEX_TABLE_NAME', mutex_table.table_name) bot_handler.add_environment('URL_TABLE_NAME', url_table.table_name) bot_handler.add_environment('S3_BUCKET_NAME', bucket.bucket_name) bot_handler.add_environment('DEBUG_LOG', "false") # Creating an API Gateway for a slack bot bot_api = aws_apigateway.LambdaRestApi(self, "HitterBotAPI", handler=bot_handler) # Only once for the hosted zone. hosted_zone = aws_route53.HostedZone.from_hosted_zone_attributes( self, 'HitterHostedZone', hosted_zone_id=ZONE_ID, zone_name=ZONE_NAME) # Set the domain for a bot bot_subdomain = "hitter" bot_domain_name = bot_subdomain + '.' + ZONE_NAME # Using AWS ACM to create a certificate for a bot bot_cert = aws_certificatemanager.DnsValidatedCertificate( self, 'HitterBotCertificate', domain_name=bot_domain_name, hosted_zone=hosted_zone) # Add the domain name to the api and the A record to our hosted zone for a bot bot_domain = bot_api.add_domain_name('HitterBotDomain', certificate=bot_cert, domain_name=bot_domain_name) # Set the A record for a bot aws_route53.ARecord( self, 'HitterBotARecord', record_name=bot_subdomain, zone=hosted_zone, target=aws_route53.RecordTarget.from_alias( aws_route53_targets.ApiGatewayDomain(bot_domain))) # Setting up Short URL Lambda function short_url_handler = aws_lambda.Function( self, "HitterShortURL", runtime=aws_lambda.Runtime.GO_1_X, handler="main", timeout=core.Duration.seconds(900), memory_size=128, code=aws_lambda.AssetCode(path="./lambda_api")) # Setting environment variables to the Short URL Lambda function url_table.grant_read_data(short_url_handler) # Setting environment variables to the salck bot Lambda function short_url_handler.add_environment('URL_TABLE_NAME', url_table.table_name) short_url_handler.add_environment('DEBUG_LOG', "false") # Creating an API Gateway for a Short URL short_url_api = aws_apigateway.LambdaRestApi(self, "HitterShortURLAPI", handler=short_url_handler) # Set the domain for a Short URL short_url_subdomain = "sl" short_url_domain_name = short_url_subdomain + '.' + ZONE_NAME short_url = 'https://' + short_url_domain_name # Using AWS ACM to create a certificate for a Short URL short_url_cert = aws_certificatemanager.DnsValidatedCertificate( self, 'HitterShortURLCertificate', domain_name=short_url_domain_name, hosted_zone=hosted_zone) # Add the domain name to the api and the A record to our hosted zone for a Short URL short_url_domain = short_url_api.add_domain_name( 'HitterShortURLDomain', certificate=short_url_cert, domain_name=short_url_domain_name) # Set the A record for a Short URL aws_route53.ARecord( self, 'HitterShortURLARecord', record_name=short_url_subdomain, zone=hosted_zone, target=aws_route53.RecordTarget.from_alias( aws_route53_targets.ApiGatewayDomain(short_url_domain))) # Set the URL of the API Gateway to receive the shortened URL to an environment variable. bot_handler.add_environment('API_BASE_URL', short_url)
def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # Create a Lambda function # Code in ./src directory lambda_fn = lambda_.Function( self, "MyFunction", runtime=lambda_.Runtime.PYTHON_3_9, handler="index.handler", code=lambda_.Code.from_asset(os.path.join(DIRNAME, "src")) ) #Input parameter for custom domain name created for API Gateway, ex: apis.example.com custom_domain_name = cdk.CfnParameter(self, "customdomainname", type="String", description="The custom domain name for AWS REST API Gateway") #Input parameter for ACM certificate arn certificate_arn = cdk.CfnParameter(self, "certificatearn", type="String", description="The ACM certificate ARN for custom domain name") #Input parameter for s3 bucket name that has truststore pem file truststore_bucket = cdk.CfnParameter(self, "truststorebucket", type="String", description="The S3 trustsore uri for custom domain name") #Input parameter for public hosted zone id public_zone_id = cdk.CfnParameter(self, "publiczoneid", type="String", description="The public hosted zone id to create a record for custom domain name") #Input parameter for public hosted zone id public_zone_name = cdk.CfnParameter(self, "publiczonename", type="String", description="The public hosted zone name to create a record for custom domain name") # Create the Rest API rest_api = apigateway.RestApi( self, "TLSRestAPI", endpoint_types=[apigateway.EndpointType.REGIONAL], description="RestAPI Gateway to verify mutual TLS", deploy=False, retain_deployments=False, disable_execute_api_endpoint=True ) # Create the custom domain api_domain = apigateway.DomainName( self, "MyDomainName", domain_name=custom_domain_name.value_as_string, certificate=acm.Certificate.from_certificate_arn(self, "cert", certificate_arn.value_as_string), mtls=apigateway.MTLSConfig( bucket=s3.Bucket.from_bucket_name(self, "Bucket", truststore_bucket.value_as_string), key="/truststore.pem" ), security_policy=apigateway.SecurityPolicy.TLS_1_2 ) # Create API deployment deployment = apigateway.Deployment( self, "Deployment", api=rest_api, retain_deployments=False ) # Create prod Stage for deployment stage = apigateway.Stage( self, "prod", deployment=deployment, ) # Create API mapping to custom domain base_path_mapping = apigateway.BasePathMapping(self, "MyBasePathMapping", domain_name=api_domain, rest_api=rest_api, stage=stage ) #Get public hosted zone object public_zone = route53.HostedZone.from_hosted_zone_attributes(self, "publiczone", hosted_zone_id=public_zone_id.value_as_string,zone_name=public_zone_name.value_as_string) #Create A record for custom domain name in public hosted zone #Record name will be taken from custom domain name, ex: for apis.example.com, record name will be apis record = route53.ARecord(self, 'MyAliasRecord', zone=public_zone, record_name=cdk.Fn.select(0,cdk.Fn.split('.',custom_domain_name.value_as_string)), target=route53.RecordTarget.from_alias(targets.ApiGatewayDomain(api_domain)) ) rest_api.deployment_stage = stage # Create URI for lambda function stage_uri = f"arn:aws:apigateway:{cdk.Aws.REGION}:lambda:path/2015-03-31/functions/{lambda_fn.function_arn}/invocations" # Create Lambda Integration integration = apigateway.Integration( type=apigateway.IntegrationType.AWS_PROXY, integration_http_method="POST", uri=stage_uri ) # Create APIGW Method method = rest_api.root.add_method("GET", integration) # Add Lambda permissions lambda_fn.add_permission( "lambdaPermission", action="lambda:InvokeFunction", principal=iam.ServicePrincipal("apigateway.amazonaws.com"), source_arn=method.method_arn.replace( rest_api.deployment_stage.stage_name, "*" ) ) # OUTPUTS cdk.CfnOutput(self, "LambdaFunction", export_name="MyLambdaFunction", value=lambda_fn.function_arn) cdk.CfnOutput(self, "ApigwId", export_name="MyAPIGWID", value=rest_api.rest_api_id) cdk.CfnOutput(self, "CustomDomainName", export_name="MyCustomDomain", value=api_domain.domain_name) cdk.CfnOutput(self, "CustomDomainHostedZone", export_name="MyCustomeZone", value=api_domain.domain_name_alias_hosted_zone_id) cdk.CfnOutput(self, "CustomDomainAlias", export_name="MyCustomAlias", value=api_domain.domain_name_alias_domain_name)