Deploy a Solution to Production

Detailed information how to you can deploy your Solution into a production-like environment

Overview

Deployments to production environments differ from non-production environments in that the production cluster is separate from the non-production clusters and the Solution Designer's UI for creating the Deploy pipeline is not available because typically only the Solution Hub is installed.

To deploy a solution developed with IBM Financial Services Workbench to a production-like environment you therefore need to consider at least the following additional requirements:

  • The image of the Solution must be copied between different OpenShift Container Platform registries, from a non-production cluster to a production cluster.

  • The Deploy pipeline in the production environment must be created once by calling the REST API directly instead of using the Solution Designer's UI.
  • The Solution configuration must be transferred and modified once for the production environment.

This guide explains the basic workflow for this deployment and shows examples of how these requirements can be implemented. However, it does not provide a production-ready workflow, but is a useful example that you can adapt to your specific security and automation requirements.

For this explanation, the following deployment scenario is assumed:

  • You have an OpenShift project {Source Project} in your non-production cluster {Source Cluster} that is used as a deployment target for the solutions you developed. Your solution {Solution Acronym} is already built and deployed into this project. The container image {Solution Image} of this solution that is ready for promotion to production is tagged with {Source Tag} and stored in the internal OpenShift docker registry in your non-production cluster.

  • You have an OpenShift project {Destination Project} in your production cluster {Destination Cluster}, which is used as a deployment target for your production-ready solutions. Your solution should be deployed to this project and the container image {Solution Image} should be tagged with {Destination Tag} and stored in the internal OpenShift docker registry in your production cluster.

The following steps outline the process:

Check Prerequisites

Before you begin, ensure that the following tasks are complete:

  1. Install skopeo

    The command line tool skopeo is used to copy the solution image between different OpenShift Container platform registries. It is preferable to using Docker because it can copy an image from one registry to another without first downloading it locally and without running a daemon to work.

  2. Obtain OpenShift account with sufficient permissions

    To copy the solution image to the production image registry, an account in the role of cluster administrator is required on the non-production and production cluster. Creating the pipeline for solution deployment via a REST API call requires the Project Administrator role for the project for which you are creating the pipeline.

  3. Provide access to the OpenShift’s Docker Registries

    This guide assumes that you have external access to the internal OpenShift image registry of the non-production and the production cluster. You can find out the external address for each registry by viewing the route image-registry in the openshift-image-registry namespace.

    Check if these addresses are accessible from your network, for example as follows:
    $ oc login -u={Username} -p={Password} -s={Source Cluster}
    $ SRC_IMAGE_REGISTRY=$(oc get route image-registry -n openshift-image-registry --template='{{ .spec.host }}')
    $ curl -v https://$SRC_IMAGE_REGISTRY/healthz

Step 1: Copy the solution image to the production image registry

Use the copy command of the skopeo tool as shown here to copy the solution image from the non-production registry to the production registry.

oc login -u={Username} -p={Password} -s={Source Cluster}
SRC_CREDS="openshift:$(oc whoami -t)"
SRC_REGISTRY=$(oc get route image-registry -n openshift-image-registry --template='{{ .spec.host }}')
oc login -u={Username} -p={Password} -s={Destination Cluster}
DEST_CREDS="openshift:$(oc whoami -t)"
DEST_REGISTRY=$(oc get route image-registry -n openshift-image-registry --template='{{ .spec.host }}')
skopeo copy --dest-creds ${DEST_CREDS} --dest-tls-verify=false \
--src-creds ${SRC_CREDS} --src-tls-verify=false \
docker://${SRC_REGISTRY}/{Source Project}/{Solution Image}:{Source Tag}
docker://${DEST_REGISTRY}/{Destination Project}/{Solution Image}:{Source Tag} 
Note:
  • In this example, replace the placeholder variables {..} as follows:

    • {Username} and {Password} : OpenShift account in the role of cluster administrator.
    • {Source Cluster} : Host name of the non-production OpenShift cluster.
    • {Destination Cluster}: Host name of the production OpenShift cluster.
    • {Solution Image}: Name of the image that should be copied.
    • {Source Tag} : Tag of the image that should be copied.
    • {Source Project} : Name of the project in which the Solution is already deployed.
    • {Destination Project} : Name of the project to which the Solution should be deployed.
  • The --src-tls-verify=false and --dest-tls-verify=false options for the copy command can be used if the default cluster certificate for routes is untrusted.

  • The source-image and destination-image parameters of the copy command use the form docker:://{External Address of Image Registy}/{project}/{image}:{tag}.

Step 2: Create the pipeline for solution deployment via REST API call

The solution {Solution Acronym} will be deployed by executing a Deploy pipeline on the production cluster. The Deploy pipeline configuration must once be created using the Pipeline Manager API.

You can find the URL of the Swagger UI for this API on the Solution Envoy Dashboard for your target project {Destination Project} under Infrastructure on the production cluster. If {Destination Domain} denotes the cluster domain, the URL is usually as follows: https://{Destination Project}.{Destination Domain}/swagger/-/swagger-ui.html?urls.primaryName=pipeline-manager#/pipeline-controller

The pipeline configuration is set to use the existing image {Solution Image} that was previously copied to the production registry, deploy it into the target project {Destination Project} and set the image tag{Destination Tag}. The Deploy pipeline is triggered immediately by creation, but also automatically every time the image {Solution Image} with the tag {Source Tag} has changed in the production registry.

