Version Note: The service intentions functionality described here is available only in Consul version 1.9.0 and later.
In the Secure Service Communication with Consul Service Mesh and Envoy tutorial, you deploy services into your Consul service mesh and regulate service-to-service communication.
In this tutorial, you will setup service (L7) intentions using configuration entries and configure intentions to allow only a certain path of the application to be served.
»Prerequisites
In order to deploy and test Consul service intentions, you will need the following resources deployed in a non-production environment:
A Consul datacenter with Consul service mesh enabled. Check Secure Service-to-Service Communication for configuration guidance. In this tutorial, this will be referred to as the server node.
One node, hosting an instance of a service, called api.
One node, hosting a web service, you are going to use to route requests to the api services. The web service must be configured to consume the api service as an upstream.
[Optional] One node running as an ingress gateway.
Configuration Note: In order for the commands listed in the tutorial to work, you must set enable_central_service_config = true
in all Consul agents’ configuration in order to have the service-defaults
configuration entries automatically applied to all services in the Consul datacenter.
Default ACL policy for production: If the default_policy
for ACL is set to allow
it is necessary to create a policy that denies communication across all services with consul intention create -deny "*" "*"
to define zero trust networking. In a production environment you want to set the default_policy
to deny
so the default ACL policy will be inherited by the default intention. Read more on this in Secure Consul with Access Control Lists (ACLs) tutorial.
»Initial environment setup
The diagram below shows the minimal architecture needed to demonstrate the functionality.
NOTE: An interactive hands-on lab is 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.
Security Warning: This tutorial is not for production use. By default, the lab will install an insecure configuration of Consul.
»Service application
This tutorial uses a fake-service application that simulates a multi-tier environment and offers:
- a
/
path to provide a JSON structure representing the system response - a
/ui
path to provide a web interface - a
/health
path to be used for health-checks
»Configure service-defaults
Service intention rules which utilize permissions are restricted to destination services that define their protocol as HTTP. You can configure your service protocol as HTTP individually using a service-defaults config entry or globally using proxy-defaults.
Before being able to define intentions, you must define service-defaults for both the api and the web service.
Create a file named default-api.hcl
with the following content:
Kind = "service-defaults"
Name = "api"
Protocol = "http"
Once you have created the file, apply the configuration to Consul.
$ consul config write default-api.hcl
Example output:
Config entry written: service-defaults/api
Create a file named default-web.hcl
with the following content:
Kind = "service-defaults"
Name = "web"
Protocol = "http"
Once you have created the file, apply the configuration to Consul.
$ consul config write default-web.hcl
Example output:
Config entry written: service-defaults/web
»Configure zero-trust communication with a default intention
For this tutorial, you will define a default intention policy that denies all service communication.
Check below to ensure you have applied the desired configuration to your environment.
If you try connecting to the web service using the service mesh, you will not be able to connect.
If you have Consul ACLs enabled, the default intention policy is inherited from the default ACL policy. You can skip this step by setting a default policy that denies connections, and only enable necessary connections as shown later in the tutorial.
»Apply service intention defaults with configuration entries
Consul 1.9 introduces the ability to create service intentions as configuration entries that can be applied globally to many instances of a service or services.
To make the api service accessible from the web service, you will need to define an intention that permits communication between service web and service api.
Create a file named config-intentions-api.hcl
with the following content:
Kind = "service-intentions"
Name = "api"
Sources = [
{
Name = "web"
Action = "allow"
},
# NOTE: a default catch-all based on the default ACL policy will apply to
# unmatched connections and requests. Typically this will be DENY.
]
and apply the configuration with:
$ consul config write config-intentions-api.hcl
Example output:
Config entry written: service-intentions/api
Once the intention is created, you can verify it shows up in the Consul UI.
»Confirm service communication
Once you have configured the intention, you can try connect to the web service. If the service is accessible on the node running it, you will see the service is now healthy:
»Ingress gateways and intentions (optional)
If you need to access the service from outside the service mesh, you will need to setup an ingress gateway.
Use the following configuration file to setup an ingress gateway for the web service:
Kind = "ingress-gateway"
Name = "ingress-service"
Listeners = [
{
Port = 8080
Protocol = "http"
Services = [
{
Name = "web"
}
]
}
]
This will enable an ingress gateway that will allow access to the web service on port 8080
of the gateway node.
Configuration Info: When using an http
listener in the ingress gateway configuration, Consul will only accept requests to the ingress gateway service if the hostname matches the internal naming convention <service_name>.ingress.*
. If you need the service to be accessible using a different hostname or an IP, please refer to the ingress gateway configuration entry documentation.
»Apply service intentions
To enable external access to the web service, you will need to setup an extra intention that will permit connections between the ingress gateway service and the web service.
In this tutorial, you will setup a more fine grained configuration where you will only allow connections from the ingress gateway on the /ui
path and deny connections on the /health
path.
Create a file named config-intentions-web.hcl
with the following content:
Kind = "service-intentions"
Name = "web"
Sources = [
{
Name = "ingress-service"
Permissions = [
{
Action = "allow"
HTTP {
PathExact = "/ui"
Methods = ["GET"]
}
}
{
Action = "deny"
HTTP {
PathExact = "/health"
Methods = ["GET"]
}
}
]
},
# NOTE: a default catch-all based on the default ACL policy will apply to
# unmatched connections and requests. Typically this will be DENY.
]
and apply the configuration with:
$ consul config write config-intentions-web.hcl
Example output:
Config entry written: service-intentions/web
»Confirm service communication
You can use the intention match API to retrieve all relevant intentions for specific services.
For example, the following command retrieves all intentions that have web
as their source:
curl --silent "http://consul.service.dc1.consul:8500/v1/connect/intentions/match?by=source&name=web" | jq
{{execute}}
{
"web": [
{
"SourceNS": "default",
"SourceName": "web",
"DestinationNS": "default",
"DestinationName": "api",
"SourceType": "consul",
"Action": "allow",
"Precedence": 9,
"CreateIndex": 60,
"ModifyIndex": 61
},
{
"SourceNS": "default",
"SourceName": "*",
"DestinationNS": "default",
"DestinationName": "*",
"SourceType": "consul",
"Action": "deny",
"Precedence": 5,
"CreateIndex": 49,
"ModifyIndex": 49
}
]
}
You can also ensure that the /health
path is not permitted by using curl
:
curl web.ingress.consul:8080/health
That should output a permission error:
RBAC: access denied
Challenge: Try to change the intentions to allow access to /
path and while denying the ui
path. Once you have applied the new configuration, start a new instance of the service from outside the service mesh and see if the new application is able to connect to the web service inside the Consul service mesh.
»Next steps
By completing this tutorial you learned more advanced concepts on how to create and manage your service (L7) intentions in Consul.
You can review the full list of options for the service_intentions configuration entry in the documentation
You can learn more about the other options for traffic splitting available in Consul from our Traffic Splitting for Service Deployments tutorial.
If you want to test and configure the load balancing policies available in Consul service mesh you can complete the Load Balancing for Consul Service Mesh with Envoy tutorial.
If you want to learn more on how to deploy an ingress gateway for your Consul service mesh, you can complete the Allow External Traffic Inside Your Service Mesh With Ingress Gateways tutorial.