Import an existing cluster¶
When you finish, a Qumulo cluster that is already running is in Terraform state, and terraform plan reports no changes.
Before you start¶
- Terraform 1.11 or later, signed in to the cloud the cluster runs in, or a connection profile for a bare metal cluster
- On AWS, the extra permissions in AWS import permissions
- The cluster's admin password, soft capacity limit, and floating IP count from your own records
- For a cluster built by
aws-terraform-cnq,azure-terraform-cnq, orqumulo-terraform-gcp, follow Adopt a cluster built by the legacy CNQ modules instead
1. Find the import ID¶
The import ID is <region>/<deployment_unique_name>. List the unique names of the clusters in the region.
aws ec2 describe-instances --region us-east-1 \
--filters "Name=tag-key,Values=Qumulo-Cluster" \
--query 'Reservations[].Instances[].Tags[?Key==`Qumulo-Cluster`][].Value' \
--output text | tr '\t' '\n' | sort -u
Each cluster prints one line, such as qumulo-a1b2c3. The import ID for it is us-east-1/qumulo-a1b2c3.
The import ID is <subscription_id>/<resource_group_name>/<deployment_unique_name>. List the VMs in the cluster's resource group.
Each node prints as <deployment_unique_name>-node-<id>, such as qumulo-a1b2c3-node-1. The import ID is 00000000-0000-0000-0000-000000000000/rg-qumulo/qumulo-a1b2c3, with your subscription ID first.
The import ID is <project_id>/<region>/<deployment_unique_name>. List the instances in the cluster's project.
Each node prints as <deployment_unique_name>-node-<id>, such as qumulo-a1b2c3-node-1, and any -provisioner instance can be ignored. The import ID is your-gcp-project-id/us-central1/qumulo-a1b2c3.
The import ID is the name of the connection profile in your provider block, such as baremetal or edge. There is nothing to look up.
You now hold one import ID. On a cloud, its last segment ends in a six-character suffix, such as -a1b2c3.
2. Write the configuration¶
Save the configuration for your cloud as main.tf. Replace every value marked <-- Replace with the running cluster's value, and give deployment_name the bare name without the suffix.
terraform {
required_version = ">= 1.11"
required_providers {
qumulo = {
source = "qumulo-terraform-registry.s3.us-east-1.amazonaws.com/qumulo/qumulo"
version = "~> 1.0"
}
}
}
provider "qumulo" {
aws {}
}
resource "qumulo_filesystem_aws" "cluster" {
cluster_name = "qumulo" # <-- Replace with the running cluster's name
deployment_name = "qumulo" # <-- Replace with the deployment name, without the suffix
region = "us-east-1" # <-- Replace with the region in the import ID
subnet_ids = ["subnet-0123456789abcdef0"] # <-- Replace with the cluster's subnet IDs
node_count = 3 # <-- Replace with the current node count
instance_type = "m6idn.2xlarge" # <-- Replace with the nodes' instance type
cluster_product_type = "HOT" # <-- Replace with HOT or COLD
storage_class = "INTELLIGENT_TIERING" # <-- Replace with the class the buckets use
soft_capacity_limit_tb = 500 # <-- Replace with the current soft capacity limit
admin_password = "YourSecurePassword123!" # <-- Replace with the current admin password
allow_cidrs = ["10.0.0.0/8"] # <-- Replace with the security group's ingress CIDRs
networking_mode = "host_managed"
floating_ip_count = 0 # <-- Replace with the cluster's floating IP count
}
Read storage_class from any object in one of the cluster's -qps- buckets.
aws s3api list-buckets --query "Buckets[?contains(Name, 'qumulo-a1b2c3-qps')].Name" --output text
aws s3api list-objects-v2 --bucket <bucket> --max-items 1 --query 'Contents[0].StorageClass'
The second command prints the class to declare, such as "INTELLIGENT_TIERING".
terraform {
required_version = ">= 1.11"
required_providers {
qumulo = {
source = "qumulo-terraform-registry.s3.us-east-1.amazonaws.com/qumulo/qumulo"
version = "~> 1.0"
}
}
}
provider "qumulo" {
azure {
subscription_id = "00000000-0000-0000-0000-000000000000" # <-- Replace with the subscription in the import ID
}
}
resource "qumulo_filesystem_azure" "cluster" {
cluster_name = "qumulo" # <-- Replace with the running cluster's name
deployment_name = "qumulo" # <-- Replace with the deployment name, without the suffix
resource_group_name = "rg-qumulo" # <-- Replace with the resource group in the import ID
location = "eastus2" # <-- Replace with the cluster's region
subnet_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-network/providers/Microsoft.Network/virtualNetworks/vnet-main/subnets/subnet-qumulo" # <-- Replace with the cluster's subnet resource ID
node_count = 3 # <-- Replace with the current node count
vm_type = "Standard_L8s_v3" # <-- Replace with the nodes' VM size
storage_class = "STANDARD" # <-- Replace with the class the storage accounts use
soft_capacity_limit_tb = 500 # <-- Replace with the current soft capacity limit
admin_password = "YourSecurePassword123!" # <-- Replace with the current admin password
allow_cidrs = ["10.0.0.0/8"] # <-- Replace with the NSG's inbound CIDRs
networking_mode = "host_managed"
floating_ip_count = 0 # <-- Replace with the cluster's floating IP count
}
For storage_class, open a cluster storage account in the Azure portal. An access tier of Smart means INTELLIGENT_TIERING, and Hot means STANDARD.
terraform {
required_version = ">= 1.11"
required_providers {
qumulo = {
source = "qumulo-terraform-registry.s3.us-east-1.amazonaws.com/qumulo/qumulo"
version = "~> 1.0"
}
}
}
provider "qumulo" {
gcp {
project_id = "your-gcp-project-id" # <-- Replace with the project in the import ID
region = "us-central1" # <-- Replace with the region in the import ID
}
}
resource "qumulo_filesystem_gcp" "cluster" {
cluster_name = "qumulo" # <-- Replace with the running cluster's name
deployment_name = "qumulo" # <-- Replace with the deployment name, without the suffix
subnetwork = "qumulo-subnet" # <-- Replace with the cluster's subnetwork name
node_count = 3 # <-- Replace with the current node count
instance_type = "n2-highmem-8" # <-- Replace with the nodes' machine type
soft_capacity_limit_tb = 500 # <-- Replace with the current soft capacity limit
admin_password = "YourSecurePassword123!" # <-- Replace with the current admin password
allow_cidrs = ["10.0.0.0/8"] # <-- Replace with the firewall rule's source ranges
networking_mode = "host_managed"
floating_ip_count = 0 # <-- Replace with the cluster's floating IP count
}
resource "qumulo_filesystem_baremetal" "cluster" {
connection_profile = "baremetal"
cluster_name = "prod" # <-- Replace with the running cluster's name
admin_password = "YourSecurePassword123!" # <-- Replace with the current admin password
lifecycle {
ignore_changes = [cluster_name, admin_password, cluster_version, blocks_per_stripe, max_drive_failures, max_node_failures]
}
}
For an edge cluster, use qumulo_filesystem_edge_baremetal with ignore_changes = [cluster_name, admin_password, cluster_version].
Then check the file.
The validate command prints Success! The configuration is valid. Every attribute and its import behavior is listed in Import IDs and attributes.
3. Import the cluster¶
The command ends with Import successful! The cluster is now in state, and nothing on it has changed.
4. Fix the plan¶
For every attribute the plan wants to change, copy the live value from terraform state show into main.tf, then plan again. Stop when every remaining change sets a value import cannot recover, such as cluster_name, networking_mode, or soft_capacity_limit_tb, and the plan ends with Plan: 0 to add, 1 to change, 0 to destroy.
On bare metal, the ignore_changes list covers the values the cluster cannot report. The plan reports No changes., and step 5 can be skipped.
Warning
Never apply a plan that says must be replaced or shows 1 to destroy. Those lines mean main.tf still disagrees with the running cluster.
5. Apply¶
The apply ends with Apply complete! Resources: 0 added, 1 changed, 0 destroyed. Run terraform plan once more, and it reports No changes. Your infrastructure matches the configuration.
Set node_replacement_when_changed only in a later apply, once this plan is clean.
Next¶
The cluster now answers to Terraform like one you created. Keep Import IDs and attributes open for the full attribute lists.