使用 AWS CDK 配置带有 S3 源和自定义源 (ELB) 的 CloudFront 分配

Configuring CloudFront distribution with S3 Origin and Custom Origin (ELB) using AWS CDK

我有一个使用 Django 和 Vue.js 的应用程序。目前 API 在 api.mydomain.com 上提供服务,它将流量发送到路由到 Fargate 服务的应用程序负载均衡器,而 Vue.js 静态站点在 mydomain.com 上提供服务,它将流量发送到CloudFront 分布在存储站点静态资产的 S3 存储桶前面。

我想在 mydomain.com/api/* 上提供 API,而不使用子域,并继续在 mydomain.com 上提供静态站点。

ALB 工作正常,我可以转到 ALB 的自动生成的 AWS URL 并从我的 Fargate 服务获得正确的响应。

这是我的 CloudFront 发行版的 CDK 代码:

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

这是我的应用程序负载均衡器的代码:

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

我不确定 SSL 终止应如何与 CloudFront 和 ALB 一起使用。 ALB 是否应该只接受来自 CloudFront 分配的连接?

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

这是我尝试使用 CDK https://gitlab.com/verbose-equals-true/django-postgres-vue-gitlab-ecs/-/tree/feature-aws-cdk 实现 IaC 的分支的完整回购协议。我正在尝试将此项目从 CloudFormation 移动到 CDK

您需要转发所有指向您的 ALB 来源的行为中的所有 cookie、headers 和查询字符串。如果您打算将数据发送到此后端,您可能也希望允许所有方法。

这是我目前正在为一个项目处理的 TypeScript 示例(它看起来与您的略有不同,但应该很容易适应)

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: ''
    });