AppMesh and ECS with Imported ACM certificates on Envoy Sidecar by way of EFS


Abstract

This information showcases the power to make use of imported certificates from a 3rd celebration supplier (e.g. Venafi) in ACM, mount them in EFS and use them as trusted sources on Envoy sidecars with purposes operating in ECS. AppMesh is used as a passthrough with TLS termination occurring on the applying container layer.

Conditions and limitations

Conditions

A certificates that incorporates the chain of domains required for the fronted service and micro-services wanted.

What we are going to produce:

  • ACM containing an Imported Certificates.
  • EFS quantity.
  • Route53 report.
  • Community Load Balancer, with related Goal Group.
  • ECS cluster, with Duties managed by a Service. A Job Definition to compound the mapping standards.
  • AppMesh Digital Gateway, Digital Service and Digital Node pointing again to the ECS job containers.
  • CloudMap to combine ECS and AppMesh configurations with automation.
  • Bastion host used for testing functions.

Structure

Goal know-how stack

ACM, EFS, Route53, NLB, TG, ECS, AppMesh, CloudMap

Goal structure

N/A

Finest practices

ACM – Certificates Supervisor

Certificates are imported from Venafi (third celebration supplier):

Drilling into this info, the domains listed include ample subdomains to handle the micro-services oriented structure.

EFS

AppMesh doesn’t assist ACM PCM Certificates instantly, so they’re loaded onto an EFS quantity that shall be mounted on the Envoy sidecar containers.

Route53

A hosted zone is setup in Route53 to have the ability to route visitors from our main area to a Community Load Balancer.

LoadBalancer

This Community Load Balancer is setup as inner to permit for managed inner visitors solely.

There’s a single listener open on port 443:

Goal Group

The Goal Group routes visitors to the applying port on two ECS duties behind our ECS service.

The well being examine confirms entry on the outlined visitors port, which is the applying container port for ECS.

ECS

Every service fronts it’s personal microservice utility, which consists of an utility container and an envoy sidecar.

The service incorporates a number of duties to distribute load.

A number of containers reside inside every job definition.

Community bindings are setup to permit visitors by way of the applying ports that had been setup beforehand within the goal teams.

Establishing Envoy to have the ability to validate the certificates for utility TLS termination is vital. To do that, an envoy job definition could look one thing like this:

{
    "taskDefinitionArn": "arn:aws:ecs:af-south-1:xxxxxx:task-definition/envoy-task:12",
    "containerDefinitions": [
        {
            "name": "envoy",
            "image": "xxxxx.dkr.ecr.af-south-1.amazonaws.com/aws-appmesh-envoy:v1.22.2.1-prod",
            "cpu": 0,
            "memory": 500,
            "portMappings": [
                {
                    "containerPort": 8443,
                    "hostPort": 8443,
                    "protocol": "tcp"
                },
                {
                    "containerPort": 8080,
                    "hostPort": 8080,
                    "protocol": "tcp"
                },
                {
                    "containerPort": 9901,
                    "hostPort": 9901,
                    "protocol": "tcp"
                }
            ],
            "important": true,
            "setting": [
                {
                    "name": "APPMESH_VIRTUAL_NODE_NAME",
                    "value": "mesh/VAX/virtualGateway/om-xxx-vgw"
                },
                {
                    "name": "ENVOY_LOG_LEVEL",
                    "value": "debug"
                }
            ],
            "mountPoints": [
                {
                    "sourceVolume": "cert-vol",
                    "containerPath": "/certs",
                    "readOnly": true
                }
            ],
            "volumesFrom": [],
            "consumer": "1337",
            "logConfiguration": {
                "logDriver": "awslogs",
                "choices": {
                    "awslogs-group": "/ecs/envoy-task",
                    "awslogs-region": "af-south-1",
                    "awslogs-stream-prefix": "ecs"
                }
            },
            "healthCheck":  grep -q LIVE"
                ],
                "interval": 5,
                "timeout": 2,
                "retries": 3,
                "startPeriod": 60
            
        }
    ],
    "household": "envoy-task",
    "taskRoleArn": "arn:aws:iam::xxxxxx:function/Bounded-AmazonECSTaskExecutionRole",
    "executionRoleArn": "arn:aws:iam::xxxxxx:function/Bounded-AmazonECSTaskExecutionRole",
    "networkMode": "awsvpc",
    "revision": 12,
    "volumes": [
        {
            "name": "cert-vol",
            "efsVolumeConfiguration": {
                "fileSystemId": "fs-01c20c20xxxxd3",
                "rootDirectory": "/",
                "transitEncryption": "ENABLED",
                "authorizationConfig": {
                    "accessPointId": "fsap-06a57e7xxx1d439",
                    "iam": "DISABLED"
                }
            }
        }
    ],
    "standing": "ACTIVE",
    "requiresAttributes": [
        {"name": "ecs.capability.execution-role-awslogs"},
        {"name": "com.amazonaws.ecs.capability.ecr-auth"},
        {"name": "com.amazonaws.ecs.capability.docker-remote-api.1.17"},
        {"name": "com.amazonaws.ecs.capability.task-iam-role"},
        {"name": "ecs.capability.container-health-check"},
        {"name": "ecs.capability.execution-role-ecr-pull"},
        {"name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"},
        {"name": "ecs.capability.task-eni"},
        {"name": "com.amazonaws.ecs.capability.docker-remote-api.1.29"},
        {"name": "com.amazonaws.ecs.capability.logging-driver.awslogs"},
        {"name": "ecs.capability.efsAuth"},
        {"name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"},
        {"name": "ecs.capability.efs"},
        {"name": "com.amazonaws.ecs.capability.docker-remote-api.1.25"}
    ],
    "placementConstraints": [],
    "compatibilities": [
        "EC2",
        "FARGATE"
    ],
    "requiresCompatibilities": [
        "FARGATE"
    ],
    "cpu": "1024",
    "reminiscence": "2048",
    "runtimePlatform": {
        "operatingSystemFamily": "LINUX"
    },
    "registeredAt": "20xx-08-31T12:01:xx.525Z",
    "registeredBy": "arn:aws:sts::xxxx:assumed-role/XXXUsrRole/[email protected]",
    "tags": []
}

