amazon-web-servicesaws-cloudformationamazon-ecsaws-fargatenlb

Resource handler returned message: "Invalid request provided: Rules are unsupported for Network Load Balancer listeners


I'm creating a CloudFormation stack for ECS automation and I'm using an internal NLB.

I'm having a problem with the ListenerRule that returns the following error in CloudFormation: Resource handler returned message: "Invalid request provided: Rules are unsupported for Network Load Balancer listeners

My script is this:

AWSTemplateFormatVersion: 2010-09-09
Description: ECS Fargate

Parameters:
  Name:
    Type: String
  VPC:
    Type: AWS::EC2::VPC::Id
  Subnets:
    Type: List<AWS::EC2::Subnet::Id>
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup::Id 
  CreationVCPEndpoint:
    Type: String
    AllowedValues: [true, false]
  DesiredCount:
    Type: String

Conditions:
  CreationVCPEndpointSelected: !Equals [!Ref CreationVCPEndpoint, true]

Resources:
# Endpoints necessários para o serviço do ECS funcionar.
  EndpointLogs:
    Type: AWS::EC2::VPCEndpoint
    Condition: CreationVCPEndpointSelected
    Properties:
      ServiceName: !Join
        - ''
        - - com.amazonaws.
          - !Ref 'AWS::Region'
          - .logs
      PrivateDnsEnabled: true
      SecurityGroupIds: 
        - !Ref SecurityGroup
      SubnetIds: 
        Ref: Subnets
      VpcEndpointType: Interface
      VpcId: 
        Ref: VPC

  EndpointS3:
    Type: AWS::EC2::VPCEndpoint
    Condition: CreationVCPEndpointSelected
    Properties:
      ServiceName: !Join
        - ''
        - - com.amazonaws.
          - !Ref 'AWS::Region'
          - .s3
      PrivateDnsEnabled: true
      SecurityGroupIds: 
        - !Ref SecurityGroup
      SubnetIds: 
        Ref: Subnets
      VpcEndpointType: Interface
      VpcId: 
        Ref: VPC

  EndpointECR:
    Type: AWS::EC2::VPCEndpoint
    Condition: CreationVCPEndpointSelected
    Properties:
      ServiceName: !Join
        - ''
        - - com.amazonaws.
          - !Ref 'AWS::Region'
          - .ecr.api
      PrivateDnsEnabled: true
      SecurityGroupIds: 
        - !Ref SecurityGroup
      SubnetIds: 
        Ref: Subnets
      VpcEndpointType: Interface
      VpcId: 
        Ref: VPC

  EndpointSSM:
    Type: AWS::EC2::VPCEndpoint
    Condition: CreationVCPEndpointSelected
    Properties:
      ServiceName: !Join
        - ''
        - - com.amazonaws.
          - !Ref 'AWS::Region'
          - .ssm
      PrivateDnsEnabled: true
      SecurityGroupIds: 
        - !Ref SecurityGroup
      SubnetIds: 
        Ref: Subnets
      VpcEndpointType: Interface
      VpcId: 
        Ref: VPC

  EndpointDKR:
    Type: AWS::EC2::VPCEndpoint
    Condition: CreationVCPEndpointSelected
    Properties:
      ServiceName: !Join
        - ''
        - - com.amazonaws.
          - !Ref 'AWS::Region'
          - .ecr.dkr
      PrivateDnsEnabled: true
      SecurityGroupIds: 
        - !Ref SecurityGroup
      SubnetIds: 
        Ref: Subnets
      VpcEndpointType: Interface
      VpcId: 
        Ref: VPC

# Criação do NLB Privado
  LoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Ref Name
      Subnets: !Ref Subnets
      Type: network
      Scheme: internal
      Tags:
        - Key: Name
          Value: !Ref Name

  LoadBalancerListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      LoadBalancerArn: !Ref LoadBalancer
      Port: 80
      Protocol: TCP
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref TargetGroup

  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${Name}-tg
      VpcId: !Ref VPC
      Port: 80
      Protocol: TCP
      TargetType: ip

  ListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      ListenerArn: !Ref LoadBalancerListener
      Priority: 1
      Conditions:
        - Field: source-ip
          #Values:
          #  - /
      Actions:
        - TargetGroupArn: !Ref TargetGroup
          Type: forward

