Import an existing infrastructure into Terraform
Stephane Jourdan
2 juillet 2020
0 minutes de lectureEditor's note: This post originally appeared on CloudSkiff.com. CloudSkiff joined Snyk in October 2021.
Sometimes you need to import an existing infrastructure into Terraform. This happens for a lot of reasons. Some people are only just getting started and need to migrate existing infrastructures and build a new code base out of it. Sometimes, even though you are an expert, you just need to go from a POC (proof of concept) that you rapidly built by clicking around in your console to a live project that needs to be stable in production.
Assuming that you already have a live infrastructure that you built from your cloud console… how do you get some Terraform code from it, and more importantly how do you make it work?
In this article, we’ll quickly review the main ways to automatically generate infrastructure code from an existing environment — how to clone an environment, make it work, and ensure that it’s repeatable.
Import an existing infrastructure into Terraform using Terraform import
If you have a small number of resources to turn into code, and the required skills, you can simply re-write the code. But obviously, you need to exactly know how those resources are configured.
In case you already have an existing Terraform code base, once the code is written, you’ll need to terraform import
it within your codebase. terraform import
is a subcommand from Terraform. And since this code will perfectly match the existing resources within your cloud provider's account, you will achieve a perfect balance between your code, your existing resources, and your TFState file.
Import an existing infrastructure into Terraform with an importer
The option we just mentioned can work for a small number of resources, but for larger environments, the task can be daunting. There are different importers converters, scanners terraform generators, etc. on the market that will help you.
One of them, Terraformer, was built by the Waze SRE Team in Tel Aviv.
Upon giving it your credentials, Terraformer will scan your cloud provider's account for resources and when it finds one, it will convert it into proper Terraform code with a working state file.
The code you will get is not super clean, certainly not DRY but it gets 80% of the job done and you can start building on top of it.
Key steps to turn your imported infrastructures into Terraform code that works
Once you have imported your existing resources into Terraform, it is crucial that you follow a couple of further steps to make it work. Indeed, at this stage, the code is neither clean nor optimized.
Ensure that everything is using variables and ensure that all the variables are unified.
Imagine you have a VPC network called VPC
. This situation can be a problem in case you can only have one VPC name per region. This is the case for Amazon S3 buckets. For example, as you can have only one s3 bucket worldwide for all the customers.
Renaming the resources is going to take you a little bit of time. But once you ensure through variables that the names you use are unique, you get pretty sure that the code is repeatable in another region.
Explicitly declare your dependencies.
One of the problems with importing automatically resources to Terraform code is that very often the links between the resources are not made. You will see some resources that make sense as a whole, but that do not have dependencies explicitly declared. Or maybe that are declared but not through variables.
For example, you might face a situation where you have a security group rule declared and linked to an ID for this security group and the whole thing working properly. But if there is no internal link, or more precisely no dependency inside the code, the next time you will try to redeploy it in another region you will probably deploy rules and a security group that are not linked together.
Last but not least: Ensure repeatability through randomness
The last key step is to ensure repeatability through randomness. Basically, randomizing names with a few characters is enough.
I personally use a random string with a suffix. This generates a very simple eight characters long randomized string (without special characters because you don’t want weird characters in your name). I just create local variables here.
For my production and my staging system, I just add them as a suffix. Thus I’m sure that whether I’m in a production or in a staging environment, I will have a unique randomized name based on this. And I can very easily in just a copy-paste create another environment for testing.
1# cluster name needs to be unique
2resource "random_string" "suffix" {
3 length = 8
4 special = false
5}
6locals {
7 production_cluster_name = "eks-production-${random_string.suffix.result}"
8 staging_cluster_name = "eks-staging-${random_string.suffix.result}"
9}
10# Production Cluster
11module "production_cluster" {
12 source = "terraform-aws-modules/eks/aws"
13 version = "7.0.1"
14 cluster_name = local.production_cluster_name
15 cluster_version = var.kubernetes_version
16 manage_aws_auth = true
17 worker_ami_name_filter = "amazon-eks-node-1.14-v20200312"
18 subnets = module.vpc.private_subnets
19 vpc_id = module.vpc.vpc_id
20 map_users = var.map_users
21 workers_additional_policies = [aws_iam_policy.allow_ecr.arn]
22 worker_additional_security_group_ids = [aws_security_group.management.id]
23 worker_groups = [
24 {
25 name = "production-1.14-wg-small"
26 instance_type = "t3.small"
27 asg_max_size = 2
28 asg_desired_capacity = 1
29 },
30 {
31 name = "production-1.14-wg-medium"
32 instance_type = "t3.medium"
33 asg_max_size = 3
34 asg_desired_capacity = 2
35 asg_min_size = 2
36 }
37 ]
38 tags = {
39 environment = "production"
40 Terraform = "true"
41 }
42 workers_group_defaults = {
43 key_name = aws_key_pair.admin.key_name
44 }
45}
Wrap up
Importing your resources is just step 1 and rarely is enough.
To make your code actionable, your next steps are to:
Ensure that everything is using variables
Ensure that all the variables are unified.
Declare your dependencies and link them
Randomize variables to generate unique names.
Securing your Terraform code
Snyk IaC secures your Terraform configs (and Kubernetes, CloudFormation, and ARM templates!) as you code, with guided fixes so you can merge and move on. You can test as you write, monitor for changes in your git repositories, and automate testing in your build pipelines before deployment. Getting started with a Free plan takes minutes, while a breach from an IaC misconfiguration can cause damage to last a lifetime. Sign up and start securing your configs below.
Une infrastructure sécurisée à la source
Snyk automatise la sécurité et la conformité de l’IaC dans les workflows, et détecte les ressources manquantes ou ayant dérivé.