Configuración de la distribución de CloudFront con S3 Origin y Custom Origin (ELB) mediante AWS CDK

3

Tengo una aplicación que usa Django y Vue.js. Actualmente, se sirve la API api.mydomain.comque envía tráfico a un Balanceador de carga de aplicaciones que enruta a los servicios de Fargate y se sirve el sitio estático Vue.js en el mydomain.comque envía tráfico a una distribución de CloudFront frente a un depósito S3 donde se almacenan los activos estáticos del sitio.

Me gustaría servir la API en mydomain.com/api/*, sin usar un subdominio, y continuar sirviendo el sitio estático en mydomain.com.

El ALB está funcionando bien, puedo ir a la URL de AWS generada automáticamente por el ALB y obtener la respuesta correcta de mi servicio Fargate.

Aquí está el código CDK para mi distribución de CloudFront:

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,
    ) -> 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')}.",
        )

Aquí está el código de mi Application Load Balancer:

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
    ) -> 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]
        )

No estoy seguro de cómo debería funcionar la terminación SSL con CloudFront y ALB. ¿El ALB solo debe aceptar conexiones de la distribución de CloudFront?

Aquí está el resultado de cdk synth:

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:
      ...

Aquí está el repositorio completo con la rama que estoy tratando de implementar IaC con CDK https://gitlab.com/verbose-equals-true/django-postgres-vue-gitlab-ecs/-/tree/feature-aws-cdk . Estoy intentando mover este proyecto de CloudFormation a CDK

2
+500

Debe reenviar todas las cookies, encabezados y cadenas de consulta en cualquier comportamiento que apunte a su origen ALB. Probablemente también desee permitir todos los métodos si tiene la intención de enviar datos a este backend.

Aquí hay un ejemplo en TypeScript en el que estoy trabajando actualmente para un proyecto (se ve ligeramente diferente al suyo, pero debería ser fácil de adaptar)

const cdn = new cf.CloudFrontWebDistribution(this, 'SPACloudFrontDistribution', {
      originConfigs: [
        {
          customOriginSource: {
            domainName: alb.loadBalancerDnsName,
            originProtocolPolicy: cf.OriginProtocolPolicy.MATCH_VIEWER
          },
          behaviors : [ 
            { 
              isDefaultBehavior: true,
              allowedMethods: cf.CloudFrontAllowedMethods.ALL,
              forwardedValues: {
                queryString: true,
                cookies: {
                  forward: 'all'
                },
                headers: ['*']
              }
            } 
          ]
        },
        {
          s3OriginSource: {
            s3BucketSource: bucket
          },
          behaviors: [
            {
              pathPattern: '/static/*',
              allowedMethods: cf.CloudFrontAllowedMethods.GET_HEAD,
              cachedMethods: cf.CloudFrontAllowedCachedMethods.GET_HEAD
            }
          ]
        }
      ],
      aliasConfiguration: {
        acmCertRef: sslCert.certificateArn,
        names: domains
      },
      defaultRootObject: ''
    });