aws / copilot-cli

The AWS Copilot CLI is a tool for developers to build, release and operate production ready containerized applications on AWS App Runner or Amazon ECS on AWS Fargate.
https://aws.github.io/copilot-cli/
Apache License 2.0
3.51k stars 414 forks source link

Create an internal Network load balancer with AWS Copilot #5131

Open ShanikaEdiriweera opened 1 year ago

ShanikaEdiriweera commented 1 year ago

I am trying to deploy bitnami/openldap container in ECS using AWS Copilot as a backend service with a internal NLB (Couldn't go with ALB since bitnami/openldap does not have a http healthcheck endpoint).

I have the following config in Copilot service manifest.

name: ldap2023
type: Backend Service

nlb:
  port: 1389/tcp
  healthcheck:
    healthy_threshold: 3
    unhealthy_threshold: 10
    grace_period: 120s
    interval: 15s
    timeout: 10s

network:
  vpc:
    placement: private

But when I deploy the service a NLB is not created. R53 dns record is directly pointing to the ECS task ip.

Is it not possible to use NLB with backend service?

Can't find it in docs but it is not mentioned that it is not possible as well. For Load balanced web service it has examples for both ALB and NLB!

bencehornak-gls commented 1 year ago

@ShanikaEdiriweera I think you should use a Load Balanced Service, not a Backend Service with an nlb config:

# copilot/<service>/manifest.yml
name: <service name>
type: Load Balanced Web Service
nlb:
  port: 80/tcp

Unfortunately, this will create a public NLB, AFAIK there is no official way to set it to internal.

Having said that, as a workaround you can create a YAML patch to fix this:

# copilot/<service>/overrides/cfn.patches.yml
# Change the NLB to internal
- op: replace
  path: /Resources/PublicNetworkLoadBalancer/Properties/Scheme
  value: internal
# Add a Name to the NLB (otherwise the automatically generated name will contain 'public', which is confusing)
- op: add
  path: /Resources/PublicNetworkLoadBalancer/Properties/Name
  value: !Sub "${AppName}-${EnvName}-${WorkloadName}-NLB"
jhtann commented 2 months ago

hello! any idea how to enable access logs on this NLB resource? I tried to add the below in the environment manifest but not working. The output is s3 bucket created but not associated with NLB.

environment

http:
  public:
    access_logs: true

output

+ Mappings:
+     RegionalConfigs:
+         us-east-1:
+             ElbAccountId: '127311923021'
+         us-east-2:
+             ElbAccountId: '033677994240'
+         us-west-1:
+             ElbAccountId: '027434742980'
+         us-west-2:
+             ElbAccountId: '797873946194'
+         af-south-1:
+             ElbAccountId: '098369216593'
+         ca-central-1:
+             ElbAccountId: '985666609251'
+         eu-central-1:
+             ElbAccountId: '054676820928'
+         eu-west-1:
+             ElbAccountId: '156460612806'
+         eu-west-2:
+             ElbAccountId: '652711504416'
+         eu-south-1:
+             ElbAccountId: '635631232127'
+         eu-west-3:
+             ElbAccountId: '009996457667'
+         eu-north-1:
+             ElbAccountId: '897822967062'
+         ap-east-1:
+             ElbAccountId: '754344448648'
+         ap-northeast-1:
+             ElbAccountId: '582318560864'
+         ap-northeast-2:
+             ElbAccountId: '600734575887'
+         ap-northeast-3:
+             ElbAccountId: '383597477331'
+         ap-southeast-1:
+             ElbAccountId: '114774131450'
+         ap-southeast-2:
+             ElbAccountId: '783225319266'
+         ap-southeast-3:
+             ElbAccountId: '589379963580'
+         ap-south-1:
+             ElbAccountId: '718504428378'
+         me-south-1:
+             ElbAccountId: '076674570225'
+         sa-east-1:
+             ElbAccountId: '507241528517'
+         us-gov-west-1:
+             ElbAccountId: '048591011584'
+         us-gov-east-1:
+             ElbAccountId: '190560391635'
+         cn-north-1:
+             ElbAccountId: '638102146993'
+         cn-northwest-1:
+             ElbAccountId: '037604701340'
~ Resources:
    + ELBAccessLogsBucket:
    +     Metadata:
    +         "aws:copilot:description": "A S3 bucket for the Load Balancer's access logs"
    +     Type: AWS::S3::Bucket
    +     Properties:
    +         VersioningConfiguration:
    +             Status: Enabled
    +         BucketEncryption:
    +             ServerSideEncryptionConfiguration:
    +                 - ServerSideEncryptionByDefault:
    +                     SSEAlgorithm: AES256
    +         PublicAccessBlockConfiguration:
    +             BlockPublicAcls: true
    +             BlockPublicPolicy: true
    +             IgnorePublicAcls: true
    +             RestrictPublicBuckets: true
    + ELBAccessLogsBucketPolicy:
    +     Type: AWS::S3::BucketPolicy
    +     Condition: CreateALB
    +     DependsOn: ELBAccessLogsBucket
    +     Properties:
    +         Bucket: !Ref ELBAccessLogsBucket
    +         PolicyDocument:
    +             Version: '2012-10-17'
    +             Statement:
    +                 - Action:
    +                     - s3:PutObject
    +                   Effect: Allow
    +                   Resource:
    +                     - !Join
    +                       - ''
    +                       - - 'arn:'
    +                         - !Ref AWS::Partition
    +                         - ':s3:::'
    +                         - !Ref ELBAccessLogsBucket
    +                         - '/AWSLogs/'
    +                         - !Ref AWS::AccountId
    +                         - '/*'
    +                   Principal:
    +                     AWS: !Join ["", [!Sub 'arn:${AWS::Partition}:iam::', !FindInMap [RegionalConfigs, !Ref 'AWS::Region', ElbAccountId], ":root"]]
    ~ EnvironmentManagerRole/Properties/Policies:
        ~ - (changed item)
          ~ PolicyDocument/Statement:
              (13 unchanged items)
              + - Sid: EmptyELBAccessLogsBucket
              +   Effect: Allow
              +   Action:
              +     - s3:EmptyBucket
              +   Resource: !Join ["/", [!GetAtt ELBAccessLogsBucket.Arn, "*"]]
              (8 unchanged items)
    ~ PublicLoadBalancer:
        + DependsOn: ELBAccessLogsBucketPolicy
        ~ Properties:
            + LoadBalancerAttributes:
            +     - Key: 'access_logs.s3.enabled'
            +       Value: true
            +     - Key: 'access_logs.s3.bucket'
            +       Value: !Ref ELBAccessLogsBucket

the logical name for NLB load balancer is PublicNetworkLoadBalancer in cloudformation service stack, thus cannot find?

Lou1415926 commented 2 months ago

Hi @jhtann! http.public.access_logs only enables the access log on the public load balancer, not the network load balancer. I suggest you try using addons for the service that has the nlb to manage the access log for the nlb. This would mean that you will need to write a chunk of CloudFormation template for the access log, but you can always refer to how we write it for the public load balancer to aid you!