Terraform apply command destroys my newly imported resources

I’m using terraform to deploy infrastructure in Oracle Cloud (OCI) and I have some resources such as virtual machines that were deployed manually.
I created the below terraform script to import a VM

variable "tenancy_ocid" {}
variable "user_ocid" {}
variable "fingerprint" {}
variable "private_key_path" {}
variable "region" {}

variable "compartment_ocid" {
  type       = string
  default    = "ocid1.compartment.oc1..aaaaaaaa....."

variable "availability_domain" {
  type       = string
  default    = "phiX:US-ASHBURN-AD-1"

variable "subnet_ocid" {
  type = string
  default    = "ocid1.subnet.oc1.iad.aaaaaaaa......"

variable "ssh_public_key_file"{
    type = string
    default = "/Users/cgperalt/.ssh/id_rsa.pub" 

provider "oci" {
  tenancy_ocid      = var.tenancy_ocid
  user_ocid         = var.user_ocid
  fingerprint       = var.fingerprint
  private_key_path  = var.private_key_path
  region            = var.region
  version           = "~> 3.17"

# get latest Oracle Linux 7.7 image
data "oci_core_images" "oraclelinux-7-7" {
  compartment_id = var.compartment_ocid
  operating_system = "Oracle Linux"
  operating_system_version = "7.7"
  filter {
    name = "display_name"
    values = ["^([a-zA-z]+)-([a-zA-z]+)-([\\.0-9]+)-([\\.0-9-]+)$"]
    regex = true

resource "oci_core_instance" "example" {
  count               = 2
  compartment_id      = var.compartment_ocid
  availability_domain = var.availability_domain
  subnet_id           = var.subnet_ocid
  display_name        = "example_TF-1${count.index}"
  image               = lookup(data.oci_core_images.oraclelinux-7-7.images[0], "id")
  shape               = "VM.Standard1.1"

  metadata = {
    ssh_authorized_keys = "${file(var.ssh_public_key_file)}"

then I ran

terraform import oci_core_instance.example <vm_id>

and then if I do
terraform plan
terraform marks the imported machine to be destroyed.
Does anybody know why this is happening ?

Thanks so much

Hi @gibsster,

It looks like your oci_core_instance.example resource has count set, so you’ll need to import the existing object into one of its two instances.

For example, if you want to import into the first of the two, the following command line will do that:

terraform import 'oci_core_instance.example[0]' VM_ID

(I’ve used Unix-shell-style quoting here. If you are using the Windows Command Prompt then omit the ' markers. PowerShell will likely require some different sort of escaping which I can try to figure out if needed.)

The reason Terraform planned to destroy your new instance here is that a resource with count set doesn’t have an “un-keyed” instance (one without an index in [ ] brackets), and so Terraform thinks you’ve just added count and therefore want to replace your single-instance resource with a multi-instance resource. This would be like if you’d initially had a resource block without count set, applied that configuration to create it, and then added count and applied again: once you’ve run terraform import Terraform treats that object as if it had been created by Terraform itself.

@apparentlymart thanks for your quick reply. I tried to run your command as directed and I got this

$ terraform import ‘oci_core_instance.example[0]’ ocid1.instance.oc1.iad.anuwcljsaqwyx5yc4impngdsduuwviefwazzg37rwew347bkgdcgisavdr5a
oci_core_instance.example[0]: Importing from ID “ocid1.instance.oc1.iad.anuwcljsaqwyx5yc4impngdsduuwviefwazzg37rwew347bkgdcgisavdr5a”…
oci_core_instance.example[0]: Import prepared!
Prepared oci_core_instance for import

Error: Resource already managed by Terraform

Terraform is already managing a remote object for
oci_core_instance.example[0]. To import to this address you must first remove
the existing object from the state.

Which makes sense since an object in that position ‘oci_core_instance.example[0]’ already exists. So I ran this command instead

$ terraform import ‘oci_core_instance.example[3]’ ocid1.instance.oc1.iad.anuwcljsaqwyx5yc4impngdsduuwviefwazzg37rwew347bkgdcgisavdr5a
oci_core_instance.example[3]: Importing from ID “ocid1.instance.oc1.iad.anuwcljsaqwyx5yc4impngdsduuwviefwazzg37rwew347bkgdcgisavdr5a”…
oci_core_instance.example[3]: Import prepared!
Prepared oci_core_instance for import
oci_core_instance.example[3]: Refreshing state… [id=ocid1.instance.oc1.iad.anuwcljsaqwyx5yc4impngdsduuwviefwazzg37rwew347bkgdcgisavdr5a]

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.

Now when I do terraform show I see four objects

oci_core_instance.example[0], oci_core_instance.example[1], oci_core_instance.example[2], oci_core_instance.example[3]

which I think it’s correct since before my VM imported was not part of the list.
So I tried to run terraform plan and got this :slightly_frowning_face:

$ 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.

data.oci_core_images.oraclelinux-7-7: Refreshing state…
oci_core_instance.example[2]: Refreshing state… [id=ocid1.instance.oc1.iad.anuwcljsaqwyx5yc4nyber37ny72vt5oytmnud4ijysvew3g7cr62qs7jxja]
oci_core_instance.example[1]: Refreshing state… [id=ocid1.instance.oc1.iad.anuwcljsaqwyx5ycu6alxlyxtefsscwyn2dbklzi3yqtxzbxgtik4guulzia]
oci_core_instance.example[0]: Refreshing state… [id=ocid1.instance.oc1.iad.anuwcljsaqwyx5yceapqrvq52q6ydikkkpgghb3d6gzngy4g3tb4kbmslhza]
oci_core_instance.example[3]: Refreshing state… [id=ocid1.instance.oc1.iad.anuwcljsaqwyx5yc4impngdsduuwviefwazzg37rwew347bkgdcgisavdr5a]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy

Terraform will perform the following actions:

# oci_core_instance.example[3] will be destroyed

oci_core_instance.example[3] is the one I added.

Hi @gibsster,

This seems like your resource still has count = 3 set, and so Terraform can see that there are more instances than the configuration calls for and plans to delete one to fix that. If so, you can change it to count = 4 to declare that you are expecting an instance index 3, and then Terraform should not plan to destroy it.