diff --git a/deploy/README.md b/deploy/README.md index 3247665..773b23f 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -12,3 +12,7 @@ The `cdk.json` file tells the CDK Toolkit how to execute your app. * `cdk deploy` deploy this stack to your default AWS account/region * `cdk diff` compare deployed stack with current state * `cdk synth` emits the synthesized CloudFormation template + +## configuration, please set them as env var + * `LOCALTUNNEL_BASE_DOMAIN` the base domain for the localtunnel server, must be a root domain like example.com + * `LOCALTUNNEL_ROUTE53_ID` the ID of the route53 hosted zone for the domain diff --git a/deploy/bin/deploy.ts b/deploy/bin/deploy.ts index ffaeecd..1700437 100644 --- a/deploy/bin/deploy.ts +++ b/deploy/bin/deploy.ts @@ -3,5 +3,6 @@ import 'source-map-support/register'; import * as cdk from '@aws-cdk/core'; import { DeployStack } from '../lib/deploy-stack'; -const app = new cdk.App(); -new DeployStack(app, 'DeployStack'); +let app = new cdk.App(); +// replace them with HostedZoneID in route53, the domain name for the localtunnel, and the hosted zone domain +new DeployStack(app, 'DeployStack', process.env.LOCALTUNNEL_ROUTE53_ID as string , process.env.LOCALTUNNEL_BASE_DOMAIN as string); diff --git a/deploy/lib/deploy-stack.ts b/deploy/lib/deploy-stack.ts index f3344ab..9c3e3c8 100644 --- a/deploy/lib/deploy-stack.ts +++ b/deploy/lib/deploy-stack.ts @@ -5,8 +5,11 @@ import * as ec2 from "@aws-cdk/aws-ec2"; import * as ecs from "@aws-cdk/aws-ecs"; import * as ecs_patterns from "@aws-cdk/aws-ecs-patterns"; +// tls certificate with ACM +import * as route53 from '@aws-cdk/aws-route53'; +import * as acm from '@aws-cdk/aws-certificatemanager'; export class DeployStack extends cdk.Stack { - constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { + constructor(scope: cdk.Construct, id: string, hostedZoneID: string, domainName: string, props?: cdk.StackProps) { super(scope, id, props); // create vpc with 3 subnets const vpc = new ec2.Vpc(this, "LocalTunnelVPC", { @@ -16,18 +19,46 @@ export class DeployStack extends cdk.Stack { const cluster = new ecs.Cluster(this, "LocalTunnelCluster", { vpc: vpc }) + // create acm cert + const DNSZone = route53.HostedZone.fromHostedZoneAttributes(this, 'HostedZone', { + zoneName: domainName, + hostedZoneId: hostedZoneID + }) + // add wildcard CNAME + new route53.CnameRecord(this, 'CnameRecordWildcard', { + zone: DNSZone, + recordName: "*", + domainName: domainName + }) + const cert = new acm.Certificate(this, 'Cert', { + domainName: domainName, + subjectAlternativeNames: ["*."+domainName], + validation: acm.CertificateValidation.fromDns(DNSZone) + }) + + // create LBed Fargate service - new ecs_patterns.ApplicationLoadBalancedFargateService(this, "LocalTunnelService", { + let localtunnelsvc = new ecs_patterns.ApplicationLoadBalancedFargateService(this, "LocalTunnelService", { cluster: cluster, cpu: 512, desiredCount: 1, taskImageOptions: { image: ecs.ContainerImage.fromRegistry("defunctzombie/localtunnel-server:latest") + }, memoryLimitMiB: 2048, - publicLoadBalancer : true, - assignPublicIp: true + publicLoadBalancer: true, + certificate: cert, + redirectHTTP: true, + recordType: ecs_patterns.ApplicationLoadBalancedServiceRecordType.ALIAS, + listenerPort: 443, + domainName: domainName, + domainZone: DNSZone + }) + // set health route + localtunnelsvc.targetGroup.configureHealthCheck({ + path: "/api/status" }) } }