Your first policy

Now that you’re connected, this tutorial walks through the core object interface — reading and writing PCE objects — and finishes by creating and provisioning policy. For end-to-end segmentation examples, see the security policy guide.

API Endpoints

PCE API CRUD endpoints are registered as attributes in PolicyComputeEngine, represented by instances of the internal _PCEObjectAPI class.

Each one implements a standard interface to manage objects in the PCE. The full list can be found in the API documentation.

>>> from illumio import IPList, IPRange, FQDN
>>> ip_lists = pce.ip_lists.get(params={'max_results': 5})
>>> ip_lists
[
    IPList(href='/orgs/1/sec_policy/draft/ip_lists/1', ...),
    ...
]
>>> new_ip_list = pce.ip_lists.create(
...     IPList(
...         name='IPL-Private',
...         ip_ranges=[
...             IPRange(from_ip='127.0.0.1'),
...             IPRange(from_ip='172.16.0.0', to_ip='172.31.255.255'),
...             IPRange(from_ip='192.168.0.0/16')
...         ]
...     )
... )
>>> new_ip_list
IPList(href='/orgs/1/sec_policy/draft/ip_lists/12', ...)
>>> pce.ip_lists.update(new_ip_list, {'fqdns': [FQDN(fqdn='localhost')]})
>>> updated_ip_list = pce.ip_lists.get_by_reference(new_ip_list.href)
>>> updated_ip_list
IPList(href='/orgs/1/sec_policy/draft/ip_lists/12', fqdns=[FQDN(fqdn='localhost')], ...)
>>> pce.ip_lists.delete(new_ip_list)

In addition to the CRUD operations shown above, the _PCEObjectAPI class also provides functions for asynchronous and batch operations - see the Reading large collections guide for details.

Note

HTTP requests The illumio library uses requests under the hood to communicate with the PCE. The various request functions accept the same keyword arguments as their requests counterparts, allowing query parameters, headers, body data, cookies, certificates, and other HTTP features to be specified. See the requests documentation for the full specification.

References

PCE objects use an HREF as a unique identifier. The HREF is typically made up of the organization reference and object path:

/orgs/1/labels/1

This HREF is used to GET individual objects and in request/response bodies to reference dependent or nested objects.

Where references are required, the illumio library generally accepts HREF string literals, dictionaries containing an href key, or a Reference object. The Reference class is a base type extended by most PCE objects.

HREF string

>>> label = pce.labels.get_by_reference('/orgs/1/labels/1')
>>> label
Label(href='/orgs/1/labels/1', ...)

Dictionary

>>> label = pce.labels.get_by_reference({'href': '/orgs/1/labels/1'})
>>> label
Label(href='/orgs/1/labels/1', ...)

Reference object

>>> import illumio
>>> label_ref = illumio.Reference(href='/orgs/1/labels/1')
>>> label = pce.labels.get_by_reference(label_ref)
>>> label
Label(href='/orgs/1/labels/1', ...)

API Responses

The convenience functions in _PCEObjectAPI wrap the JSON responses from the PCE and return python objects of the expected type. While these should be sufficient for most use-cases, the underlying get, post, put, delete, and get_collection functions are exposed for unimplemented or custom PCE requests:

>>> pce.set_credentials('first.last@company.com', 'keepmesecret')
>>> resp = pce.post('/users/1/api_keys', json={'name': 'ILLUMIO_PY'}, include_org=False)
>>> api_key_response = resp.json()
>>> api_key_response
{'key_id': '11ce8a65cde969f8f', 'auth_username': 'api_11ce8a65cde969f8f', 'secret': '...'}
>>> pce.set_credentials(api_key_response['auth_username'], api_key_response['secret'])

These functions return the requests.Response object directly. For supported objects, the JSON response can be converted to its Python equivalent using from_json:

>>> from illumio import Service
>>> resp = pce.get('/sec_policy/active/services/1')
>>> service = Service.from_json(resp.json())
>>> service
Service(href='/orgs/1/sec_policy/active/services/1', name='All Services', ...)

Working with Policy Objects

Segmenting your network using the PCE is achieved through security policy defined using policy objects.

Security Rules, scoped within Rule Sets, provide a flexible way to define allow-list policies for your workloads. IP Lists and Services provide abstraction and grouping for ingress and egress. Labels and Label Groups categorize workloads, defining policy scope in an extensible and human-readable way.

Representing Application Boundaries with Labels

The Illumio Policy Compute Engine provides four label dimensions: Role, Application, Environment, and Location. Using these, we can create logical boundaries for workloads within which to define policy rules.

Let’s take a look at an example.

>>> from illumio import Label
>>> role_label = pce.labels.create(Label(key='role', value='R-NTP'))
>>> app_label = pce.labels.create(Label(key='app', value='A-CoreServices'))
>>> env_label = pce.labels.create(Label(key='env', value='E-Prod'))
>>> loc_label = pce.labels.create(Label(key='loc', value='L-AWS'))
>>> ntp_server = pce.workloads.create(
...     Workload(
...         name='Internal NTP',
...         hostname='ntp0.lab.company.com',
...         public_ip='10.8.0.17',
...         labels= [role_label, app_label, env_label, loc_label]
...     )
... )
>>> ntp_server
Workload(
    href='/orgs/1/workloads/644418c6-fdf7-4008-87d7-d023019a6f0d',
    name='Internal NTP',
    ...
)

Based on these labels, it’s clear that this unmanaged workload represents an NTP server in our Production Core Services application running in AWS.

Check out the nano-segmentation use-case for a more detailed example of how labels can be used to simplify policy definition for complex applications, or further explore how labels can be applied to workloads in the workload labelling use-case.

Policy Provisioning

Objects in the PCE that directly affect your network’s security policy – such as Rules, IP Lists, Enforcement Boundaries, and Virtual Services – are initially created in a draft state. Changes to these objects will show up in Illumination’s Draft view so that their impact can be reviewed before being applied.

The GET functions in _PCEObjectAPI provide a policy_version parameter to specify whether draft or active state objects should be returned from the PCE.

Note

By default, these functions return draft objects as all PCE objects have a draft representation that may or may not be the same as its active version. Any operations that modify the object must be performed on the draft version, then provisioned.

To apply policy in draft state, we have to provision the change to create or update the active version of impacted policy objects.

>>> from illumio import LabelGroup
>>> env_labels = pce.labels.get(params={'key': 'env', 'max_results': 10})
>>> preprod_envs = ['Test', 'Staging', 'Development']
>>> preprod_labels = [label for label in env_labels if label.value in preprod_envs]
>>> label_group = pce.label_groups.create(
...     LabelGroup(
...         name='LG-E-PreProd',
...         key='env',
...         labels=preprod_labels
...     )
... )
>>> label_group
LabelGroup(
    href='/orgs/1/sec_policy/draft/label_groups/c6a57d39-ccfa-4454-ad2e-7255b5a777ba',
    name='LG-E-PreProd',
    ...
)
>>> policy_version = pce.provision_policy_changes(
...     change_description="Create pre-production environments label group",
...     hrefs=[label_group.href]
... )
>>> policy_version
PolicyVersion(
    href='/orgs/1/sec_policy/38',
    commit_message='Create pre-production environments label group',
    ...
)

Note

Objects in draft state that haven’t been provisioned do not have active representations, and DELETE requests on them will remove the object without needing a provision request.