# Criação da IAM para o ECS
  ECSIAM:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          -
            Effect: "Allow"
            Principal:
              Service:
                - "ecs.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Path: "/"
      Policies:
        -
          PolicyName: !Ref Name
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              -
                Effect: "Allow"
                Action: "*"
                Resource: "*"

# Criação do ECS Fargate
  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: !Ref Name

  ECSService:
    Type: AWS::ECS::Service
    DependsOn: ListenerRule
    Properties:
      Cluster: !Ref ECSCluster
      Role: !Ref ECSIAM
      DesiredCount: !Ref DesiredCount
      TaskDefinition: !Ref ECSTaskDefinition
      LoadBalancers:
        - ContainerName: "website-service"
          ContainerPort: 80
          TargetGroupArn: !Ref TargetGroup

  ECSTaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: website-service
      NetworkMode: awsvpc
      ContainerDefinitions:
        - Name: website-service
          Essential: true
          Image: 489732776903.dkr.ecr.us-west-2.amazonaws.com/daniel:latest
          Memory: 128
          #Environment:
          #  - Name: PRODUCT_SERVICE_URL
          #    Value: !Ref ProductServiceUrl
          PortMappings:
            - ContainerPort: 80
          #LogConfiguration:
          #  LogDriver: awslogs
          #  Options:
          #    awslogs-group: !Ref CloudWatchLogsGroup
          #    awslogs-region: !Ref AWS::Region

Does anyone have any idea what the correct ListenerRule configuration is?


