10

I need to create several new EC2, RDS, etc.using Terraform, in an existing AWS VPC. and the existing subnet, security group, iam, etc. they are not created by Terraform. it is created manually.

I heard the right way is to use terraform import (it is correct?). To test how terraform import works, I first tested how to import an existing EC2 in stead of an existing VPC, Because I do not want to accidentally change anything In an exist VPC.

before running

terraform import aws_instance.example i-XXXXXXXXXX

It looks like I need to create a very detailed EC2 resource in my ec2.tf file, such as:

resource "aws_instance" "example" {
  iam_instance_profile = XXXXXXXXXX
  instance_type = XXXXXXX
  ami = XXXXXXX
  tags {
    Name = XXXXX
    Department = XXXX
    ....
  }
} 

if I just write:

resource "aws_instance" "example" {
}

it showed I missed ami and instance type,

if I write:

resource "aws_instance" "example" {
  instance_type = XXXXXXX
  ami = XXXXXXX
}

then running "terraform apply" will change tags of my existing EC2 to nothing, change iam profile to nothing.

I have not tried how to import existing vpc, subnet, security group yet. I am afraid if I try, I have to put a lot of information of the existing vpc, subnet, security group, etc. my system is complex.

is it expected that I need to indicate so many details in my terraform code? isn't there a way so that I just simply indicate the id of existing stuff like vpc's id, and my new stuff will be created based on the existing id? sth. like:

data "aws_subnet" "public" {
    id = XXXXXXX
}

resource "aws_instance" "example" {
  instance_type = "t2.micro"
  ami = "${var.master_ami}"
  ......
  subnet_id = "${aws_subnet.public.id}"
}
user389955
  • 9,605
  • 14
  • 56
  • 98

3 Answers3

24

You can leave the body of the resource blank during the import, but you'll need to go back in and fill in the specific details once it's been imported. You can look at the imported resource with the terraform show command, and fill in all of the resource details, so when you try to run terraform plan it should show no changes needed.

But, to answer your question, yes you can use your existing resources without having to import them. Just create a variables file that holds your existing resource ids that you need for your new resources, and then you can then reference the ones you need.

So you could have a .vars file with something like:

variable "ami_id" {
  description = "AMI ID"
  default = "ami-xxxxxxxx"
}

variable "subnet_prv1" {
  description = "Private Subnet 1"
  default = "subnet-xxxxxx"
}

Then in your main.tf to create the resource:

resource "aws_instance" "example" {
   instance_type = "t2.micro"
   ami = "${var.ami_id}"
   ......
   subnet_id = "${var.subnet_prv1}"
}

Just one way to go about it. There are others, which you can read up on in the terraform docs for AWS variables

Uberhumus
  • 921
  • 1
  • 13
  • 24
Rick Baker
  • 873
  • 11
  • 22
  • 2
    Thanks Rick. it works. so in summary, if I need to changed the existing vpc (which is manually created) using terraform, I should import first, but if I want to create new components from the existing vpc, then I will use the second solution you posted. Thx. – user389955 Dec 06 '17 at 22:40
  • This was very helpful about variables to me: https://stackoverflow.com/a/62697711/2550985 – rmsys Oct 28 '21 at 12:30
3

Just use this with your vpc data

resource "aws_vpc" "main" {
  cidr_block = "XXXXXXXXXX"
}

then run cmd with existing vpc id:

$ terraform import aws_vpc.main VPC_ID
1

For using existing VPC you can create a new subnet and define the ip range for this subnet. For example, for VPC with cdir 10.10.0.0/16 we can do the next:

resource "aws_subnet" "pre_exist_vpc" {
    vpc_id = "id_of_existing_vpc"
    cidr_block = "10.10.10.0/24"
}

resource "aws_instance" "test_ec2" {
    ami = "ami-033b95fb8079dc481"
    instance_type = "t2.micro"
    subnet_id = aws_subnet.exist_vpc.id
}

And the second option - using an existing subnet of necessary VPC:

resource "aws_instance" "test_ec2" {
    ami = "ami-033b95fb8079dc481"
    instance_type = "t2.micro"
    subnet_id = "id of existing subnet"
}
Andy Al
  • 29
  • 5