Created
December 31, 2025 03:42
-
-
Save kjkuan/abe71b978b4d34d1f0f099abee883e19 to your computer and use it in GitHub Desktop.
A script that generates terraform import blocks from existing terraform resource states
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| declare -A resource_id_map=( # terraform resource type -> jq expression for its import id | |
| [aws_lb]=.arn | |
| [aws_lb_listener]=.arn | |
| [aws_lb_target_group]=.arn | |
| [aws_security_group]=.id | |
| [aws_vpc_security_group_ingress_rule]=.security_group_rule_id | |
| [aws_vpc_security_group_egress_rule]=.security_group_rule_id | |
| [aws_iam_role]=.name | |
| [aws_iam_role_policy]='"\(.role):\(.name)"' | |
| [aws_ecs_cluster]=.name | |
| [aws_ecs_cluster_capacity_providers]=.cluster_name | |
| [aws_ecs_service]='"\(.cluster|sub("^.*/"; ""))/\(.name)"' | |
| [aws_ecs_task_definition]=.arn | |
| [aws_kms_key]=.id | |
| [aws_kms_alias]=.name | |
| [aws_route53_record]=.id | |
| [aws_secretsmanager_secret]=.arn | |
| [aws_secretsmanager_secret_version]=.id | |
| # Feel free to look up the documentation and add the jq expression for the import id | |
| # For example, according to https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#import | |
| # the import id for 'aws_s3_bucket' is the bucket name, which is available from the terraform state ( | |
| # made available via "$state_attributes_json" in 'generate-imports' below), so you would add an entry here like so: | |
| # | |
| # [aws_s3_bucket]=.id | |
| # | |
| # to teach the script how to get the import id for any aws_s3_bucket resources. | |
| # | |
| ) | |
| generate-imports () { | |
| local state_attributes_json; state_attributes_json=$( | |
| terraform state pull | jq ' | |
| [ | |
| .resources[] | |
| | select(.mode == "managed") | |
| | (if .module then "\(.module)." else "" end) as $module | |
| | .instances[] as $inst | |
| | (if $inst.index_key then "[\($inst.index_key|tojson)]" else "" end) as $index | |
| | { | |
| "key": "\($module)\(.type).\(.name)\($index)", | |
| "value": $inst.attributes | |
| } | |
| ] | from_entries | |
| ' # | tee state_attributes.json | |
| # NOTE: Uncomment to see the json that can be used for mapping a resource type to | |
| # its import id used in the resource_id_map above. | |
| ) | |
| local source_state_name | |
| while read -r source_state_name; do | |
| resource_type=${source_state_name#module.*.} | |
| resource_type=${resource_type%%.*} | |
| cat <<EOF | |
| import { | |
| id = $(jq --arg key "$source_state_name" ".[\$key] | ${resource_id_map[$resource_type]:?}" <<<"$state_attributes_json") | |
| to = $(map-tf-state-name) | |
| } | |
| EOF | |
| done | |
| } | |
| map-tf-state-name () { | |
| : TODO: implement your mapping logic here and output the target resource id | |
| # NOTE: You are free to reference variables (e.g., $source_state_name or even $state_attributes_json) | |
| # in the call chain. | |
| } | |
| terraform state list | egrep -v 'data\.' \ | |
| | | |
| generate-imports |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment