有没有一种方法可以合并terraform变量以在多个AWS区域中使用同一模块?

时间:2018-09-17 15:27:01

标签: terraform terragrunt

我是terraform的新手,并且我正在利用terragrunt来帮助我使事情进展。我有相当数量的基础架构可以迁移并使用terraform进行设置,但是首先要站在我的脚下。我们在不同的区域中有多个VPC,并且使用了许多我想在每个区域中复制的相同的安全组规则(即(web,db等)。

我有一个简单的示例,说明我目前如何设置EC2模块来重新创建安全组规则,并且想知道是否有更好的方法来组织此代码,因此我不必为同一SG创建新模块每个区域的规则?即一些巧妙的方式来为我的vpc,提供商等使用列表...

由于这只是两个地区的一条SG规则,因此在我们扩大到更多地区并输入多个SG规则时,我试图避免这种丑陋的发展

我的状态当前存储在S3中,在此设置中,我拉状态,以便可以访问用于创建VPC的另一个模块的VPC输出

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}"
  }
}

1 个答案:

答案 0 :(得分: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.