Air-Gapped with Halyard

Options for deploying Armory Enterprise using Armory Halyard in an air-gapped environment.

Overview

This guide shows how you can host the Armory Enterprise Bill of Materials (BOM) and Docker images in your air-gapped environment.

Halyard is scheduled for deprecation in 2021, so Armory recommends using the Armory Operator to deploy and manage Armory Enterprise on Kubernetes. See Air-Gapped with the Armory Operator for instructions.

Before you begin

  • You have read the introduction to air-gapped environments.
  • You are using Armory-extended Halyard to deploy and manage Armory Enterprise.
  • You have public internet access and access to the environment where you want to deploy Armory Enterprise.
  • You have access to a private Docker registry with credentials to push images.
  • You have installed the AWS CLI.
  • You have installed yq version 4+. This is used by helper scripts.

Host Armory’s Bill Of Materials (BOM)

Armory’s BOMs are stored in public AWS S3 bucket: s3://halconfig.

If you are unable to access this bucket from the machine running Halyard, host the BOM in storage that is compatible with AWS S3 or Google Cloud Storage (GCS). MinIO is a good option.

Update Halyard to use your custom storage bucket

If you’re running Halyard in Kubernetes, Armory recommends using the Armory Operator to deploy and manage Armory Enterprise on Kubernetes. See Air-Gapped with the Armory Operator for instructions.

After you have created your custom storage bucket, you need to enable custom storage in Halyard. Create /opt/spinnaker/config/halyard-local.yml with the following content:

spinnaker:
  config:
    input:
      # To use a custom GCS bucket, switch this to true
      gcs:
        enabled: false
      # Name of your private bucket
      bucket: <your-bucket-name>
      # If your s3 bucket is not in us-west-2 (region does not matter for Minio)
      region: <aws-s3-bucket-region>
      # If you are using a platform that does not support PathStyleAccess, such as Minio, switch this to true
      # https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro
      enablePathStyleAccess: false
      # For s3 like storage with custom endpoint, such as Minio:
      # endpoint: https://minio.minio:9000
      # anonymousAccess: false

Restart Halyard.

Host the Armory Enterprise BOM

Use bomdownloader.sh to download the version of the Armory Enterprise BOM that you require.

Show the script
#!/bin/bash

# This script download a version of Armory's BOM to a local directory
# Usage: bomdownloader.sh <version name> <docker_registry>
# Prerequisites:
# - aws cli: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html
# - access to public s3 installed (no need for credentials)
# - write access to the destination path
# - yq: a portable command-line YAML processor

# Change that

PGM=$0
VERSION=$1
NEW_DOCKER_REGISTRY=$2
DESTINATION_DIR="halconfig"
ARMORY_BUCKET="halconfig"
ARMORY_BUCKET_REGION="us-west-2"
SERVICES="clouddriver echo gate orca igor deck fiat front50 kayenta rosco monitoring-daemon dinghy terraformer"

