Release in an air-gapped environment
An air-gapped environment is a network physically isolated from unsecured networks. It means that when you install Digital.ai Release in such environment, Release does not have access to the internet.
Tip: see the official documentation on how to install Release on an Air-gapped Environment
Release does not need internet access to work. Without internet access, problems occur for container
type plugins, based on docker images; they are by default configured to fetch images from docker.io.
Hopefully Digital.ai will provide soon a solution to configure these plugins using a custom registry URL.
In the current Release version, version 23.3.4, the container
type plugins cannot be used in an air-gapped environment without customization.
In this article I will show you a way to customize container
type plugins so that you can use them in an air-gapped environment.
This is not without drawbacks: by using custom plugins, you’ll have to maintain the plugin definitions up to date with new versions and you’ll have to pull/push new images. This is a temporary solution until Digital.ai provides a way to manage custom image registry.
There are 3 steps:
- use a custom images registry
- pull the images from docker.io and push them in your local registry
- define new plugins based on your local registry images
Step 1: Custom registry
For this article, I’m going to use a simple local registry based on docker. Run the command:
docker run -d -p 5050:5000 --name registry registry
The command starts a local registry based on the registry
image. You can add an entry in your /etc/hosts
file to refer to this local registry like:
127.0.0.1 container-registry
You can optionally install a UI for the registy. Run the command:
docker run -d \
-p 8080:80 \
-e REGISTRY_HOST=host.docker.internal \
-e REGISTRY_PORT=5050 \
-e REGISTRY_PROTOCOL=http \
-e REGISTRY_ALLOW_DELETE=true \
--name registry-ui \
parabuzzle/craneoperator
You can access your local registry UI at http://container-registry:8080
. It’s empty for now.
Step 2: Pull images
For the demo, I’m going to use the ‘Terraform Container’ plugin.
The definition of the plugin is available in the type-definition.xml
file stored in the zip file of the plugin. Here is an extract:
<type type="containerTerraform.BaseTask" extends="xlrelease.ContainerTask" virtual="true">
<property name="image" required="true" hidden="true" default="docker.io/xebialabs/release-terraform-integration:23.3.1" transient="true"/>
<property name="iconLocation" default="release-terraform-integration.png" hidden="true"/>
<property name="taskColor" hidden="true" default="#667385"/>
</type>
As we can see, the plugin uses the docker.io/xebialabs/release-terraform-integration:23.3.1
image from docker.io.
Let’s pull this image locally:
docker pull xebialabs/release-terraform-integration:23.3.1
Now let’s push this image in our registry. To do this we first need to add our registry’s location to the repository name. Run the command:
docker tag xebialabs/release-terraform-integration:23.3.1 container-registry:5050/mycompany/release-terraform-integration:23.3.1
Warning: Be aware that in a real scenario, the URL must be set with a DNS name, resolved by the k8s server running the Release Remote runner!
then push the image:
docker push container-registry:5050/mycompany/release-terraform-integration:23.3.1
Refresh the registry ui to confirm:
Step 3: Define a custom plugin
Add the definition of a new plugin in the ext/synthetic.xml
file. The definition below is a coy of the default definition with a modified image property and custom labels (set as (MyCompany Registry)
to differenciate from the default ones):
Warning: Like for the previous warning, the URL must be set with a DNS name, resolved by the k8s server running the Release Remote runner!
<type type="mycompanyContainerTerraform.BaseTask" extends="xlrelease.ContainerTask" virtual="true">
<property name="iconLocation" default="release-terraform-integration.png" hidden="true"/>
<property name="taskColor" hidden="true" default="#667385"/>
<property name="image" required="true" hidden="true" default="container-registry:5050/mycompany/release-terraform-integration:23.3.1" transient="true"/>
</type>
<type type="mycompanyContainerTerraform.Apply" extends="mycompanyContainerTerraform.BaseTask" label="Terraform: Apply (MyCompany Registry)" description="The task is to execute terraform module for the apply command">
<property category="input" name="terraformClientVersion" readonly="true" required="false" kind="string" default="1.5.0" description="The installed terraform client version"/>
<property category="input" name="gitUrl" label="Git URL" kind="string" description="Git repository URL"/>
<property category="input" name="branch" required="false" kind="string" description="Git branch"/>
<property category="input" name="gitDirPath" required="false" kind="string" label="Git directory path"/>
<property category="input" name="gitToken" required="false" kind="string" password="true" description="Personal token for connecting to git"/>
<property name="environmentVariables" category="input" required="false" size="large" password="true" label="Environment Variables" description="Pass terraform environment variables the following format: {'VAR1': 'value1', 'VAR2': 'value2'}"/>
<property name="outputVariables" category="output" kind="map_string_string" description="Return variable and values for a Terraform module"/>
</type>
<type type="mycompanyContainerTerraform.Destroy" extends="mycompanyContainerTerraform.BaseTask" label="Terraform: Destroy (MyCompany Registry)" description="The task is to execute terraform module for the destroy command">
<property category="input" name="terraformClientVersion" readonly="true" required="false" kind="string" default="1.5.0" description="The installed terraform client version"/>
<property category="input" name="gitUrl" label="Git URL" kind="string" description="Git repository URL"/>
<property category="input" name="branch" required="false" kind="string" description="Git branch"/>
<property category="input" name="gitDirPath" required="false" kind="string" label="Git directory path"/>
<property category="input" name="gitToken" required="false" kind="string" password="true" description="Personal token for connecting to git"/>
<property name="environmentVariables" category="input" size="large" required="false" password="true" label="Environment Variables" description="Pass terraform environment variables the following format: {'VAR1': 'value1', 'VAR2': 'value2'}"/>
</type>
Restart your Release instance after modifying the synthetic.xml
file. You should now have new tasks using the new image stored in your images registry.