Solution

  • I managed to get the template right, there is the template ready.

    AWSTemplateFormatVersion: 2010-09-09
    
    Description: ECS Fargate
    
    Parameters:
    
      Name:
        Type: String
      
      VPC:
        Type: AWS::EC2::VPC::Id
    
      Subnets:
        Type: List<AWS::EC2::Subnet::Id>
    
      SecurityGroup:
        Type: AWS::EC2::SecurityGroup::Id 
    
      CreationVCPEndpoint:
        Type: String
        AllowedValues: [true, false]
    
      DesiredCount:
        Type: String
    
    Conditions:
      CreationVCPEndpointSelected: !Equals [!Ref CreationVCPEndpoint, true]
    
    Resources:
    
    # Endpoints necessários para o serviço do ECS funcionar.
    
      EndpointLogs:
        Type: AWS::EC2::VPCEndpoint
        Condition: CreationVCPEndpointSelected
        Properties:
          ServiceName: !Join
            - ''
            - - com.amazonaws.
              - !Ref 'AWS::Region'
              - .logs
          PrivateDnsEnabled: true
          SecurityGroupIds: 
            - !Ref SecurityGroup
          SubnetIds: 
            Ref: Subnets
          VpcEndpointType: Interface
          VpcId: 
            Ref: VPC
    
      EndpointS3:
        Type: AWS::EC2::VPCEndpoint
        Condition: CreationVCPEndpointSelected
        Properties:
          ServiceName: !Join
            - ''
            - - com.amazonaws.
              - !Ref 'AWS::Region'
              - .s3
          PrivateDnsEnabled: false
          SecurityGroupIds: 
            - !Ref SecurityGroup
          SubnetIds: 
            Ref: Subnets
          VpcEndpointType: Interface
          VpcId: 
            Ref: VPC
    
      EndpointECR:
        Type: AWS::EC2::VPCEndpoint
        Condition: CreationVCPEndpointSelected
        Properties:
          ServiceName: !Join
            - ''
            - - com.amazonaws.
              - !Ref 'AWS::Region'
              - .ecr.api
          PrivateDnsEnabled: true
          SecurityGroupIds: 
            - !Ref SecurityGroup
          SubnetIds: 
            Ref: Subnets
          VpcEndpointType: Interface
          VpcId: 
            Ref: VPC
    
      EndpointSSM:
        Type: AWS::EC2::VPCEndpoint
        Condition: CreationVCPEndpointSelected
        Properties:
          ServiceName: !Join
            - ''
            - - com.amazonaws.
              - !Ref 'AWS::Region'
              - .ssm
          PrivateDnsEnabled: true
          SecurityGroupIds: 
            - !Ref SecurityGroup
          SubnetIds: 
            Ref: Subnets
          VpcEndpointType: Interface
          VpcId: 
            Ref: VPC
    
      EndpointDKR:
        Type: AWS::EC2::VPCEndpoint
        Condition: CreationVCPEndpointSelected
        Properties:
          ServiceName: !Join
            - ''
            - - com.amazonaws.
              - !Ref 'AWS::Region'
              - .ecr.dkr
          PrivateDnsEnabled: true
          SecurityGroupIds: 
            - !Ref SecurityGroup
          SubnetIds: 
            Ref: Subnets
          VpcEndpointType: Interface
          VpcId: 
            Ref: VPC
    
    # Criação do NLB Privado
    
      LoadBalancer:
        Type: AWS::ElasticLoadBalancingV2::LoadBalancer
        Properties:
          Name: !Ref Name
          Subnets: !Ref Subnets
          Type: network
          Scheme: internal
          Tags:
            - Key: Name
              Value: !Ref Name
    
      LoadBalancerListener:
        Type: AWS::ElasticLoadBalancingV2::Listener
        Properties:
          LoadBalancerArn: !Ref LoadBalancer
          Port: 80
          Protocol: TCP
          DefaultActions:
            - Type: forward
              TargetGroupArn: !Ref TargetGroup
    
      TargetGroup:
        Type: AWS::ElasticLoadBalancingV2::TargetGroup
        Properties:
          Name: !Sub ${Name}-tg
          VpcId: !Ref VPC
          Port: 80
          Protocol: TCP
          TargetType: ip
    
    # Criação da IAM para o ECS
    
      ECSIAM:
        Type: AWS::IAM::Role
        Properties:
          AssumeRolePolicyDocument:
            Version: "2012-10-17"
            Statement:
              -
                Effect: "Allow"
                Principal:
                  Service:
                    - "ecs.amazonaws.com"
                    - "ecs-tasks.amazonaws.com"
                Action:
                  - "sts:AssumeRole"
          Path: "/"
          Policies:
            -
              PolicyName: !Ref Name
              PolicyDocument:
                Version: "2012-10-17"
                Statement:
                  -
                    Effect: "Allow"
                    Action: "*"
                    Resource: "*"
    
    # Criação do ECS Fargate
    
      ECSCluster:
        Type: AWS::ECS::Cluster
        Properties:
          ClusterName: !Ref Name
    
      ECSService:
        Type: AWS::ECS::Service
        DependsOn: LoadBalancerListener
        Properties:
          Cluster: !Ref ECSCluster
          LaunchType: FARGATE
          DesiredCount: !Ref DesiredCount
          TaskDefinition: !Ref ECSTaskDefinition
          NetworkConfiguration:
            AwsvpcConfiguration:
              AssignPublicIp: ENABLED
              SecurityGroups:
                - sg-0c2e8f8e84a22bdd4
              Subnets:
                - subnet-04d79b3e4ac16ba6f
                - subnet-07baab102179ee184
          LoadBalancers:
            - ContainerName: "test-container"
              ContainerPort: 80
              TargetGroupArn: !Ref TargetGroup
    
      ECSTaskDefinition:
        Type: AWS::ECS::TaskDefinition
        Properties:
          Family: test-container
          NetworkMode: awsvpc
          Cpu: 512
          Memory: 1024
          ExecutionRoleArn: !Ref ECSIAM
          RequiresCompatibilities:
            - FARGATE
          ContainerDefinitions:
            - Name: test-container
              Essential: true
              Image: URI
              Cpu: 512
              Memory: 1024
              PortMappings:
                - ContainerPort: 80