if [[ $# -lt 2 ]]; then
    echo "Usage: ${PGM} <version name> <new_docker_registry_address>"
    exit 1
fi

mkdir -p ${DESTINATION_DIR}/bom
aws s3 cp --no-sign-request --region ${ARMORY_BUCKET_REGION} s3://${ARMORY_BUCKET}/versions.yml ${DESTINATION_DIR}
bom="${DESTINATION_DIR}/bom/${VERSION}.yml"
aws s3 cp --no-sign-request --region ${ARMORY_BUCKET_REGION} s3://${ARMORY_BUCKET}/bom/${VERSION}.yml ${bom}
for svc in $SERVICES; do
    sv=$(yq e '.services.'${svc}'.version' ${bom})
    sdir="$DESTINATION_DIR/profiles/${svc}/${sv}"
    mkdir -p $sdir
    aws s3 cp --no-sign-request --region ${ARMORY_BUCKET_REGION} --recursive --include "*" s3://${ARMORY_BUCKET}/profiles/${svc}/${sv}/ $sdir
done

sed -i '' "s/docker.io\\/armory/$(echo $NEW_DOCKER_REGISTRY | sed 's/\//\\\//g')/g" $bom

echo "Version ${VERSION} is ready to be uploaded to your private bucket."
echo "For example, with \"aws cp --recursive\"  or \"gsutil cp -m -r ...\""

The script creates a halconfig folder, downloads the necessary files, and updates the BOM to use the Docker registry you specified.

To download the BOM, run bomdownloader.sh <armory-version> <docker-registry>. For example, if you want to download the 2.25.0 BOM and your registry is my.jfrog.io/myteam/armory:

./bomdownloader.sh 2.25.0 my.jfrog.io/myteam/armory

Output is similar to:

download: s3://halconfig/versions.yml to halconfig/versions.yml
download: s3://halconfig/bom/2.25.0.yml to halconfig/bom/2.25.0.yml
download: s3://halconfig/profiles/clouddriver/2.25.3/clouddriver.yml to halconfig/profiles/clouddriver/2.25.3/clouddriver.yml
...
Version 2.25.0 is ready to be uploaded to your private bucket.
For example, with "aws cp --recursive"  or "gsutil cp -m -r ..."

Inspecting your file system, you should see the new halconfig folder. For example, if you specified Armory Enterprise v2.25.0, your file system should be:

halconfig
 ┣ bom
 ┃ ┗ 2.25.0.yml
 ┣ profiles
 ┃ ┣ clouddriver
 ┃ ┣ dinghy
 ┃ ┣ echo
 ┃ ┣ fiat
 ┃ ┣ front50
 ┃ ┣ gate
 ┃ ┣ igor
 ┃ ┣ kayenta
 ┃ ┣ monitoring-daemon
 ┃ ┣ orca
 ┃ ┣ rosco
 ┃ ┗ terraformer
 ┗ versions.yml

Each subdirectory in the profiles directory contains a <service-name>.yml profile file.

If you need to change your Docker registry, you can manually edit the <armory-version>.yml file located under halconfig/bom. Update the value for the key artifactSources.dockerRegistry.

version: 2.25.0
timestamp: "2021-03-25 09:28:32"
services:
    clouddriver:
        commit: de3aa3f0
        version: 2.25.3
    deck:
        commit: 516bcf0a
        version: 2.25.3
    ...
    terraformer:
        commit: 5dcae243
        version: 2.25.0
dependencies:
    redis:
        version: 2:2.8.4-2
artifactSources:
    dockerRegistry: my.jfrog.io/myteam/armory

Copy the BOM to your custom storage bucket

Upload the files you just downloaded to your storage bucket. Make sure they are readable from wherever Halyard is running.

For example:

$ aws s3 cp --recursive halconfig s3://halconfig

$ gsutil cp -m -r ...

Use a custom Docker registry

There are two options for hosting the Docker images: 1) configure your Docker registry as a proxy for docker.io/armory; or 2) download the images and push them to your private Docker registry.

Proxy to docker.io/armory

Configure docker.io/armory as a remote repository within your private Docker registry. If you are using JFrog Artifactory, you can follow the instructions in the Remote Docker Repositories section of the JFrog docs.

Download images

You can use the imagedownloader.sh helper script to download and push the images to your private Docker registry.

Show the script
#!/bin/bash

# This script downloads the images used by Armory 
# Usage: imagedownloader.sh <version name>
# Prerequisites:
# - docker and creds to push to your docker registry
# - yq: a portable command-line YAML processor

PGM=$0
VERSION=$1
DESTINATION_DIR="halconfig"
SERVICES="clouddriver echo gate orca igor deck fiat front50 kayenta rosco monitoring-daemon dinghy terraformer"

if [[ $# -lt 1 ]]; then
    echo "Usage: ${PGM} <version name>"
    exit 1
fi

bom="${DESTINATION_DIR}/bom/${VERSION}.yml"
armory_address=docker.io/armory
new_registy_address=$(yq e '.artifactSources.dockerRegistry' ${bom})

set -x

for svc in $SERVICES; do
    sv=$(yq e '.services.'${svc}'.version' ${bom})
    docker pull $armory_address/${svc}:${sv}
    docker tag $armory_address/${svc}:${sv} $new_registy_address/${svc}:${sv}
    docker push $new_registy_address/${svc}:${sv}
done

The script looks for the downloaded BOM and proceeds to download, tag, and push the images for that particular version to the private Docker registry you specified when you ran bomdownloader.sh.

The execution format is:

.imagedownloader.sh <armory-version>

Run the script from the parent directory of the halconfig directory that the bomdownloader script created.

Since you already updated Halyard to use your custom storage bucket, you can now configure and deploy Armory Enterprise.

Help resources

Contact Armory Support or use the Spinnaker Slack #armory channel.


Last modified May 17, 2021: (d6c91cc)