To create the Deploy Pipeline configuration, make a POST request on the production cluster using, for example, the curl command line tool as shown in the following example:

$ TOKEN=$(oc whoami -t)
$ URL="https://{Destination Project}.{Destination Domain}/-/pipelines/v1/-/deploy"
$ curl -k \
    -X POST \
    -d @- \
    -H "Authorization: Bearer $TOKEN" \
    -H 'Accept: application/json' \
    -H 'Content-Type: application/json' \
     $URL <<'EOF'
{
    "pipelineName": "{Pipeline Name}",
    "application": "{Application Group}",
    "autoDeploy": true,
    "inputImageNamespace": "{Destination Project}",
    "inputImageTag": "{Source Tag}",
    "resultImageTag": "{Destination Tag}",
    "skipSolutionTest": true,
    "solutionAcronym": "{Solution Acronym}",
    "solutionType": "ddd"
}
EOF
Note:
  • In this example, replace the placeholder variables {..} as follows:

    • {Destination Project} : Project to which the Solution should be deployed.
    • {Destination Domain} : URL of the Domain of the production cluster.
    • {Pipeline Name} : Name of the Deploy Pipeline to be created.
    • {Application Tag} : Tag to label a group of solutions.
    • {Source Tag} : Tag of the image that should be deployed.
    • {Destination Tag} : Tag that should be set for the deployed image.
    • {Solution Acronym} : Solution acronym in capital letters.
  • Expect an HTTP 200/OK message returning the pipeline name.

You can also call the following API methods as needed:

  • Get a pipeline configuration with a GET request
    $ URL="https://{Destination Project}.{Destination Domain}/-/pipelines/v1/{Pipeline Name}"

    Expect an HTTP 200/OK message returning the pipeline configuration.

  • Trigger a pipeline with a POST request
    $ URL="https://{Destination Project}.{Destination Domain}/-/pipelines/v1/{Pipeline Name}"

    Expect an HTTP 200/OK message returning the pipeline name run.

  • Delete a pipeline with a DELETE request
    $ URL="https://{Destination Project}.{Destination Domain}/-/pipelines/v1/{Pipeline Name}"

    Expect an HTTP 204/No content message.

Step 3: Create the solution specific configuration for production

The need to create a solution-specific configuration for a solution arises when the configuration parameters differ across stages and must be adjusted in production and this parameter configuration differs from the default solution configuration in production.

This situation is common when the solution refers to an API dependency that was not developed with the IBM Financial Services Workbench. For example, to customize this API dependency in terms of URL and authentication data, you can create an API binding that contains these parameters by creating a solution specific configuration for production.

Attention: You might not need a specific API Binding if the named dependency was also developed with IBM Financial Services Workbench and you selected Local lookup in your solution when adding the API dependency.
Attention: The created configuration must be applied to the solution by redeploying the solution. To do this, you must trigger the deployment pipeline with a POST request as described in step 2 after you create the configuration.

The solution-specific configuration can be created using the Configuration Management API. You can find the host name {Config Management Host} of this Configuration Management API by viewing the {configuration_management} route in the {FSW Project} project where you have installed IBM Financial Services Workbench on the production cluster. The URL of the Swagger UI is usually as follows: https://{Config Management Host}/swagger-ui.html#/configuration-controller

To create the solution specific configuration, make a POST request on the production cluster using, for example, the curl command line tool as shown in the following example:

$ TOKEN=$(oc whoami -t)
$ URL="https://{Config Management Host}/api/cfg/v1/runtimes/{Destination Project}/solutions/{Solution Acronym}/configurations/{Solution Configuration}"
$ curl -k \
    -X POST \
    -d @- \
    -H "Authorization: Bearer $TOKEN" \
    -H 'Accept: application/json' \
    -H 'Content-Type: application/json' \
     $URL <<'EOF'
{
    "url": "{External API URL}",
    "user": "{API Username}",
    "password": "{API Password}"
}
EOF
Note:
  • In this example, replace the placeholder variables {..} as follows:

    • {Config Management Host} : Host name of the Configuration Management API.
    • {External API URL} : URL of the external API.
    • {API Username} and {API Password} : Credentials for external API access.
  • Expect an HTTP 201/No content message message.

  • The solution had to be deployed already by step 2, since a solution-specific configuration can be created only for an already existing solution.

You can also call the following API methods as needed:

  • Get a solution specific configuration with a GET request.
    $ URL="https://{Config Management Host}/api/cfg/v1/runtimes/{Destination Project}/solutions/{Solution Acronym}/configurations/{Solution Configuration}"

    Expect an HTTP 200/OK message returning the configuration.

  • Get all solution specific configurations for a solution with a GET request.
    $ URL="https://{Config Management Host}/api/cfg/v1/runtimes/{Destination Project}/solutions/{Solution Acronym}/configurations"

    Expect an HTTP 200/OK message returning the configurations.

  • Delete a solution specific configuration with a DELETE request.
    $ URL="https://{Config Management Host}/api/cfg/v1/runtimes/{Destination Project}/solutions/{Solution Acronym}/configurations/{Solution Configuration}"

    Expect an HTTP 204/No content message.