0

I'm brand new to terraform, and I'm utilizing terragrunt to help me get things rolling. I have a decent amount of infrastructure to migrate and get set up w/ terraform, but I'm getting my feet underneath me first. We have multiple VPC's in different regions with a lot of the same security group rules used i.e.(web, db, etc..) that I want to replicate across each region.

I have a simple example of how I currently have an EC2 module setup to recreate the security group rules and was wondering if there's a better way to organize this code so I don't have to create a new module for the same SG rule for each region? i.e. some smart way to utilize lists for my vpc's, providers, etc...

since this is just one SG rule across two regions, I'm trying to avoid this growing ugly as we scale up to even more regions and I input multiple SG rules

My state is currently being stored in S3 and in this setup I pull the state so I can access the VPC outputs from another module I used to create the VPC's

terraform {
  backend "s3" {}
}

provider "aws" {
  version = "~> 1.31.0"
  region  = "${var.region}"
  profile = "${var.profile}"
}

provider "aws" {
  version = "~> 1.31.0"
  alias  = "us-west-1"
  region = "us-west-1"
  profile = "${var.profile}"
}

#################################
# Data sources to get VPC details
#################################

data "terraform_remote_state" "vpc" {
  backend = "s3"

  config {
    bucket = "${var.vpc_remote_state_bucket}"
    key    = "${var.vpc_remote_state_key}"
    region = "${var.region}"
    profile = "${var.profile}"
  }
}

#####################
# Security group rule
#####################

module "east1_vpc_web_server_sg" {
  source = "terraform-aws-modules/security-group/aws"
  version = "2.5.0"

  name        = "web-server"
  description = "Security group for web-servers with HTTP ports open within the VPC"
  vpc_id      = "${data.terraform_remote_state.vpc.us_east_vpc1_id}"

  # Allow VPC public subnets to talk to each other for API's
  ingress_cidr_blocks = ["${data.terraform_remote_state.vpc.us_east_vpc1_public_subnets_cidr_blocks}"]
  ingress_rules       = ["https-443-tcp", "http-80-tcp"]

  # List of maps
  ingress_with_cidr_blocks = "${var.web_server_ingress_with_cidr_blocks}"

  # Allow engress all protocols to outside
  egress_rules = ["all-all"]

  tags = {
    Terraform = "true"
    Environment = "${var.environment}"
  }
}

module "west1_vpc_web_server_sg" {
  source = "terraform-aws-modules/security-group/aws"
  version = "2.5.0"

  providers {
    aws = "aws.us-west-1"
  }

  name        = "web-server"
  description = "Security group for web-servers with HTTP ports open within the VPC"
  vpc_id      = "${data.terraform_remote_state.vpc.us_west_vpc1_id}"

  # Allow VPC public subnets to talk to each other for API's
  ingress_cidr_blocks = ["${data.terraform_remote_state.vpc.us_west_vpc1_public_subnets_cidr_blocks}"]
  ingress_rules       = ["https-443-tcp", "http-80-tcp"]

  ingress_with_cidr_blocks = "${var.web_server_ingress_with_cidr_blocks}"

  # Allow engress all protocols to outside
  egress_rules = ["all-all"]

  tags = {
    Terraform = "true"
    Environment = "${var.environment}"
  }
}
veilig
  • 5,085
  • 10
  • 48
  • 86

1 Answers1

0

Your current setup uses two times the same module differing in the provider. You can pass down multiple providers to the module (see the documentation). Then, within the module, you can use the same variables you specified once in your main document to create all the instances you need.

However, since you are using one separate provider for each resource type, you have to have at least some code duplication down the line.

Your code could then look something like this

module "vpc_web_server_sg" {
  source = "terraform-aws-modules/security-group/aws"
  version = "2.5.0"

  providers {
    aws.main = "aws"
    aws.secondary = "aws.us-west-1"
  }

  name        = "web-server"
  description = "Security group for web-servers with HTTP ports open within the VPC"
  vpc_id      = "${data.terraform_remote_state.vpc.us_west_vpc1_id}"

  # Allow VPC public subnets to talk to each other for API's
  ingress_cidr_blocks = ["${data.terraform_remote_state.vpc.us_west_vpc1_public_subnets_cidr_blocks}"]
  ingress_rules       = ["https-443-tcp", "http-80-tcp"]

  ingress_with_cidr_blocks = "${var.web_server_ingress_with_cidr_blocks}"

  # Allow engress all protocols to outside
  egress_rules = ["all-all"]

  tags = {
    Terraform = "true"
    Environment = "${var.environment}"
  }
}

Inside your module you can then use the main and secondary provider to deploy all your required resources.

Markus
  • 684
  • 5
  • 11