JPNagarajan
JPNagarajan

Reputation: 928

how to create ec2 instances using different subnet and security groups in terraform?

I have 3 different services like valid,jsc,test and i have created 3 different subnets and 3 different security groups for the same.Now i want to crate 3 instances for each service with respective subnet id and security group.How to achieve this?

variable "region" {
  type = string
  default = "ap-south-1"
}



variable "subnet-string" {
  type = map
  default = {
    "valid" = "10.0.1.0/28",
    "jsc" = "10.0.2.0/28",
    "test" = "10.0.3.0/28"
}
}

variable "instance_count" {
  type = string
  default = 3
}

variable "vpc-cidr" {
  type = string
  default = "10.0.0.0/16"
}

variable "az" {
  type = string
  default = "ap-south-1c"
  
}

provider "aws" {
 region = var.region
}


resource "aws_vpc" "ecom-vpc" {
  cidr_block = "10.0.0.0/16"
}

 variable "service-names" {
   type = list
   default = ["valid","jsc","test"]
  
 }




 resource "aws_subnet" "ecom-subnet" {
     vpc_id = aws_vpc.ecom-vpc.id
     for_each = var.subnet-string
     cidr_block = each.value
     map_public_ip_on_launch = false
     availability_zone = var.az

     tags = {
         Name = "${each.key}-service"
     }
  
}



variable "sg_ingress_rules" {
    type = map
    default = {
    "valid" = {
      description = "sg rules for validation service"
      rules = [{
        description = "SSH",
        from_port = 22,
        to_port = 22,
        protocol = "tcp",
        cidr_blocks = ["10.0.0.0/16"],
      },{
        description = "withinvpc",
        from_port = 80,
        to_port = 80,
        protocol = "tcp",
        cidr_blocks = ["10.0.0.0/16"],
      },{
        description = "withinvpc",
        from_port = 27017,
        to_port = 27017,
        protocol = "tcp",
        cidr_blocks = ["10.0.0.0/16"],
      }]
    },
    "jsc" = {
      description = "sg rules for jsclient service"
      rules = [{
        description = "SSH",
        from_port = 22,
        to_port = 22,
        protocol = "tcp",
        cidr_blocks = ["10.0.0.0/16"],
      },{
        description = "withinvpc",
        from_port = 80,
        to_port = 80,
        protocol = "tcp",
        cidr_blocks = ["10.0.0.0/16"],
      },{
        description = "withinvpc",
        from_port = 27017,
        to_port = 27017,
        protocol = "tcp",
        cidr_blocks = ["10.0.0.0/16"],
      }]
     },
      "test" = {
      description = "sg rules for 3ds service"
      rules = [{
        description = "SSH",
        from_port = 22,
        to_port = 22,
        protocol = "tcp",
        cidr_blocks = ["10.0.0.0/16"],
      },{
        description = "withinvpc",
        from_port = 80,
        to_port = 80,
        protocol = "tcp",
        cidr_blocks = ["10.0.0.0/16"],
      },{
        description = "withinvpc",
        from_port = 27017,
        to_port = 27017,
        protocol = "tcp",
        cidr_blocks = ["10.0.0.0/16"],
      }]
    }
  }
}

resource "aws_security_group" "ecom-sg" {
  for_each    = var.sg_ingress_rules

  name        = each.key # top-level key is security group name
  description = each.value.description

  dynamic "ingress" {
    for_each = each.value.rules # List of Maps with rule attributes
    content {
      description = ingress.value.description
      from_port   = ingress.value.from_port
      to_port     = ingress.value.to_port
      protocol    = ingress.value.protocol
      cidr_blocks = ingress.value.cidr_blocks
    }
  }
  tags = {
    "Name" = "sg-${each.key}-service"
  }
}
output "security_groups" {
  value = aws_security_group.ecom-sg
}



data "aws_ami" "ecom" {
  most_recent = true


  owners = ["114712064551"] # Canonical
}

Now i have to create 3 ec2 instances for each valid,jsc,test services.

Trying something like below.But no idea how to acheive this

 resource "aws_instance" "ecom-validation-service" {
  count = length(var.instance_count)
   ami           = data.aws_ami.ecom.id
   instance_type = "t3.micro"
   for_each = toset(var.service-names)

   tags = {
     Name = "${each.value}-service"
   }
   vpc_security_group_ids = [aws_security_group.ecom-sg.*.id,lookup(each.value)]
   subnet_id = ${element(aws_subnet.ecom-subnet.*.id,${lookup(each.value))}
 }

Upvotes: 1

Views: 163

Answers (1)

Marcin
Marcin

Reputation: 238111

You can create a helper variable and use setproduct:

locals {
  helper_map = {for idx, val in setproduct(var.service-names, range(var.instance_count)): 
                   idx => {service_name = val[0]}
               }
}

resource "aws_instance" "ecom-validation-service" {

   for_each      = local.helper_map 

   ami           = data.aws_ami.ecom.id
   instance_type = "t3.micro"

   tags = {
     Name = "${each.value.service_name}-service"
   }
   
   vpc_security_group_ids = [aws_security_group.ecom-sg.*.id, lookup(each.value.service_name)]
   subnet_id = element(aws_subnet.ecom-subnet.*.id, ${lookup(each.value.service_name))
}

Upvotes: 2

Related Questions