Skip to content

Install in an air-gapped environment

When you finish, Terraform on a host with no internet access installs the Qumulo provider from files you carried in.

Before you start

  • A connected machine with Terraform, curl, and gpg
  • A way to move files to the air-gapped host

Use the provider mirror whenever you can run Terraform on the connected machine, and fall back to dev_overrides only when you cannot.

  1. On the connected machine, in a directory with the required_providers block from Install the provider, download the provider into a mirror directory. Add one -platform flag per target platform.

    terraform providers mirror -platform=linux_amd64 ./qumulo-mirror
    

    ./qumulo-mirror now holds the provider zip for each platform.

  2. Optionally, verify the mirrored zips by hand. Terraform cannot re-check the GPG signature when it installs from a local mirror.

    Each zip passes the signature and checksum checks.

  3. Copy the mirror directory to the air-gapped host, for example to /opt/terraform/providers.

    The host now holds the mirror at that path.

  4. Point Terraform at the mirror in ~/.terraformrc (Linux and macOS) or %APPDATA%/terraform.rc (Windows).

    provider_installation {
      filesystem_mirror {
        path    = "/opt/terraform/providers" # <-- Replace with your mirror path
        include = ["qumulo-terraform-registry.s3.us-east-1.amazonaws.com/*/*"]
      }
      direct {
        exclude = ["qumulo-terraform-registry.s3.us-east-1.amazonaws.com/*/*"]
      }
    }
    

    Terraform now looks in the mirror for the Qumulo provider and nowhere else.

  5. Run terraform init, then terraform plan and terraform apply as normal.

    terraform init ends with Terraform has been successfully initialized! If it reports Failed to query available provider packages, check the .terraformrc path and contents.

  1. On the connected machine, download and verify the zip for your platform with Verify a release signature by hand.

    The zip passes the signature and checksum checks.

  2. Copy the zip to the air-gapped host and unzip it.

    VERSION=1.4.22        # <-- Replace with the release version
    PLATFORM=linux_amd64  # <-- Replace with your platform
    mkdir -p /opt/terraform/providers/qumulo
    unzip "terraform-provider-qumulo_${VERSION}_${PLATFORM}.zip" -d /opt/terraform/providers/qumulo
    

    /opt/terraform/providers/qumulo now holds the provider binary.

  3. Point Terraform at the binary in ~/.terraformrc (Linux and macOS) or %APPDATA%/terraform.rc (Windows).

    provider_installation {
      dev_overrides {
        "qumulo-terraform-registry.s3.us-east-1.amazonaws.com/qumulo/qumulo" = "/opt/terraform/providers/qumulo"
      }
      direct {}
    }
    

    Terraform now loads the Qumulo provider from that directory.

  4. Skip terraform init, which would try to reach the registry, and run terraform plan and terraform apply directly.

    Both commands print a warning that provider development overrides are in effect, which is expected.

dev_overrides skips Terraform's checks

With dev_overrides, Terraform ignores version constraints and lock file verification for this provider. Your out-of-band signature and checksum check is the only one that runs.

Deploy a cluster into an air-gapped subnet

When you finish, a cluster runs in a subnet that cannot reach Qumulo Nexus or MissionQ.

The host that runs Terraform still needs to reach Qumulo Nexus, even with no other internet access. The provider requires a Nexus API token, and it copies the Qumulo Core packages from Nexus into a staging bucket that the cluster subnet can read. When package_url is set, the provider creates no staging bucket, and the nodes download that package directly, so it must be reachable from the subnet.

  1. Set air_gapped = true on the cluster resource.

    resource "qumulo_filesystem_aws" "cluster" {
      # ...
      air_gapped = true
    }
    

    The provisioner no longer checks that it can reach MissionQ and Nexus, and the cluster is not registered with Nexus.

  2. Give the subnet a route to the cloud services the cluster uses.

    VPC endpoint Type Used for
    com.amazonaws.<region>.s3 Gateway Persistent storage and the staging bucket. Already required for every deployment.
    com.amazonaws.<region>.ssm Interface Provisioner progress
    com.amazonaws.<region>.secretsmanager Interface Provisioner inputs
    com.amazonaws.<region>.ec2 Interface Floating IPs and tags on cluster nodes
    com.amazonaws.<region>.logs Interface Provisioner log streaming and audit logging

    Turn on private DNS for each interface endpoint. The default provisioner AMI downloads the AWS CLI from awscli.amazonaws.com, so either allow that host or set provisioner_ami_id to an AMI with AWS CLI v2 installed.

    Service Used for
    Microsoft.Storage and Microsoft.KeyVault service endpoints Persistent storage, the staging storage account, and provisioner inputs. Already required for every deployment.
    App Configuration Provisioner progress. Set create_appconfig_private_endpoint = true, or allow the AppConfiguration service tag.
    The AzureResourceManager and AzureActiveDirectory service tags Nodes and the provisioner sign in with their managed identity.
    packages.microsoft.com and aka.ms Nodes and the provisioner install the Azure CLI.

    Private Google Access, already required for every deployment, covers Cloud Storage, Secret Manager, Compute Engine, and Cloud Logging. The provisioner installs the Cloud Logging agent from dl.google.com. Without that host the provisioner still runs, but its log does not stream to Cloud Logging.

  3. Make operating system packages available. Nodes and the provisioner install packages from the repositories their image is configured with. Point those repositories at a mirror or proxy the subnet can reach, in a custom image or from provisioner_hooks.pre_run and node_hooks.pre_run.

    terraform apply completes, and the cluster has no nexus_organization.

Threat Detection needs a cluster registered with Nexus, so qumulo_threat_detection_aws, qumulo_threat_detection_azure, and qumulo_threat_detection_gcp cannot protect an air-gapped cluster.

To leave the air-gapped setup once the subnet can reach Nexus and MissionQ, set air_gapped = false or remove it. The next terraform apply registers the cluster with Nexus.

Next

Once terraform plan runs, deploy your first cluster with Deploy a basic AWS cluster.