Virtual Event
Join us for the next HashiConf Digital October 12-15, 2020 Register for Free

Get Started with Consul Service Mesh on Kubernetes

Enforce a Zero-trust Network with Consul Service Mesh

In the previous tutorial, Secure Application with Consul Service Mesh, you deployed two services into your Consul service mesh and secured service-to-service communication with sidecar proxies. This is the first step to configure a zero-trust network and ensure that the communication between your services is automatically verified and encrypted using mutual TLS (mTLS). The second step is to ensure all connections are authorized. Before microservices, authorization was defined with firewall rules and routing tables.

Consul simplifies the definition for communication rules between services with intentions. Intentions define service-to-service communication permission by service name. Intentions are the foundation for zero-trust networking.

In this tutorial you will define high level privileges to secure network traffic using Consul intentions.


  • Kubernetes cluster with Consul service mesh. In the previous tutorial you used kubectl to deploy two services, acting as a two-tier web application into your Consul service mesh on a local Kubernetes cluster. You will be using that cluster to test the commands provided in this tutorial.

  • kubectl to interact with your Kubernetes cluster and connect to Consul containers.

NOTE: A similar, Minikube based interactive hands-on lab is also available if you do not have a Consul environment to perform the steps described in this tutorial. Click the Show Tutorial button to launch the lab experience.

»Create your first intention

The default policy for intentions is to permit all traffic. This allows all the services to communicate with each other when you first setup your Consul service mesh.

»Create the intention

The first intention you will create changes the allow-all approach where all traffic is allowed unless denied in specific rules, to a deny-all approach where all traffic is denied and only specific connections are enabled.

First, access the Consul server container using kubectl exec.

$ kubectl exec -it hashicorp-consul-server-0 /bin/sh
/ #

Once on the Consul container, you can use the consul intention create command.

$ consul intention create -deny "*" "*"
Created: * => * (deny)

»Check intentions

Once created this intention will prevent all service-to-service communication, including traffic between your two previously deployed services.

$ consul intention check web api

»Permit service communication with intentions

Once you have defined the default policy as deny all, you can authorize traffic between your two services web and api.

First, access the Consul server container using kubectl exec.

$ kubectl exec -it hashicorp-consul-server-0 /bin/sh
/ #

You can verify that the communication between web and api is now denied using the consul intention check command.

$ consul intention check web api

Create the intention using consul intention command. You will use the service names as source and destination and assign the desired permission to the communication rule you are creating.

$ consul intention create -allow web api
Created: web => api (allow)

At this point you can confirm the communication is permitted by using the same consul intention check command again.

$ consul intention check web api

»Understand the anatomy of an intention

Intentions control which services can communicate with each another and are enforced by the sidecar proxy on inbound connections. The identity of the inbound service is verified by its TLS client certificate. The sidecar proxy then checks if an intention exists that authorizes the inbound service to communicate with the destination service. If the inbound service is not authorized, the connection will be terminated.

An intention has four parts:

  • Source service. Defines the service that initiates the communication. It can be the full name of a service or * to refer to all services.
  • Destination service. Defines the service that receives the communication, this will be the upstream you configured in your service definition. It can be the full name of a service or * to refer to all services.
  • Permission. Defines whether the communication between source and destination is permitted. This can be set to either allow or deny.
  • Description. Optional component to associate a description to the intention.

»Next steps

At this point you have learned how to define traffic rules for your service mesh without the need to manually add firewall rules or use any other traffic shaping software. You learned how to create intentions using the UI and the CLI interface for Consul.

Using Consul as your service mesh solution allows you to also leverage the functionalities exposed by the sidecar proxies to obtain observability and traffic shaping for your L7 traffic. The next tutorial Observe Network Traffic with Consul Service Mesh will give you some more information on the use cases available.