terraform

Terraform Import

2023/08/12 Update:


Terraform v1.5.0 and later has a new import flow, which is more convenient. e.g.

# Put the following in a config file, and run: terraform plan -generate-config-out=db-gen.tf
# It will create a new file, db-gen.tf, with the required config!

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }

  required_version = ">= 1.5.0"
}

provider "aws" {
  region  = "us-east-1"
}

import {
  to = aws_dynamodb_table.new-table-config-name # This will be the new resource name
  id = "example-table-2023-a"                   # This is a table created from a backup!
}


Or, if you already have config for the resource, but perhaps it's name changed or was copied, change the config's resource name and run:

terraform import aws_dynamodb_table.example-table-2023-b example-table-2023-b


Terraform has started showing examples of these at the bottom of their resource documentation, e.g. https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/dynamodb_table#import


It's much smoother than it used to be!


Original article:


Will probably have to use AWS Console or AWS Cli to find IDs to import. Unfortunately they don't use a universal ID like ARN, but random things. Cloudwatch event targets for example use rule_name/target_id to import, while EC2 instances use instanceID. You can figure out what the thing you need to import is by going to the bottom of each documentation section, e.g.:

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule


Can't import until configuration has been created(why?). Can be blank though.


e.g.: import a cloudwatch event target:


Get rule name from cli (for the next step):

aws events list-rules


Get target ID from cli:


aws events list-targets-by-rule --rule "TestAnApiCall"

# Create a slot in the config for it to go in: (the config won't actually be modified automatically)
resource "aws_cloudwatch_event_target" "test_api_target_2" {
}


terraform import aws_cloudwatch_event_target.test_api_target_2 TestAnApiCall/Id6eaxxxyyyzzz


If it succeeds, run:

terraform show

^ copy the results into the .tf file where we put the blank resource block


For some reason, some of the properties it will display in terraform show are not allowed. You may need to remove those.