I am trying to figure out how to import an EC2 instance into Terraform. Whenever I import the instance, if I run "terraform plan" it always wants to replace the instance.
I have tried an extremely minimal import that just has the AMI id and instance size, and I have tried a complete import where every possible value is specified. Neither seem to work, with the same results.
The initial state:
[ec2-user@ip-172-31-34-85 terraform]$ ls
provider.aws.tf test1.tf
[ec2-user@ip-172-31-34-85 terraform]$ cat provider.aws.tf
provider "aws" {
region = "eu-west-1"
}
[ec2-user@ip-172-31-34-85 terraform]$ cat test1.tf
resource "aws_instance" "web" {
ami = "ami-0bbc25e23a7640b9b"
instance_type = "t3.medium"
}
Plan:
[ec2-user@ip-172-31-34-85 terraform]$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.web will be created
+ resource "aws_instance" "web" {
+ ami = "ami-0bbc25e23a7640b9b"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t3.medium"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ network_interface_id = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = (known after apply)
+ tenancy = (known after apply)
+ volume_tags = (known after apply)
+ vpc_security_group_ids = (known after apply)
+ ebs_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
+ ephemeral_block_device {
+ device_name = (known after apply)
+ no_device = (known after apply)
+ virtual_name = (known after apply)
}
+ network_interface {
+ delete_on_termination = (known after apply)
+ device_index = (known after apply)
+ network_interface_id = (known after apply)
}
+ root_block_device {
+ delete_on_termination = (known after apply)
+ iops = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
+ timeouts {}
}
Plan: 1 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
Apply:
```[ec2-user@ip-172-31-34-85 terraform]$ terraform apply
----snip----
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_instance.web: Creating...
aws_instance.web: Still creating... [10s elapsed]
aws_instance.web: Creation complete after 11s [id=i-0875a3e74f53ed82c]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Post creation, lets check plan:
[ec2-user@ip-172-31-34-85 terraform]$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
aws_instance.web: Refreshing state... [id=i-0875a3e74f53ed82c]
No changes. Infrastructure is up-to-date.
This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.
Now we delete the state file and import the resource:
[ec2-user@ip-172-31-34-85 terraform]$ terraform import aws_instance.web i-0875a3e74f53ed82c
aws_instance.web: Importing from ID "i-0875a3e74f53ed82c"...
aws_instance.web: Import complete!
Imported aws_instance
aws_instance.web: Refreshing state... [id=i-0875a3e74f53ed82c]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
Another plan:
[ec2-user@ip-172-31-34-85 terraform]$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
aws_instance.web: Refreshing state... [id=i-0875a3e74f53ed82c]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
# aws_instance.web must be replaced
-/+ resource "aws_instance" "web" {
ami = "ami-0bbc25e23a7640b9b"
~ arn = "arn:aws:ec2:eu-west-1:341009493741:instance/i-0875a3e74f53ed82c" -> (known after apply)
~ associate_public_ip_address = true -> (known after apply)
~ availability_zone = "eu-west-1b" -> (known after apply)
~ cpu_core_count = 1 -> (known after apply)
~ cpu_threads_per_core = 2 -> (known after apply)
- disable_api_termination = false -> null
- ebs_optimized = false -> null
get_password_data = false
+ host_id = (known after apply)
~ id = "i-0875a3e74f53ed82c" -> (known after apply)
~ instance_state = "running" -> (known after apply)
instance_type = "t3.medium"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply) # forces replacement
+ key_name = (known after apply)
- monitoring = false -> null
~ network_interface_id = "eni-077ae2820afc460a7" -> (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
~ primary_network_interface_id = "eni-077ae2820afc460a7" -> (known after apply)
~ private_dns = "ip-172-31-2-15.eu-west-1.compute.internal" -> (known after apply)
~ private_ip = "172.31.2.15" -> (known after apply)
~ public_dns = "ec2-34-255-30-73.eu-west-1.compute.amazonaws.com" -> (known after apply)
~ public_ip = "34.255.30.73" -> (known after apply)
~ security_groups = [
- "default",
] -> (known after apply)
source_dest_check = true
~ subnet_id = "subnet-25d0f941" -> (known after apply)
- tags = {
- "Backup" = "True"
} -> null
~ tenancy = "default" -> (known after apply)
+ volume_tags = (known after apply)
~ vpc_security_group_ids = [
- "sg-12b9c774",
] -> (known after apply)
- credit_specification {
- cpu_credits = "unlimited" -> null
}
+ ebs_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
+ ephemeral_block_device { # forces replacement
+ device_name = (known after apply)
+ no_device = (known after apply)
+ virtual_name = (known after apply)
}
+ network_interface {
+ delete_on_termination = (known after apply)
+ device_index = (known after apply)
+ network_interface_id = (known after apply)
}
~ root_block_device {
~ delete_on_termination = true -> (known after apply)
~ iops = 100 -> (known after apply)
~ volume_id = "vol-0c46eb9d028b04d9a" -> (known after apply)
~ volume_size = 8 -> (known after apply)
~ volume_type = "gp2" -> (known after apply)
}
timeouts {}
}
Plan: 1 to add, 0 to change, 1 to destroy.
```
This is on version 0.12.3. Everything works as expected on version 0.11.14.
Seeing the same on 0.12.6. This is something that also happened long ago with block_device.
I see this on instances that were imported. I haven't tried with a new instance.
Items I have not set in my aws_instance resource, but must include in ignore_changes to prevent recreation:
ipv6_addresses,
ebs_optimized,
security_groups,
ephemeral_block_device,
Update: only on provider.aws 2.11. On provider.aws 2.22, only ebs_optimized still causes an issue.
+1
Seeing the same on
Terraform v0.12.24
+ provider.aws v2.58.0
MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)
macos Mojave
resource "aws_instance" "test1" {
ami = "ami-0ea0e838b9153f3a9"
instance_type = "t3.micro"
security_groups = ["sg-0846a52c36953458e"]
subnet_id = "subnet-0068193f3002512c7"
}
penzaideMacBook-Pro:aws_test penzai$ terraform import aws_instance.test1 i-0ec30eb274f4f98be
aws_instance.test1: Importing from ID "i-0ec30eb274f4f98be"...
aws_instance.test1: Import prepared!
Prepared aws_instance for import
aws_instance.test1: Refreshing state... [id=i-0ec30eb274f4f98be]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
md5-b4f2dc18d7dda1f9be9dbb0ba9631d57
penzaideMacBook-Pro:aws_test penzai$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
aws_instance.test1: Refreshing state... [id=i-0ec30eb274f4f98be]
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
-/+ destroy and then create replacement
Terraform will perform the following actions:
# aws_instance.test1 must be replaced
I just test on CentOS Linux release 7.5.1804 (Core).Recreate aws_instance which same with macos
Is this solved?
I am having exactly the same issue now, with terraform 0.12.26
It seemed to be solved for me later on.
If it is still happening to you after deleting the cached provider files (where they are stored I am not always 100% sure, but https://www.terraform.io/docs/commands/cli-config.html#:~:text=exclusions%20out%20yourself.)-,Provider%20Plugin%20Cache,be%20downloaded%20for%20each%20configuration. ) then come back and post the TF and provider versions you are having the problem with.
It's happening for me for aws resources such as S3 bucket etc.
I posted my question on SO: Terraform (0.12.29) import not working as expected; import succeeded but plan shows destroy & recreate
My Env:
Local machine: macOS v10.14.6
Terraform v0.12.29
+ provider.aws v3.14.1
+ provider.null v2.1.2
+ provider.random v2.3.1
+ provider.template v2.1.2
Most helpful comment
Seeing the same on 0.12.6. This is something that also happened long ago with block_device.
I see this on instances that were imported. I haven't tried with a new instance.
Items I have not set in my aws_instance resource, but must include in ignore_changes to prevent recreation:
ipv6_addresses,
ebs_optimized,
security_groups,
ephemeral_block_device,
Update: only on provider.aws 2.11. On provider.aws 2.22, only ebs_optimized still causes an issue.