Custom State Management

Custom Desired State Management Solution

This example provides desired state management to the Mulesoft AnyPoint Cloudhub 2 platform. As at time of writing, a Terraform provider existed, but was incomplete, having no mechanism to deploy the runtime.

The application stack is made up of individual API definitions, each paired with a runtime component.

graph TD

  subgraph dc["Mulesoft Anypoint Plaform"]
    subgraph vm1["Test"]
      vm1-in-a["API Managment"]
      vm1-con-a["Application Runtime"]
      vm1-in-b["API Managment"]
      vm1-con-b["Application Runtime"]
    end
    subgraph vm2["Production"]
      vm2-in-a["API Managment"]
      vm2-con-a["Application Runtime"]
      vm2-in-b["API Managment"]
      vm2-con-b["Application Runtime"]
    end
  end

  client -->
  vm1-in-a --> vm1-con-a
  client -->
  vm1-in-b --> vm1-con-b

  client -->
  vm2-in-a --> vm2-con-a
  client -->
  vm2-in-b --> vm2-con-b

classDef external fill:lightblue
class client external
 
classDef dashed stroke-dasharray: 5, 5
class vm1,vm2,cf1,cf2 dashed

Subsections of Custom State Management

Manifest

Declare Anypoint Components as Package

The proprietary Mulesoft Anypoint Platform artefact store is called Exchange, and each artefact is called an Asset. Each asset is pushed to the exchange from the autonomous development pipelines. In the examples below, these are GitLab for Windows and Jenkins for Linux. Both use platform independent Maven deploy to push the asset.

alt text alt text

The release declaration is in the form of a manifest, specifying each desired component and it’s version.

API                        Runtime
sprint-zero-api=1.0.1      sprint-zero-app=1.2.195
patient-summary-api=1.2.0  patient-summary-app=1.4.114

While the stack construction is the same in all environments, unique settings for each environment are defined in configuration management files, e.g. properties.cm. The properties management is covered in more detail in later sections.

context    target  deployTaskOverride  fqdn                   page_id    hash_id    page_title                 anypoint_env  property_suffix
container  STAGE   promote.tsk         example.atlassian.net  149094402  256409896  "Staging Environment"      TEST          tst
container  PROD    promote.tsk         example.atlassian.net  149225473  256672078  "Production Environment"   PROD          prd

Custom State Build

Custom State Release Package

The key construct for the Authoritative Release is that all aspects of the release process are predictable and repeatable. Configuration and helper scripts are packaged into an immutable release. No build process is required, so the minimal CDAF.solution is all that is required, assuming the custom state management is placed in the custom directory within the solution directory, e.g.

devops
├── CDAF.solution
├── custom
│   ├── anypoint.sh
│   ├── delta.sh
│   ├── promote.tsk
│   └── properties.varchk
├── app-components.cm
├── patient-summary-app.cm
└── properties.cm

Example of minimal CDAF.solution

solutionName=anypoint
productName=Mulesoft Anypoint Platform
artifactPrefix=0.7

The configuration files are transformed into properties files

alt text alt text

The custom deployment tools are included due to being in the custom directory

alt text alt text

And the release package is created

alt text alt text

Configuration Management

Building Desired State from Properties

The application and environment settings are split into separate configuration management files. Application settings are those which have the same value, for the release, in all environments.

context    target               region              runtime_version  java_version  release_channel
container  patient-summary-app  cloudhub-us-east-2  4.6.7            8             LTS
container  sprint-zero-app      cloudhub-us-east-2  4.7.1            17            Edge

Environment specific settings are associated to a given component, and differ for each environment. Note the special marker for sensitive data.

context    target                   FHIR_SERVER_PROTOCOL  FHIR_SERVER_HOST  FHIR_SERVER_PORT  FHIR_SERVER_BASE  DD_API_KEY  
container  patient-summary-app-tst  HTTPS                 demo.kodjin.com                443  /fhir/
container  patient-summary-app-prd  HTTPS                 server.fire.ly                 443  /r4/              PROTECT:${DD_API_KEY}

At deploy time, an array is constructed combining the application settings and the environment properties. A SHA-256 hash is generated from each array, to provide an identification mechanism of state, without disclosing any of the settings, some of which maybe sensitive.

After deployment, these are persisted. In this example, they are stored in an Atlassian Confluence page. The advantage of this is that if it is desired to reset an environment after suspected manual interference, the record(s) can be deleted and the deployment rerun.

alt text alt text

Desired State

Determining Change

At deploy time, the current state, and desired state are compared, and only those components which have changed, are deployed.

In this example, deployment is orchestrated in Octopus Deploy Release Train

alt text alt text

Once complete, the new current state is persisted.

alt text alt text

These can be aggregated in the Wiki to provide a consolidate view for non-techincal users

alt text alt text

Note that the overarching release number is used as a update comment when writing to the Confluence page, this provides a release history which is visible outside of the toolchain, which is easier to access by business users such as test managers and product owners.

alt text alt text