# Environment selection orchestration

> Let a plugin choose which environment a server tier deploys to, instead of hardcoding it in the blueprint

---

Site [llms.txt](/llms.txt)

---

A server tier in a blueprint can hand the choice of target **Environment**, **OS Build**, and additional **Parameters** to a plugin that runs at order time. Set this on the tier's **Environment Selection Orchestration** attribute. Cloud Management Platform (CMP) then calls your plugin and provisions accordingly.

## Set it on a server tier

1. Go to **Catalog**.
1. Edit a blueprint that has a server tier.
1. Open the **Build** tab.
1. Expand the server tier.
1. Under **Environment Selection Orchestration**, add a plugin.
1. Create a plugin, or select an existing one that implements `determine_deployment_environment_and_parameters`.
1. Select **Save**.

The function receives the order's context and returns the environment to use. It can use any logic to determine the appropriate environment.

## Keyword arguments

The most common keyword arguments, and when they are available:

| Keyword | Context |
| --- | --- |
| `group` | The group this deployment order is for. |
| `profile` | The profile of the user who requested the order. |
| `blueprint` | The blueprint being deployed. |
| `server_tier` | The tier an environment is being chosen for. |
| `os_build` | The OS build set on the order for this tier. |
| `cfvs` | Custom field values for every parameter used in the order for this tier. |
| `resource` | The deployed resource created by the order, if any. |

## What to return

Always return a dictionary. CMP reads these keys:

| Key | Type | Purpose |
| --- | --- | --- |
| `environment` | object | **Required.** The Environment object to provision this tier's servers into. |
| `parameters` | dict | Optional. Key-value pairs used in fulfilling the order, including environment-specific ones such as `instance_type` when the environment you return is an AWS region. |
| `os-build` | object | Optional. The OS Build object to provision with. Making sure it is compatible with the environment you return is up to you. |

<div class="alert alert-warning" role="alert">


The OS build key changes shape between input and output. Your function receives `os_build` with an underscore, and must return `os-build` with a hyphen. Returning `os_build` is silently ignored.
</div>


## Example

This plugin places each server in whichever of the two vSphere clusters currently has fewer VMs.

```python
from infrastructure.models import Environment
from utilities.logger import ThreadLogger
from resourcehandlers.vmware.models import VsphereResourceHandler

RESOURCE_HANDLER_ID = 7
CLUSTER_ONE = 'CORP-DEV'
CLUSTER_TWO = 'CORP-PROD'

logger = ThreadLogger(__name__)


def determine_deployment_environment_and_parameters(*args, **kwargs):
    logger.info("args are {}".format(args))
    logger.info("kwargs are {}".format(kwargs))

    # Gather the VMs for each cluster
    rh = VsphereResourceHandler.objects.get(id=RESOURCE_HANDLER_ID)
    env_one = rh.get_api_wrapper().get_vms_for_cluster(CLUSTER_ONE)
    env_two = rh.get_api_wrapper().get_vms_for_cluster(CLUSTER_TWO)

    # Choose the cluster with fewer VMs
    if len(env_one) < len(env_two):
        cluster = CLUSTER_ONE
    else:
        cluster = CLUSTER_TWO

    # Use the first environment linked to the less-used cluster
    env = Environment.objects.filter(vmware_cluster=cluster).first()

    parameters = {
        "cpu_cnt": "1",
        "disk_size": "16 GB",
        "mem_size": "512 MB",
        "vmware_datastore": "CB_Nimble",
    }

    return {"environment": env, "parameters": parameters}
```

## Ordering through the API

When you order a blueprint whose server tier uses environment selection orchestration, leave the `environment` key out of the order JSON. If you pass an environment, the tier uses it, and your orchestration never runs.

## A quick way to start

The dictionary you return closely mirrors the API payload for a server tier when deploying a blueprint through the [REST API](/docs/cmp/developer-resources/rest-api/).

1. Open a recent order for the blueprint, then select the **API** button to view the order payload.
1. Copy the dictionary for the tier you are writing the orchestration for.
1. Replace the `environment` and `os_build` values with real objects rather than their API href representations, and rename the OS build key to `os-build` for the return value.

## Related

- [CloudBolt plugins](/docs/cmp/use/orchestration/plugins/): writing the plugin.
- [Blueprints](/docs/cmp/use/blueprints/): server tiers and the Build tab.
