Terraform is a great tool to create, change and destroy resources on the the cloud and there is great variety of providers to do so. However, you might eventually find yourself in a place where you want to “adopt” existing resources that someone has manually created on the data center. This posts details how you can do this in a safe way and we will be using AWS security groups as an example.

Import existing AWS infrastructure

terraform import command is used to import existing AWS resources to terraform state. Currently there is no way to generate terraform code from existing resources. You still need to write the code and import the resource from your provider by following the steps below:

  1. Create empty resource
  2. Import existing resource from your cloud provider
  3. Populate empty resource with values read from state file

Create empty resource

resource "aws_security_group" "jump-host" {
}

Import existing resource

Import the resource using the resource id from AWS console (e.g. sg-404ae452).

terraform init
terraform import aws_security_group.jump-host sg-404ae452

Populate empty resource

Terraform will create a state file with the current configuration of the resource (terraform.tfstate file). You can then use this file to fill in the details for the empty resource (jump-host) you previously created.

Manage terraform state drift

Ideally you only need to this once and people in your team start using terraform to make changes in the infrastructure. However, it is likely that someone made a manual change here and there. In that case, when running terraform apply, terraform will revert those changes to reconcile to the state defined on your code. You can remove existing terraform state (or maybe keep a backup of it for safety) and repeat the same steps described above to import the update the modified resource.

mv terraform.tfstate terraform.tfstate.original
terraform import aws_security_group.jump-host sg-404ae452

# update terraform code with current state

Additional resources

This a simple setup, where terraform state is kept locally using a version control system. However, as a part of wider team that uses terraform you should be using a remote backend. You can find more details about terraform state and remote backends at this post from Gruntwork team.