HashiCorp Cloud Platform (HCP) is a fully managed platform offering HashiCorp Products as a Service (HPaaS) to automate infrastructure on any cloud.
This tutorial will cover the process required to connect an EKS Cluster to HCP Consul on AWS.
»Prerequisites
The following prerequisites are required:
For this tutorial, you will need to ensure your AWS CLI is logged in with your credentials, and is targeting the region where you have created your EKS cluster. Review the AWS documentation for instructions on how to configure the AWS CLI.
To enable communication between the Consul control plane and the EKS cluster, you will need to complete the process outlined in the deployment tutorial.
»Configure development host
Kubernetes stores cluster connection information in a special file called
kubeconfig
. You can retrieve the Kubernetes configuration settings for your EKS
cluster and merge them into your local kubeconfig
file by issuing the
following command. Note, you will have to change the region name and
cluster name to match your environment.
$ aws eks --region <your-region> update-kubeconfig --name <your-cluster-name>
Now, download the Consul client configuration from the HCP portal by clicking the "Download client config" button from within the portal.
Unzip the client config package and cd into the unzipped directory.
Confirm that there are both client_config.json
and ca.pem
files.
$ ls
ca.pem client_config.json
From this same screen in the HCP UI, click the "Generate token" button and
then click "Copy" from the dialog box. An global-management root token
is now in your clipboard. Set it to the CONSUL_HTTP_TOKEN
environment variable on your
development host so that you can reference it later in the tutorial.
$ export CONSUL_HTTP_TOKEN=<your-token>
»Configure Consul secrets
Consul Service on HCP is secure by default. This means that client agents will need to be configured with the gossip encryption key, the Consul CA cert, and a root ACL token. All three of these secrets will need to be stored in the Kubernetes secrets engine so that they can be referenced and retrieved during the helm chart installation.
First, set an environment variable to the desired name of your
Helm installation. This tutorial will use hcp-beta
as the name.
$ export INSTALLATION_NAME=hcp-beta
From the unzipped client config directory, create a Kubernetes secret to store the Consul CA certificate:
$ kubectl create secret generic "${INSTALLATION_NAME}-consul-ca-cert" --from-file='tls.crt=./ca.pem'
Now, create a Kubernetes secret that stores the Consul Gossip key:
$ kubectl create secret generic "${INSTALLATION_NAME}-gossip-key" --from-literal="key=$(jq -r .encrypt client_config.json)"
Finally, create a Kubernetes secret to store the bootstrap ACL token you generated from the HCP UI:
$ kubectl create secret generic "${INSTALLATION_NAME}-bootstrap-token" --from-literal="token=${CONSUL_HTTP_TOKEN}"
»Install Consul clients on EKS
This tutorial will use the official consul-helm chart to install the Consul clients to your EKS cluster.
If you have not done so already, add the HashiCorp Helm repository:
$ helm repo add hashicorp https://helm.releases.hashicorp.com
Now, extract the private server URL from the client config so that it can be set
in the Helm values file as the externalServers:hosts
entry. This value will be passed
as the retry-join option to
the Consul clients.
$ export RETRY_JOIN=$(jq -r --compact-output .retry_join client_config.json)
Next, extract the public server URL from the client config so that it can be set
the Helm values file as the k8sAuthMethodHost
entry.
$ export CONSUL_HTTP_ADDR=$(kubectl config view -o jsonpath="{.clusters[?(@.name == \"$(kubectl config current-context)\")].cluster.server}")
Next, set CONSUL_HTTP_SSL_VERIFY=false
so that you can interact with the
HTTP API server using the Consul binary from your local development host.
export CONSUL_HTTP_SSL_VERIFY=false
Finally, generate the Helm values file. Notice that this configuration sets up an ingress gateway. This will be covered in more depth later.
$ cat > config.yaml << EOF
global:
enabled: false
datacenter: $(jq -r .datacenter client_config.json)
acls:
manageSystemACLs: true
bootstrapToken:
secretName: ${INSTALLATION_NAME}-bootstrap-token
secretKey: token
gossipEncryption:
secretName: ${INSTALLATION_NAME}-gossip-key
secretKey: key
tls:
enabled: true
enableAutoEncrypt: true
caCert:
secretName: ${INSTALLATION_NAME}-consul-ca-cert
secretKey: tls.crt
externalServers:
enabled: true
hosts: ${RETRY_JOIN}
httpsPort: 443
useSystemRoots: true
k8sAuthMethodHost: ${CONSUL_HTTP_ADDR}
client:
enabled: true
join: ${RETRY_JOIN}
connectInject:
enabled: true
ingressGateways:
enabled: true
defaults:
replicas: 1
gateways:
- name: ingress-gateway
service:
type: LoadBalancer
EOF
Validate that the config file is populated correctly.
$ more config.yaml
Install the HashiCorp Consul Helm chart:
$ helm install "${INSTALLATION_NAME}" -f config.yaml hashicorp/consul
Once you have issued the helm install
command, verify the Consul pods
have been successfully deployed by issuing kubectl get pods
.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hcp-beta-consul-6kdtq 1/1 Running 0 24s
hcp-beta-consul-connect-injector-webhook-deploymenfj8pv 1/1 Running 0 24s
hcp-beta-consul-ppc25 1/1 Running 0 24s
hcp-beta-consul-sjg89 1/1 Running 0 24s
»Deploy an example workload
Now that the clients have been deployed, it is time to deploy an application workload. This tutorial will use the HashiCups demo application. Issue the following command to clone the repository to the development host.
$ git clone https://github.com/hashicorp/learn-consul-k8s-hashicups.git
Change directory into the example repository.
cd learn-consul-k8s-hashicups
The repository contains the necessary yaml files to deploy the application. Issue the following command to deploy the application to your EKS cluster.
$ kubectl apply -f app/
Example output:
service/frontend created
serviceaccount/frontend created
configmap/nginx-configmap created
deployment.apps/frontend created
service/products-api-service created
serviceaccount/products-api created
configmap/db-configmap created
deployment.apps/products-api created
service/postgres created
serviceaccount/postgres created
deployment.apps/postgres created
service/public-api created
serviceaccount/public-api created
deployment.apps/public-api created
»Register a Consul ingress gateway
In Consul, an ingress gateway is a kind of resources called a Config Entry. An ingress gateway is an endpoint that allows external traffic to reach specific resources, such as the application user interface, that are hosted within the datacenter.
Create a file named ingress-gateway.hcl
. You will use this to
register an ingress gateway with Consul. Notice the Name
value
matches the ingressGateways:gateways:name
entry in config.yaml
.
These fields must match.
$ cat > ingress-gateway.hcl << EOF
Kind = "ingress-gateway"
Name = "ingress-gateway"
Listeners = [
{
Port = 8080
Protocol = "tcp"
Services = [
{
Name = "frontend"
}
]
}
]
EOF
Now, register the config entry with Consul.
$ consul config write ingress-gateway.hcl
»Create the necessary intentions
Since HCP Consul on AWS is secure by default, the datacenter is created with a "default deny" intention in place. This means that, by default, no services can interact with each other until an operator explicitly allows them to do so by creating intentions for each inter-service operations they wish to allow.
Issue the following command to create the intentions the HashiCups application requires to run.
$ consul intention create ingress-gateway frontend && \
consul intention create frontend public-api && \
consul intention create public-api products-api && \
consul intention create products-api postgres
Example output:
Created: ingress-gateway => frontend (allow)
Created: frontend => public-api (allow)
Created: public-api => products-api (allow)
Created: products-api => postgres (allow)
»Access the HashiCups UI
With the intentions in place, all that remains is to retrieve the public URL and port of the ingress gateway. Do this by retrieving a list of services.
$ kubectl get svc
Example output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
consul-ingress-gateway ClusterIP 10.0.53.153 40.36.23.19 8080/TCP 4h43m
...TRUNCATED
Verify you have successfully deployed the application by visiting that ip/port combination in a browser tab. This validates that Consul service discovery is working, because the services are able to resolve the upstreams. This also validates that Consul service mesh is working, because the intentions that were created are allowing services to interact with one another.
»Next steps
In this tutorial, you connected Consul clients on EKS to HCP Consul and deployed a demo application. To keep learning about Consul's features, and for step-by-step examples of how to perform common Consul tasks, complete one of the following tutorials.
- Explore the Consul UI
- Review recommend practices for Consul on Kubernetes
- Deploy a metrics pipeline with Prometheus and Grafana
If you encounter any issues, please contact the HCP team at support.hashicorp.com.