AppMesh

There’s a single Mesh outlined.

Mesh

On this setup, we make use of Digital Gateways, Digital Providers and Digital Nodes to route again to operating ECS companies.

Digital Gateway

A single digital gateway is provisioned.

The configuration of which mounts the EFS quantity’s certificates chain, and acts as a passthrough, or permissive visitors stream.

om-vas-vgw

meshName: VAS
virtualGatewayName: om-vas-vgw
spec:
  backendDefaults:
    clientPolicy: {}
  listeners:
    - portMapping:
        port: 8443
        protocol: http
      tls:
        certificates:
          file:
            certificateChain: /certs/vas-api-service.instance.com.crt
            privateKey: /certs/new.key
        mode: PERMISSIVE
    - portMapping:
        port: 8080
        protocol: http
  logging:
    accessLog:
      file:
        path: /dev/std

Listeners:
Listeners of which, are setup for each TLS and non-TLS, fully for testing functions throughout improvement phases solely.

Gateway Routes

A gateway route is setup to route http sort visitors by way of to a digital service outlined under.

vas-api-service-route:

meshName: VAS
virtualGatewayName: om-vas-vgw
gatewayRouteName: vas-api-service-route
spec:
  httpRoute:
    motion:
      rewrite:
        hostname:
          defaultTargetHostname: DISABLED
        prefix:
          defaultPrefix: ENABLED
      goal:
        virtualService:
          virtualServiceName: om-vas-api-vsvc
    match:
      port: 8443
      prefix: /

The digital service is attached to a digital node by way of the under configuration.
om-vas-api-vsv:

meshName: VAS
virtualServiceName: om-vas-api-vsvc
spec:
  supplier:
    virtualNode:
      virtualNodeName: om-vas-api-server-vnode

Digital Node:

The digital node permits visitors to go by way of to the applying port on 34559 as proven under.

meshName: VAS
virtualNodeName: om-vas-api-server-vnode
spec:
  backendDefaults:
    clientPolicy:
      tls:
        implement: false
        ports: []
        validation:
          belief:
            file:
              certificateChain: /certs/vas-api-service.instance.com.crt
  backends: []
  listeners:
    - healthCheck:
        healthyThreshold: 3
        intervalMillis: 10000
        path: /
        port: 34559
        protocol: tcp
        timeoutMillis: 5000
        unhealthyThreshold: 2
      portMapping:
        port: 34559
        protocol: tcp
  logging: {}
  serviceDiscovery:
    awsCloudMap:
      attributes: []
      namespaceName: instance.com
      serviceName: vas-api-service

Digital Node Listeners:

A visible illustration is as follows:

CloudMap

CloudMap gives service discovery for our assets, we begin with a namespace which can be utilized for API calls and DNS queries throughout the VPC.
We’ve got created a namespace to deal with our collective assets.

Right here we are able to see the Service Cases that ECS duties are reporting again to us.

If we have a look at considered one of them, we are able to see the knowledge that can inform AppMesh:

Confirming visitors stream

Operating the next connection checks by way of a Bastion permits us to remain throughout the identical inner community for all checks.

Now we set off the service instantly on ECS to see the certificates is accepted:

sh-4.4$ curl -I https://vas-api-service.instance.com:34559/swagger-ui/
HTTP/1.1 200 OK
Final-Modified: Wed, 20 Jul 2022 13:15:06 GMT
Content material-Size: 3129
Settle for-Ranges: bytes
Content material-Kind: textual content/html

Then we are able to check that the precise entrance service by way of the chain beginning with Route53 connects efficiently:

sh-4.4$ curl -I https://vas.instance.com/swagger-ui/
HTTP/1.1 200 OK
Final-Modified: Wed, 20 Jul 2022 13:15:06 GMT
Content material-Size: 3129
Settle for-Ranges: bytes
Content material-Kind: textual content/html

Lastly we make it possible for the connection instantly from the load balancer doesn’t permit ingress:

sh-4.4$ curl -I https://om-vas-service-nlb-be13b4dccxxxxxx.elb.af-south-1.amazonaws.com/swagger-ui/
curl: (51) SSL: no different certificates topic identify matches goal host identify 'om-vas-service-nlb-be13b4dccxxxxx.elb.af-south-1.amazonaws.com'
sh-4.4$

Leave a Reply