Reputation: 928
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
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