Administering Dynamic Egress Policies (Beta)

Page last updated:

Note: This is a beta feature.

This topic describes how to administer dynamic egress policies for the apps in your deployment.

Overview

You can create dynamic egress policies to allow your apps to communicate with external services, such as a MySQL database. The workflow is as follows:

  • Create a destination object with details about the external service that your app or space need access to, including an IP range.
  • Create an egress policy from the app or space to the destination object.

Dynamic egress policies provide the following benefits over App Security Groups (ASGs):

  • You do not have to restart your apps when applying these policies, so there is no downtime.
  • The policies include an additional level of granularity: you can apply them to specific apps.

For more information about ASGs, see App Security Groups.

Enable the Dynamic Egress Feature

The dynamic egress feature is disabled by default. To enable this feature, you must set the enforce_experimental_dynamic_egress_policies property of the policy-server-internal job to true. For more information, see the spec file in the CF Networking Release repository.

Note: This feature is only compatible with the Silk CNI plugin.

API Authorization

To administer dynamic egress policies, you must have the network.admin UAA scope. If you are a CF admin, you already have the network.admin scope. An admin can also grant the network.admin scope to a space developer. For more information, see Creating and Managing Users with the UAA CLI (UAAC) and Orgs, Spaces, Roles, and Permissions.

If you have the network.admin scope, you can interact with the API in the following ways:

Option 1: cf curl

When you use cf curl, you do not have to provide a token or the full API URL because you are already logged in and targeting your deployment. See the following example:

$ cf curl /networking/v1/external/egress_policies
{"total_egress_policies":2,"egress_policies":[{"source":{...}]}

Option 2: curl

When using curl, you must provide the token Authorization header and use the full API URL. See the following example:

$ export TOKEN=`cf oauth-token` # as CF admin
$ curl http://api.bosh-lite.com/networking/v1/external/egress_policies -H "Authorization: $TOKEN"
{"total_egress_policies":2,"egress_policies":[{"source":{...}]}

Typical Workflows

Dynamic egress policies depend on a destination object. See the following workflow examples:

Add an Egress Policy

To create a policy, you must first create a destination. To create a destination:

  1. Create an egress destination. For more information, see Create Egress Destinations.

  2. Create an egress policy linking the destination and an app or space. For more information, see Create Egress Policies.

  3. The policy is applied. You do not need to restart any apps.

Update an Egress Policy When an IP Changes

To update a policy, you update the destination. To update the destination of a policy:

  1. List all egress destinations to find the one you want to change. For more information, see List Egress Destinations.

  2. Update the egress destination. For more information, see Update Egress Destinations.

  3. The updated policy is applied. You do not need to restart any apps.

Egress Destination API

Method Path Description
GET /networking/v1/external/destinations List Destinations
POST /networking/v1/external/destinations Create Destinations
PUT /networking/v1/external/destinations Update Destinations
DELETE /networking/v1/external/destinations/GUID Delete Destinations

List Egress Destinations

GET /networking/v1/external/destinations

Arguments:

  • (Optional) id: comma-separated ID values. This cannot be used with name.
  • (Optional) name: comma-separated name values. This cannot be used with id.

Response Body:

This endpoint returns all egress destinations.

{
  "total_destinations": 2,
  "destinations": [
   {
      "name": "oracle database",
      "id": "90be9c1f-b694-4463-9f1f-6ce71904440d",
      "description": "db for user accounts",
      "ips": [{"start":"1.9.9.9", "end": "1.9.9.20"}],
      "ports": [{"start": 8000, "end": 9000}],
      "protocol": "tcp"
   },
   {
      "name": "AWS",
      "id": "72813418-bd38-49e0-ace0-7bf5b7c54687",
      "ips": [{"start":"1.8.8.8", "end": "1.8.8.8"}],
      "ports": [{"start": 8000, "end": 9000}],
      "protocol": "udp"
   }
  ]
}

Create Egress Destinations

POST /networking/v1/external/destinations

Request Body:

{
  "destinations": [
   {
      "name": "oracle database",
      "description": "db for user accounts",
      "ips": [{"start":"1.9.9.9", "end": "1.9.9.20"}],
      "ports": [{"start": 8000, "end": 9000}],
      "protocol": "tcp"
   },
   {
      "name": "AWS",
      "ips": [{"start":"1.8.8.8", "end": "1.8.8.8"}],
      "ports": [{"start": 8000, "end": 9000}],
      "protocol": "udp"
   }
  ]
}

Parameters

Field Required? Description
destinations.name Yes The name of the destination. Must be globally unique.
destinations.description No A description of the destination.
destinations.ips.start* Yes The start of the destination IP range. Must be IPv4.
destinations.ips.end* Yes The end of the destination IP range. Must be IPv4. May be equal to the the start IP.
destinations.ports.start* Yes The destination start port (1 - 65535). Ports are not applicable for ICMP protocol.
destinations.ports.end* Yes The destination end port (1 - 65535). Ports are not applicable for ICMP protocol.
destinations.protocol Yes The protocol (tcp, udp, or icmp).
destinations.icmp_type No The ICMP type to allow when using the ICMP protocol. Default is all ICMP types, represented by -1.
destinations.icmp_code No The ICMP code to allow when using the ICMP protocol. Default is all ICMP codes, represented by -1.

*Currently, only one IP range and one port range are supported.

Update Egress Destinations

PUT /networking/v1/external/destinations

Request Body:

{
  "destinations": [
   {
      "id": "90be9c1f-b694-4463-9f1f-6ce71904440d",
      "name": "oracle database",
      "description": "db for user accounts",
      "ips": [{"start":"1.9.9.9", "end": "1.9.9.20"}],
      "ports": [{"start": 8000, "end": 9000}],
      "protocol": "tcp"
   },
   {
      "id": "72813418-bd38-49e0-ace0-7bf5b7c54687",
      "name": "AWS",
      "ips": [{"start":"1.8.8.8", "end": "1.8.8.8"}],
      "ports": [{"start": 8000, "end": 9000}],
      "protocol": "udp"
   }
  ]
}

Parameters

Field Required? Description
destinations.id Yes The ID of the destination. This ID is returned in the destinations create response, as well as in the destinations index response.
destinations.name Yes The name of the destination. Must be globally unique.
destinations.description No A description of the destination.
destinations.ips.start* Yes The start of the destination IP range. Must be IPv4.
destinations.ips.end* Yes The end of the destination IP range. Must be IPv4. May be equal to the the start IP.
destinations.ports.start* Yes The destination start port (1 - 65535). Ports are not applicable for ICMP protocol.
destinations.ports.end* Yes The destination end port (1 - 65535). Ports are not applicable for ICMP protocol.
destinations.protocol Yes The protocol (tcp, udp, or icmp).
destinations.icmp_type No The ICMP type to allow when using the ICMP protocol. Default is all ICMP types, represented by -1.
destinations.icmp_code No The ICMP code to allow when using the ICMP protocol. Default is all ICMP codes, represented by -1.

*Currently, only one IP range and one port range are supported.

Delete an Egress Destination

DELETE /networking/v1/external/destinations/GUID

Response Body:

This endpoint returns the JSON of the deleted destination object.

{
  "total_destinations": 1,
  "destinations": [
   {
      "name": "oracle database",
      "id": "90be9c1f-b694-4463-9f1f-6ce71904440d",
      "description": "db for user accounts",
      "ips": [{"start":"1.9.9.9", "end": "1.9.9.20"}],
      "ports": [{"start": 8000, "end": 9000}],
      "protocol": "tcp"
   }
  ]
}

Egress Policy API

Method Path Description
GET /networking/v1/external/egress_policies List Egress Policies
POST /networking/v1/external/egress_policies Create EgressPolicies
DELETE /networking/v1/external/egress_policies/GUID Delete Egress Policy

List Egress Policies

GET /networking/v1/external/egress_policies

Arguments:

None

Response Body:

This endpoint returns all egress policies.

{
  "total_egress_policies": 1,
  "egress_policies": [{
    "id": "dynamic-egress-guid",
    "source": {
      "type": "app",
      "id": "SOURCE-APP-GUID"
     },
     "destination": {
        "id": "guid-abc-123",
        "name": "AWS",
        "description": "AWS",
        "id": "72813418-bd38-49e0-ace0-7bf5b7c54687",
        "ips": [{"start":"1.8.8.8", "end": "1.8.8.8"}],
        "ports": [{"start": 8000, "end": 9000}],
        "protocol": "udp"
     }
   }]
}

Create Egress Policies

POST /networking/v1/external/egress_policies

Request Body:

{
  "egress_policies": [{
    "source": {
      "type": "space",
      "id": "SOURCE-SPACE-GUID"
    },
    "destination": {
      "id": "EGRESS-DESTINATION-GUID"
    }
  }]
}

Parameters

Field Required? Description
source.type No The type of source. Must be app or space. Defaults to app.
source.id Yes The GUID of the source app or space.
destination.id Yes The GUID of the egress destination.

Delete an Egress Policy

DELETE /networking/v1/external/egress_policies/GUID

Response Body:

This endpoint returns the JSON of the deleted egress policy object.

{
  "total_egress_policies": 1,
  "egress_policies": [{
    "id": "dynamic-egress-guid",
    "source": {
      "type": "app",
      "id": "SOURCE-APP-GUID"
     },
     "destination": {
        "name": "AWS",
        "description": "AWS",
        "id": "72813418-bd38-49e0-ace0-7bf5b7c54687",
        "ips": [{"start":"1.8.8.8", "end": "1.8.8.8"}],
        "ports": [{"start": 8000, "end": 9000}],
        "protocol": "udp"
     }
   }]
}
Create a pull request or raise an issue on the source for this page in GitHub