title: Configuring CloudFront distribution with S3 Origin and Custom Origin (ELB) using AWS CDK
body: <p>I have an app that uses Django and Vue.js. Currently the API is served on <code>api.mydomain.com</code> that sends traffic to an Application Load Balancer which routes to Fargate services and the Vue.js static site is served on <code>mydomain.com</code> which sends traffic to a CloudFront distribution in front of an S3 bucket where the site's static assets are stored. </p>
  
  <p>I would like to serve the API on <code>mydomain.com/api/*</code>, without using a subdomain, and continue to serve the static site on <code>mydomain.com</code>. </p>
  
  <p>The ALB is working just fine, I can go to the ALB's auto-generated AWS URL and get the correct response from my Fargate service.</p>
  
  <p>Here is the CDK code for my CloudFront distribution: </p>
  
  <pre class="lang-py prettyprint-override"><code>import os
  
  from aws_cdk import (
      aws_certificatemanager as acm,
      aws_s3 as s3,
      aws_cloudfront as cloudfront,
      aws_route53 as route53,
      aws_iam as iam,
      aws_route53_targets as targets,
      core,
  )
  
  
  class StaticSite(core.Construct):
      def __init__(
          self,
          scope: core.Construct,
          id: str,
          hosted_zone: route53.IHostedZone,
          certificate: acm.ICertificate,
          alb: str,
          **kwargs,
      ) -&gt; None:
          super().__init__(scope, id, **kwargs)
  
          self.static_site_bucket = s3.Bucket(
              self,
              "StaticSiteBucket",
              access_control=s3.BucketAccessControl.PUBLIC_READ,
              bucket_name=os.environ.get("DOMAIN_NAME", "mysite.com"),
              removal_policy=core.RemovalPolicy.DESTROY,
          )
  
          self.policy_statement = iam.PolicyStatement(
              actions=["s3:GetObject"],
              resources=[f"{self.static_site_bucket.bucket_arn}/*"],
          )
  
          self.policy_statement.add_any_principal()
  
          self.static_site_policy_document = iam.PolicyDocument(
              statements=[self.policy_statement]
          )
  
          self.static_site_bucket.add_to_resource_policy(self.policy_statement)
  
          self.distribution = cloudfront.CloudFrontWebDistribution(
              self,
              "CloudFrontDistribution",
              origin_configs=[
                  cloudfront.SourceConfiguration(
                      s3_origin_source=cloudfront.S3OriginConfig(
                          s3_bucket_source=self.static_site_bucket
                      ),
                      behaviors=[cloudfront.Behavior(is_default_behavior=True)],
                  ),
                  cloudfront.SourceConfiguration(
                      # origin_path="/test",
                      custom_origin_source=cloudfront.CustomOriginConfig(
                          domain_name=alb,
                      ),
                      behaviors=[
                          cloudfront.Behavior(
                              path_pattern="/test",
                              # forwarded_values={"headers": ["*"], "query_string": True},
                          )
                      ],
                  ),
              ],
              alias_configuration=cloudfront.AliasConfiguration(
                  acm_cert_ref=certificate.certificate_arn,
                  names=[
                      os.environ.get("DOMAIN_NAME", "mysite.com"),
                      f"*.{os.environ.get('DOMAIN_NAME', 'mysite.com')}",
                  ],
              ),
              error_configurations=[
                  {
                      "errorCode": 403,
                      "errorCachingMinTtl": 0,
                      "responseCode": 200,
                      "responsePagePath": "/index.html",
                  },
                  {
                      "errorCode": 404,
                      "errorCachingMinTtl": 0,
                      "responseCode": 200,
                      "responsePagePath": "/index.html",
                  },
              ],
          )
  
          route53.ARecord(
              self,
              "AliasRecord1",
              target=route53.AddressRecordTarget.from_alias(
                  targets.CloudFrontTarget(self.distribution)
              ),
              zone=hosted_zone.hosted_zone,
              # don't forget the '.' at the end of the record name!
              record_name=f"{os.environ.get('DOMAIN_NAME', 'mysite.com')}.",
          )
  </code></pre>
  
  <p>Here is the code for my Application Load Balancer: </p>
  
  <pre class="lang-py prettyprint-override"><code>from aws_cdk import (
      aws_iam as iam,
      aws_ec2 as ec2,
      aws_route53 as route53,
      aws_certificatemanager as acm,
      aws_elasticloadbalancingv2 as elbv2,
      core,
  )
  
  
  class ApplicationLoadBalancer(core.Construct):
      def __init__(
          self,
          scope: core.Construct,
          id: str,
          hosted_zone: route53.IHostedZone,
          certificate: acm.ICertificate,
          vpc: ec2.IVpc,
          **kwargs
      ) -&gt; None:
          super().__init__(scope, id, **kwargs)
  
          self.alb = elbv2.ApplicationLoadBalancer(
              self, "ALB", internet_facing=True, vpc=vpc
          )
  
          self.alb.connections.allow_from_any_ipv4(
              ec2.Port.tcp(80), "Internet access ALB 80"
          )
  
          self.alb.connections.allow_from_any_ipv4(
              ec2.Port.tcp(443), "Internet access ALB 443"
          )
  
          # redirect_listener = elbv2.CfnListener(
          #     self,
          #     "RedirectListener",
          #     protocol="HTTP",
          #     port=80,
          #     load_balancer_arn=self.alb.load_balancer_arn,
          #     default_actions=[
          #         {
          #             "type": "redirect",
          #             "redirectConfig": {
          #                 "host": "#{host}",
          #                 "path": "/#{path}",
          #                 "port": "443",
          #                 "protocol": "HTTPS",
          #                 "query": "#{query}",
          #                 "statusCode": "HTTP_301",
          #             },
          #         }
          #     ],
          # )
  
          # I think this part is incorrect
          self.redirect_response = elbv2.RedirectResponse(
              status_code="HTTP_301",
              host="#{host}",
              path="/#{path}",
              port="80",
              protocol="HTTPS",
              query="#{query}",
          )
  
          self.https_listener = elbv2.ApplicationListener(
              self,
              "HTTPSListener",
              load_balancer=self.alb,
              port=443,
              certificates=[
                  elbv2.ListenerCertificate(certificate.certificate_arn)
              ],
          )
  
          self.default_target_group = elbv2.ApplicationTargetGroup(
              self,
              "DefaultTargetGroup",
              port=80,
              protocol=elbv2.ApplicationProtocol.HTTP,
              vpc=vpc,
          )
  
          self.https_listener.add_target_groups(
              "DefaultTargetGroup", target_groups=[self.default_target_group]
          )
  </code></pre>
  
  <p>I'm not sure how SSL termination should work with CloudFront and ALB. Should the ALB only accept connections from the CloudFront distribution?</p>
  
  <p>Here is the output of <code>cdk synth</code>: </p>
  
  <pre><code>Resources:
    SiteCert6025247C:
      Type: AWS::CertificateManager::Certificate
      Properties:
        DomainName: mydomain.com
        DomainValidationOptions:
          - DomainName: mydomain.com
            ValidationDomain: mydomain.com
          - DomainName: "*.mydomain.com"
            ValidationDomain: mydomain.com
        SubjectAlternativeNames:
          - "*.mydomain.com"
        ValidationMethod: DNS
      Metadata:
        aws:cdk:path: awscdk/SiteCert/Resource
    VpcC3027511:
      Type: AWS::EC2::VPC
      Properties:
        CidrBlock: 10.0.0.0/16
        EnableDnsHostnames: true
        EnableDnsSupport: true
        InstanceTenancy: default
        Tags:
          - Key: Name
            Value: awscdk/Vpc/Vpc
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/Resource
    VpcPublicSubnet1Subnet8E8DEDC0:
      Type: AWS::EC2::Subnet
      Properties:
        CidrBlock: 10.0.0.0/24
        VpcId:
          Ref: VpcC3027511
        AvailabilityZone:
          Fn::Select:
            - 0
            - Fn::GetAZs: ""
        MapPublicIpOnLaunch: true
        Tags:
          - Key: Name
            Value: awscdk/Vpc/Vpc/PublicSubnet1
          - Key: aws-cdk:subnet-name
            Value: Public
          - Key: aws-cdk:subnet-type
            Value: Public
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/PublicSubnet1/Subnet
    VpcPublicSubnet1RouteTable431DD755:
      Type: AWS::EC2::RouteTable
      Properties:
        VpcId:
          Ref: VpcC3027511
        Tags:
          - Key: Name
            Value: awscdk/Vpc/Vpc/PublicSubnet1
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/PublicSubnet1/RouteTable
    VpcPublicSubnet1RouteTableAssociationBBCB7AA1:
      Type: AWS::EC2::SubnetRouteTableAssociation
      Properties:
        RouteTableId:
          Ref: VpcPublicSubnet1RouteTable431DD755
        SubnetId:
          Ref: VpcPublicSubnet1Subnet8E8DEDC0
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/PublicSubnet1/RouteTableAssociation
    VpcPublicSubnet1DefaultRoute0F5C6C43:
      Type: AWS::EC2::Route
      Properties:
        RouteTableId:
          Ref: VpcPublicSubnet1RouteTable431DD755
        DestinationCidrBlock: 0.0.0.0/0
        GatewayId:
          Ref: VpcIGW488B0FEB
      DependsOn:
        - VpcVPCGW42EC8516
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/PublicSubnet1/DefaultRoute
    VpcPublicSubnet2SubnetA811849C:
      Type: AWS::EC2::Subnet
      Properties:
        CidrBlock: 10.0.1.0/24
        VpcId:
          Ref: VpcC3027511
        AvailabilityZone:
          Fn::Select:
            - 1
            - Fn::GetAZs: ""
        MapPublicIpOnLaunch: true
        Tags:
          - Key: Name
            Value: awscdk/Vpc/Vpc/PublicSubnet2
          - Key: aws-cdk:subnet-name
            Value: Public
          - Key: aws-cdk:subnet-type
            Value: Public
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/PublicSubnet2/Subnet
    VpcPublicSubnet2RouteTable77FB35FC:
      Type: AWS::EC2::RouteTable
      Properties:
        VpcId:
          Ref: VpcC3027511
        Tags:
          - Key: Name
            Value: awscdk/Vpc/Vpc/PublicSubnet2
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/PublicSubnet2/RouteTable
    VpcPublicSubnet2RouteTableAssociation3AFE92E6:
      Type: AWS::EC2::SubnetRouteTableAssociation
      Properties:
        RouteTableId:
          Ref: VpcPublicSubnet2RouteTable77FB35FC
        SubnetId:
          Ref: VpcPublicSubnet2SubnetA811849C
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/PublicSubnet2/RouteTableAssociation
    VpcPublicSubnet2DefaultRouteD629179A:
      Type: AWS::EC2::Route
      Properties:
        RouteTableId:
          Ref: VpcPublicSubnet2RouteTable77FB35FC
        DestinationCidrBlock: 0.0.0.0/0
        GatewayId:
          Ref: VpcIGW488B0FEB
      DependsOn:
        - VpcVPCGW42EC8516
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/PublicSubnet2/DefaultRoute
    VpcIsolatedSubnet1SubnetDC3C6AF8:
      Type: AWS::EC2::Subnet
      Properties:
        CidrBlock: 10.0.2.0/24
        VpcId:
          Ref: VpcC3027511
        AvailabilityZone:
          Fn::Select:
            - 0
            - Fn::GetAZs: ""
        MapPublicIpOnLaunch: false
        Tags:
          - Key: Name
            Value: awscdk/Vpc/Vpc/IsolatedSubnet1
          - Key: aws-cdk:subnet-name
            Value: Isolated
          - Key: aws-cdk:subnet-type
            Value: Isolated
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/IsolatedSubnet1/Subnet
    VpcIsolatedSubnet1RouteTableF057227C:
      Type: AWS::EC2::RouteTable
      Properties:
        VpcId:
          Ref: VpcC3027511
        Tags:
          - Key: Name
            Value: awscdk/Vpc/Vpc/IsolatedSubnet1
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/IsolatedSubnet1/RouteTable
    VpcIsolatedSubnet1RouteTableAssociation0FC379C3:
      Type: AWS::EC2::SubnetRouteTableAssociation
      Properties:
        RouteTableId:
          Ref: VpcIsolatedSubnet1RouteTableF057227C
        SubnetId:
          Ref: VpcIsolatedSubnet1SubnetDC3C6AF8
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/IsolatedSubnet1/RouteTableAssociation
    VpcIsolatedSubnet2SubnetB479B99C:
      Type: AWS::EC2::Subnet
      Properties:
        CidrBlock: 10.0.3.0/24
        VpcId:
          Ref: VpcC3027511
        AvailabilityZone:
          Fn::Select:
            - 1
            - Fn::GetAZs: ""
        MapPublicIpOnLaunch: false
        Tags:
          - Key: Name
            Value: awscdk/Vpc/Vpc/IsolatedSubnet2
          - Key: aws-cdk:subnet-name
            Value: Isolated
          - Key: aws-cdk:subnet-type
            Value: Isolated
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/IsolatedSubnet2/Subnet
    VpcIsolatedSubnet2RouteTableBAB510EF:
      Type: AWS::EC2::RouteTable
      Properties:
        VpcId:
          Ref: VpcC3027511
        Tags:
          - Key: Name
            Value: awscdk/Vpc/Vpc/IsolatedSubnet2
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/IsolatedSubnet2/RouteTable
    VpcIsolatedSubnet2RouteTableAssociation8E8989F5:
      Type: AWS::EC2::SubnetRouteTableAssociation
      Properties:
        RouteTableId:
          Ref: VpcIsolatedSubnet2RouteTableBAB510EF
        SubnetId:
          Ref: VpcIsolatedSubnet2SubnetB479B99C
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/IsolatedSubnet2/RouteTableAssociation
    VpcIGW488B0FEB:
      Type: AWS::EC2::InternetGateway
      Properties:
        Tags:
          - Key: Name
            Value: awscdk/Vpc/Vpc
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/IGW
    VpcVPCGW42EC8516:
      Type: AWS::EC2::VPCGatewayAttachment
      Properties:
        VpcId:
          Ref: VpcC3027511
        InternetGatewayId:
          Ref: VpcIGW488B0FEB
      Metadata:
        aws:cdk:path: awscdk/Vpc/Vpc/VPCGW
    ApplicationLoadBalancerALBE88818A8:
      Type: AWS::ElasticLoadBalancingV2::LoadBalancer
      Properties:
        Scheme: internet-facing
        SecurityGroups:
          - Fn::GetAtt:
              - ApplicationLoadBalancerALBSecurityGroup0D676F12
              - GroupId
        Subnets:
          - Ref: VpcPublicSubnet1Subnet8E8DEDC0
          - Ref: VpcPublicSubnet2SubnetA811849C
        Type: application
      DependsOn:
        - VpcPublicSubnet1DefaultRoute0F5C6C43
        - VpcPublicSubnet2DefaultRouteD629179A
      Metadata:
        aws:cdk:path: awscdk/ApplicationLoadBalancer/ALB/Resource
    ApplicationLoadBalancerALBSecurityGroup0D676F12:
      Type: AWS::EC2::SecurityGroup
      Properties:
        GroupDescription: Automatically created Security Group for ELB awscdkApplicationLoadBalancerALB81FD6B77
        SecurityGroupIngress:
          - CidrIp: 0.0.0.0/0
            Description: Internet access ALB 80
            FromPort: 80
            IpProtocol: tcp
            ToPort: 80
          - CidrIp: 0.0.0.0/0
            Description: Internet access ALB 443
            FromPort: 443
            IpProtocol: tcp
            ToPort: 443
        VpcId:
          Ref: VpcC3027511
      Metadata:
        aws:cdk:path: awscdk/ApplicationLoadBalancer/ALB/SecurityGroup/Resource
    ApplicationLoadBalancerALBSecurityGrouptoawscdkBackendBackendServiceSecurityGroupD69D8DD280A0C3942C:
      Type: AWS::EC2::SecurityGroupEgress
      Properties:
        GroupId:
          Fn::GetAtt:
            - ApplicationLoadBalancerALBSecurityGroup0D676F12
            - GroupId
        IpProtocol: tcp
        Description: Load balancer to target
        DestinationSecurityGroupId:
          Fn::GetAtt:
            - BackendBackendServiceSecurityGroupA039445A
            - GroupId
        FromPort: 80
        ToPort: 80
      Metadata:
        aws:cdk:path: awscdk/ApplicationLoadBalancer/ALB/SecurityGroup/to awscdkBackendBackendServiceSecurityGroupD69D8DD2:80
    ApplicationLoadBalancerHTTPSListenerC96D73F5:
      Type: AWS::ElasticLoadBalancingV2::Listener
      Properties:
        DefaultActions:
          - TargetGroupArn:
              Ref: ApplicationLoadBalancerDefaultTargetGroupF1B3D7D1
            Type: forward
        LoadBalancerArn:
          Ref: ApplicationLoadBalancerALBE88818A8
        Port: 443
        Protocol: HTTPS
        Certificates:
          - CertificateArn:
              Ref: SiteCert6025247C
      Metadata:
        aws:cdk:path: awscdk/ApplicationLoadBalancer/HTTPSListener/Resource
    ApplicationLoadBalancerHTTPSListenerBackendTargetGroupA4042837:
      Type: AWS::ElasticLoadBalancingV2::TargetGroup
      Properties:
        Port: 80
        Protocol: HTTP
        TargetType: ip
        VpcId:
          Ref: VpcC3027511
      Metadata:
        aws:cdk:path: awscdk/ApplicationLoadBalancer/HTTPSListener/BackendTargetGroup/Resource
    ApplicationLoadBalancerHTTPSListenerBackendTargetRuleA3A291E2:
      Type: AWS::ElasticLoadBalancingV2::ListenerRule
      Properties:
        Actions:
          - TargetGroupArn:
              Ref: ApplicationLoadBalancerHTTPSListenerBackendTargetGroupA4042837
            Type: forward
        Conditions:
          - Field: path-pattern
            Values:
              - "*"
        ListenerArn:
          Ref: ApplicationLoadBalancerHTTPSListenerC96D73F5
        Priority: 1
      Metadata:
        aws:cdk:path: awscdk/ApplicationLoadBalancer/HTTPSListener/BackendTargetRule/Resource
    ApplicationLoadBalancerDefaultTargetGroupF1B3D7D1:
      Type: AWS::ElasticLoadBalancingV2::TargetGroup
      Properties:
        Port: 80
        Protocol: HTTP
        VpcId:
          Ref: VpcC3027511
      Metadata:
        aws:cdk:path: awscdk/ApplicationLoadBalancer/DefaultTargetGroup/Resource
    StaticSiteStaticSiteBucket442CE34F:
      Type: AWS::S3::Bucket
      Properties:
        AccessControl: PublicRead
        BucketName: mydomain.com
      UpdateReplacePolicy: Delete
      DeletionPolicy: Delete
      Metadata:
        aws:cdk:path: awscdk/StaticSite/StaticSiteBucket/Resource
    StaticSiteStaticSiteBucketPolicyC8E62485:
      Type: AWS::S3::BucketPolicy
      Properties:
        Bucket:
          Ref: StaticSiteStaticSiteBucket442CE34F
        PolicyDocument:
          Statement:
            - Action: s3:GetObject
              Effect: Allow
              Principal: "*"
              Resource:
                Fn::Join:
                  - ""
                  - - Fn::GetAtt:
                        - StaticSiteStaticSiteBucket442CE34F
                        - Arn
                    - /*
          Version: "2012-10-17"
      Metadata:
        aws:cdk:path: awscdk/StaticSite/StaticSiteBucket/Policy/Resource
    StaticSiteCloudFrontDistributionCFDistributionA70E78CD:
      Type: AWS::CloudFront::Distribution
      Properties:
        DistributionConfig:
          Aliases:
            - mydomain.com
            - "*.mydomain.com"
          CacheBehaviors:
            - AllowedMethods:
                - GET
                - HEAD
              CachedMethods:
                - GET
                - HEAD
              Compress: true
              ForwardedValues:
                Headers:
                  - "*"
                QueryString: true
              PathPattern: /test
              TargetOriginId: origin2
              ViewerProtocolPolicy: redirect-to-https
          CustomErrorResponses:
            - ErrorCachingMinTTL: 0
              ErrorCode: 403
              ResponseCode: 200
              ResponsePagePath: /index.html
            - ErrorCachingMinTTL: 0
              ErrorCode: 404
              ResponseCode: 200
              ResponsePagePath: /index.html
          DefaultCacheBehavior:
            AllowedMethods:
              - GET
              - HEAD
            CachedMethods:
              - GET
              - HEAD
            Compress: true
            ForwardedValues:
              Cookies:
                Forward: none
              QueryString: false
            TargetOriginId: origin1
            ViewerProtocolPolicy: redirect-to-https
          DefaultRootObject: index.html
          Enabled: true
          HttpVersion: http2
          IPV6Enabled: true
          Origins:
            - DomainName:
                Fn::GetAtt:
                  - StaticSiteStaticSiteBucket442CE34F
                  - RegionalDomainName
              Id: origin1
              S3OriginConfig: {}
            - CustomOriginConfig:
                HTTPPort: 80
                HTTPSPort: 443
                OriginKeepaliveTimeout: 5
                OriginProtocolPolicy: https-only
                OriginReadTimeout: 30
                OriginSSLProtocols:
                  - TLSv1.2
              DomainName:
                Fn::GetAtt:
                  - ApplicationLoadBalancerALBE88818A8
                  - DNSName
              Id: origin2
          PriceClass: PriceClass_100
          ViewerCertificate:
            AcmCertificateArn:
              Ref: SiteCert6025247C
            SslSupportMethod: sni-only
      Metadata:
        aws:cdk:path: awscdk/StaticSite/CloudFrontDistribution/CFDistribution
    StaticSiteAliasRecord4F27A661:
      Type: AWS::Route53::RecordSet
      Properties:
        Name: "*.mydomain.com."
        Type: A
        AliasTarget:
          DNSName:
            Fn::GetAtt:
              - StaticSiteCloudFrontDistributionCFDistributionA70E78CD
              - DomainName
          HostedZoneId: Z2FDTNDATAQYW2
        HostedZoneId: Z1EJVU8DMBV0XG
      Metadata:
        aws:cdk:path: awscdk/StaticSite/AliasRecord/Resource
    StaticSiteAliasRecord1B2F1F710:
      Type: AWS::Route53::RecordSet
      Properties:
        Name: mydomain.com.
        Type: A
        AliasTarget:
          DNSName:
            Fn::GetAtt:
              - StaticSiteCloudFrontDistributionCFDistributionA70E78CD
              - DomainName
          HostedZoneId: Z2FDTNDATAQYW2
        HostedZoneId: Z1EJVU8DMBV0XG
      Metadata:
        aws:cdk:path: awscdk/StaticSite/AliasRecord1/Resource
    ElasticContainerRepo2908E7AA:
      Type: AWS::ECR::Repository
      Properties:
        RepositoryName: mydomain.com/backend
      UpdateReplacePolicy: Retain
      DeletionPolicy: Retain
      Metadata:
        aws:cdk:path: awscdk/ElasticContainerRepo/Resource
    EcsEcsCluster51C39CA0:
      Type: AWS::ECS::Cluster
      Metadata:
        aws:cdk:path: awscdk/Ecs/EcsCluster/Resource
    BackendBackendTaskTaskRoleD7BBECAE:
      Type: AWS::IAM::Role
      Properties:
        AssumeRolePolicyDocument:
          Statement:
            - Action: sts:AssumeRole
              Effect: Allow
              Principal:
                Service: ecs-tasks.amazonaws.com
          Version: "2012-10-17"
      Metadata:
        aws:cdk:path: awscdk/Backend/BackendTask/TaskRole/Resource
    BackendBackendTask22B2DD1D:
      Type: AWS::ECS::TaskDefinition
      Properties:
        ContainerDefinitions:
          - Essential: true
            Image: nginx:alpine
            Name: nginx
            PortMappings:
              - ContainerPort: 80
                Protocol: tcp
        Cpu: "256"
        Family: awscdkBackendBackendTask594F440A
        Memory: "512"
        NetworkMode: awsvpc
        RequiresCompatibilities:
          - FARGATE
        TaskRoleArn:
          Fn::GetAtt:
            - BackendBackendTaskTaskRoleD7BBECAE
            - Arn
      Metadata:
        aws:cdk:path: awscdk/Backend/BackendTask/Resource
    BackendBackendService9DB18AD9:
      Type: AWS::ECS::Service
      Properties:
        Cluster:
          Ref: EcsEcsCluster51C39CA0
        DeploymentConfiguration:
          MaximumPercent: 200
          MinimumHealthyPercent: 50
        DesiredCount: 1
        EnableECSManagedTags: false
        HealthCheckGracePeriodSeconds: 60
        LaunchType: FARGATE
        LoadBalancers:
          - ContainerName: nginx
            ContainerPort: 80
            TargetGroupArn:
              Ref: ApplicationLoadBalancerHTTPSListenerBackendTargetGroupA4042837
        NetworkConfiguration:
          AwsvpcConfiguration:
            AssignPublicIp: ENABLED
            SecurityGroups:
              - Fn::GetAtt:
                  - BackendBackendServiceSecurityGroupA039445A
                  - GroupId
            Subnets:
              - Ref: VpcPublicSubnet1Subnet8E8DEDC0
              - Ref: VpcPublicSubnet2SubnetA811849C
        TaskDefinition:
          Ref: BackendBackendTask22B2DD1D
      DependsOn:
        - ApplicationLoadBalancerHTTPSListenerBackendTargetRuleA3A291E2
      Metadata:
        aws:cdk:path: awscdk/Backend/BackendService/Service
    BackendBackendServiceSecurityGroupA039445A:
      Type: AWS::EC2::SecurityGroup
      Properties:
        GroupDescription: awscdk/Backend/BackendService/SecurityGroup
        SecurityGroupEgress:
          - CidrIp: 0.0.0.0/0
            Description: Allow all outbound traffic by default
            IpProtocol: "-1"
        VpcId:
          Ref: VpcC3027511
      Metadata:
        aws:cdk:path: awscdk/Backend/BackendService/SecurityGroup/Resource
    BackendBackendServiceSecurityGroupfromawscdkApplicationLoadBalancerALBSecurityGroup5E233E2F80CC189352:
      Type: AWS::EC2::SecurityGroupIngress
      Properties:
        IpProtocol: tcp
        Description: Load balancer to target
        FromPort: 80
        GroupId:
          Fn::GetAtt:
            - BackendBackendServiceSecurityGroupA039445A
            - GroupId
        SourceSecurityGroupId:
          Fn::GetAtt:
            - ApplicationLoadBalancerALBSecurityGroup0D676F12
            - GroupId
        ToPort: 80
      Metadata:
        aws:cdk:path: awscdk/Backend/BackendService/SecurityGroup/from awscdkApplicationLoadBalancerALBSecurityGroup5E233E2F:80
    CDKMetadata:
      Type: AWS::CDK::Metadata
      Properties:
        ...
  </code></pre>
  
  <p>Here is the full repo with the branch that I am trying to implement IaC with CDK <a href="https://gitlab.com/verbose-equals-true/django-postgres-vue-gitlab-ecs/-/tree/feature-aws-cdk" rel="nofollow noreferrer">https://gitlab.com/verbose-equals-true/django-postgres-vue-gitlab-ecs/-/tree/feature-aws-cdk</a>. I'm trying to move this project from CloudFormation to CDK</p>