Importing existing resources into Terraform
In case you have existing infrastructure, that has been managed manually and want to adopt Terraform or its open source alternative OpenTofu, you are required to import existing resources into your Terraform project.
Gladly, this is possible with the metal-stack-cloud/metal provider.
Prerequisites
Make sure to install Terraform on your computer.
If you are completely new to Terraform, start with Create a cluster with Terraform before proceeding.
The assumed project structure for this guide is:
/my-terraform-project
|-- main.tf
|-- my-cluster.tf
Add the Terraform Provider
First, enter your Terraform project. Next, add the metal-stack-cloud/metal provider to your main.tf
file and configure it with your API token:
terraform {
required_providers {
metal = {
source = "metal-stack-cloud/metal"
}
}
}
provider "metal" {
api_token = "<YOUR_TOKEN>" # or set METAL_STACK_CLOUD_API_TOKEN.
}
Now run terraform init
to install all dependencies.
Importing Clusters
First, let’s create the cluster we want within our my-cluster.tf
:
resource "metal_cluster" "my_cluster" {
name = "my-cluster"
kubernetes = "1.27.8"
partition = "eqx-mu4"
workers = [
{
name = "default"
machine_type = "n1-medium-x86"
min_size = 1
max_size = 3
}
]
}
For terraform, importing a cluster can be accomplished in two ways:
- Using the command line with
terraform import metal_cluster.my_cluster "<ID or name>"
. This requires the resource to exist. - By using an
import
-block within ourmy-cluster.tf
file as follows.
Next to our resource definition, we declare our import:
import {
to = metal_cluster.my_cluster
id = "my-cluster" # name or id
}
If you have no existing cluster yet, feel free to create a new cluster and wait for it to become ready before proceeding.
Now, give terraform apply
a try. It will automatically detect if the cluster exists. If it does, it imports it. If it doesn’t it will be created.
That’s it!
Importing Public IPs
Similarly to importing clusters, you are also able to import existing IP addresses!
import {
to = metal_public_ip.my_ip
id = "my-ip" # ip-address, name or id
}
resource "metal_public_ip" "my_ip" {
name = "my-ip"
description = "Some description"
type = "ephemeral" # either ephemeral or static
}