May 27, 2023
• 3 min read
As part of evaluating Crossplane for IaC, one important use-case that I was evaluating was the overall flow of migrating resources managed by Terraform to Crossplane.
The idea was to run through the flow discussed in Crossplane's blog discussing the same use-case as I was interested in.
While it answered most of my questions, I was looking at understanding how to re-use the terraform state as part of the migration exercise.
Pre-requisites
- AWS Account
- AWS CLI & Terraform CLI
- Crossplane k8s cluster with Terraform & AWS Provider
Migration Flow
1. Clone the repo
It's a modified version of upbound's version .
2. Apply Terraform resources
Ensure you have Terraform & AWS CLI configured on your terminal and then apply the following, which provisions a VPC & Subnet:
terraform init
terraform plan -out tf.out
terraform apply "tf.out"
3. Verify the resources
We can see the VPC and Subnet created by Terraform on the AWS console.
4. Upload terraform state to S3
We can now upload the local terraform state file in a S3 bucket. In this example we push it in the bucket "xplanetfstate". This along with the region and the AWS credentials can be configured in the ProviderConfig, which will be used by Crossplane Compositions and Claims in the next sections:
apiVersion: tf.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: aws-us-east-1
spec:
configuration: |
terraform {
backend "s3" {
bucket = "xplanetfstate"
key = "terraform.tfstate"
region = "us-east-1"
access_key = "KEY"
secret_key = "SECRET"
}
}
provider "aws" {
shared_credentials_file = "aws-creds.ini"
region = "us-east-1"
}
credentials:
- filename: aws-creds.ini
secretRef:
key: creds
name: aws-creds
namespace: crossplane-system
source: Secret
5. Use Terraform Provider by Crossplane
We can achieve the same result using the Terraform workspace but letting it be provisioned via Terraform Provider by Crossplane.
6. Apply via composition
Let's see an example of using a composition to apply the same Terraform module but now via Terraform Provider by Crossplane:
kubectl apply -f crossplane/composition-tf-only/composition.yaml
kubectl apply -f crossplane/composition-tf-only/subnet-tf.yaml
This will provision the same VPC & Subnet but via a workspace object that internally uses Terraform itself.
7. Iterative migration with existing state
We can now take an iterative journey and re-use our existing terraform state that we originally uploaded to S3:
kubectl apply -f crossplane/composition-tf-and-native/composition.yaml
kubectl apply -f crossplane/composition-tf-and-native/subnet-mixed.yaml
In this case the same VPC provisioned originally by Terraform is continued to be used by Crossplane and is managed by Terraform Provider. And the subnet itself is now natively managed by AWS Provider.
8. Fully native
We can eventually move to an entirely native way of managing the resources.
Conclusion
With Terraform Provider and re-using existing Terraform states we are able to assess a migration journey to native Crossplane. And of course with that, all the benefits that Crossplane brings on the table.
Looking forward to evaluating the journey on an actual production workflow!
