Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to launch ECs in an existing VPC using Terraform

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}"
}
like image 307
user389955 Avatar asked Dec 06 '17 01:12

user389955


3 Answers

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 variables

like image 165
Rick Baker Avatar answered Nov 04 '22 22:11

Rick Baker


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
like image 25
zied marouani Avatar answered Nov 04 '22 22:11

zied marouani


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"
}
like image 1
Andy Al Avatar answered Nov 04 '22 20:11

Andy Al