Skip to main content
Knowledge Base

Unable to import Terraform existing resources into Terragrunt

Answer

Following up on https://github.com/orgs/gruntwork-io/discussions/740, I've started to implement Terragrunt into my existing (pure) Terraform repository. I have the following structure now: ``` ├── config │   ├── _envcommon │   │   ├── vpc.hcl │   ├── Makefile ├── environments │   └── test │   ├── ap-southeast-2 │   │   ├── vpc │   │   │   ├── Makefile │   │   │   ├── terragrunt.hcl │   │   │   └── versions.tf │      │   └── region.hcl │   ├── env.hcl │   └── Makefile ├── Makefile └── terragrunt.hcl ``` The `config/_envcommon/vpc.hcl` file has the VPC module config: ```HCL locals { # Automatically load environment-level variables environment_vars = read_terragrunt_config(find_in_parent_folders("env.hcl")) # Automatically load region-level variables region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl")) aws_region = local.region_vars.locals.aws_region # Extract out common variables for reuse env = local.environment_vars.locals.environment # Expose the base source URL so different versions of the module can be deployed in different environments. base_source_url = "tfr:///terraform-aws-modules/vpc/aws//?version=4.0.0" } inputs = { # Public access to the database subnets; set the below to true create_database_subnet_group = false create_database_subnet_route_table = false create_database_internet_gateway_route = false manage_default_route_table = true default_route_table_tags = { DefaultRouteTable = true } enable_dns_hostnames = true enable_dns_support = true # If NOT PRODUCTION, we have one NAT Gateway per AZ enable_nat_gateway = true single_nat_gateway = local.env == "production" || local.env == "staging" ? false : true one_nat_gateway_per_az = local.env == "production" || local.env == "staging" ? true : false enable_vpn_gateway = local.env == "production" ? true : false enable_dhcp_options = false dhcp_options_domain_name = "service.consul" dhcp_options_domain_name_servers = ["127.0.0.1", "10.10.0.2"] # Default security group - ingress/egress rules cleared to deny all manage_default_security_group = true default_security_group_ingress = [{ cidr_blocks = "10.0.0.0/8" description = "Allow all from the local network." from_port = 0 protocol = "-1" self = false to_port = 0 }] default_security_group_egress = [] # VPC Flow Logs (Cloudwatch log group and IAM role will be created) enable_flow_log = true create_flow_log_cloudwatch_log_group = true create_flow_log_cloudwatch_iam_role = true flow_log_max_aggregation_interval = 60 private_subnet_tags = { "type" = "Private" } public_subnet_tags = { "type" = "Public" } database_subnet_tags = { "type" = "Private" "service" = "Database" } elasticache_subnet_tags = { "type" = "Public" "service" = "ElastiCache" } } ``` And `environments/test/ap-southeast-2/vpc/terragrunt.hcl` has: ```HCL locals { # Automatically load environment-level variables environment_vars = read_terragrunt_config(find_in_parent_folders("env.hcl")) # Automatically load region-level variables region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl")) aws_region = local.region_vars.locals.aws_region # Extract out common variables for reuse env = local.environment_vars.locals.environment account_id = local.environment_vars.locals.aws_account_id # create a list of subnets private_subnets_cidr = tolist(concat([local.environment_vars.locals.private_subnet_a, local.environment_vars.locals.private_subnet_b, local.environment_vars.locals.private_subnet_c])) public_subnets_cidr = concat([local.environment_vars.locals.public_subnet_a, local.environment_vars.locals.public_subnet_b, local.environment_vars.locals.public_subnet_c]) database_subnets_cidr = concat([local.environment_vars.locals.database_subnet_a, local.environment_vars.locals.database_subnet_b, local.environment_vars.locals.database_subnet_c]) elasticache_subnets_cidr = concat([local.environment_vars.locals.elasticache_subnet_a, local.environment_vars.locals.elasticache_subnet_b, local.environment_vars.locals.elasticache_subnet_c]) infra_subnets_cidr = concat([local.environment_vars.locals.infra_subnet_a, local.environment_vars.locals.infra_subnet_b, local.environment_vars.locals.infra_subnet_c]) # Extract out workspace variables for reuse VPC_CIDR = local.environment_vars.locals.VPC_CIDR } terraform { source = "${include.envcommon.locals.base_source_url}" } include "root" { path = find_in_parent_folders() } include "envcommon" { path = "${dirname(find_in_parent_folders())}/config/_envcommon/vpc.hcl" expose = true } inputs = { name = "example-${local.env}-VPC" cidr = local.VPC_CIDR # 10.0.0.0/8 is reserved for EC2-Classic azs = ["${local.aws_region}a", "${local.aws_region}b", "${local.aws_region}c"] private_subnets = local.private_subnets_cidr public_subnets = local.public_subnets_cidr database_subnets = local.database_subnets_cidr elasticache_subnets = local.elasticache_subnets_cidr intra_subnets = local.infra_subnets_cidr } ``` I was able to successfully import the VPC and its subnets: ``` 2535* terragrunt import "aws_subnet.private[0]" subnet-XXX 2536* terragrunt import "aws_subnet.private[1]" subnet-XXX 2537* terragrunt import "aws_subnet.private[2]" subnet-XXX 2538* terragrunt import "aws_subnet.public[0]" subnet-XXX 2539* terragrunt import "aws_subnet.public[1]" subnet-XXX ``` Now, when trying to import one of the `aws_route_table` resources, I get the following error: ``` terragrunt import "aws_route_table.public[0]" rtb-XXX Error: resource address "aws_route_table.public[0]" does not exist in the configuration. Before importing this resource, please create its configuration in the root module. For example: resource "aws_route_table" "public" { # (resource arguments) } ``` If I run `terragrunt plan` in the `environments/test/ap-southeast-2/vpc/` directory, I can see it is trying to add that same resource: ``` # aws_route_table.public[0] will be created + resource "aws_route_table" "public" { + arn = (known after apply) + id = (known after apply) + owner_id = (known after apply) + propagating_vgws = (known after apply) + route = (known after apply) + tags = { + "Name" = "example-test-VPC-public" } + tags_all = { + "Name" = "example-test-VPC-public" } + vpc_id = "vpc-XXX" } ``` What am I missing here? --- <ins datetime="2023-06-27T22:03:11Z"> <p><a href="https://support.gruntwork.io/hc/requests/110306">Tracked in ticket #110306</a></p> </ins>

Okay. After deleting the `.terragrunt-csche` folder, the import worked.