如何依次运行Terraform代码?

时间:2019-04-24 10:15:24

标签: amazon-web-services terraform

我正在尝试围绕AWS基础设施设置一些自动化。刚遇到有关模块依赖性的一个问题。由于在terraform中没有“包含”类型的选项,因此实现我的目标变得越来越困难。

这是场景的简短描述:

在我的根目录中,有一个文件main.tf

,由多个模块块组成 例如。

module mytest1
{
source = mymod/dev
}

module mytest2
{
source = mymod2/prod
}

每个开发人员和生产人员都有很多tf文件 prod目录中存在的我的.tf文件很少需要dev目录中存在的资源的一些输出

由于模块没有依赖性,我在想是否有任何顺序运行模块的方法或任何其他想法?

3 个答案:

答案 0 :(得分:0)

不能完全确定您的用例,以使产品和开发人员需要按照您所说的方式进行交互。

我希望您可能具有以下文件夹结构:

  • 文件夹1:开发人员(包含开发人员模块)
  • 文件夹2:产品(包含产品模块)
  • 文件夹3:资源(包含可用于dev和prod模块的通用资源块)

然后,当您为文件夹1运行terraform apply时,它将通过将变量从模块传递到资源(在文件夹3中)来创建开发基础结构。

当您为文件夹2运行terraform apply时,它将通过将变量从模块传递到资源(在文件夹3中)来创建产品基础结构。

如果由于某种原因而无法执行此操作,则输出变量或数据源可能会帮助您检索所需的信息。

答案 1 :(得分:0)

您没有理由为不同的环境使用不同的模块。通常,较低的env和prod之间的区别是每种资源的数量和层,您可以使用变量将其传递到模块内部。

为此,您可以使用terraform workspaces并为每个环境创建一个工作区,例如:

terraform worskspace new staging

这将创建一个具有其自身状态的全新工作区。如果需要定义要创建的资源数量,则可以使用变量s或terraform工作区名称本身,例如:

# Your EC2 Module
"aws_instance" "example" {
    count = "${terraform.workspace == "prod" ? 3 : 1}"
}

# or

"aws_instance" "example" {
    count = "${lenght(var.subnets)}" # you are likely to have more subnets for prod
}


# Your module
module "instances" {
source = "./modules/ec2"
subnets = "my subnets list"
}

就是这样,只需创建工作空间并更改管道中每个变量的变量并每次应用计划,就可以使所有模块都适用于任何环境。

You can read more about workspaces here

答案 2 :(得分:0)

我不太确定您的要求生产环境取决于开发环境,但是撇开细节,在Terraform中在资源之间和模块之间创建排序的惯用方式是使用引用表达式。

您没有说生产环境占用了开发环境的哪个方面,但是为了举例说明,我们假设生产环境需要在开发环境中创建的VPC的ID。在这种情况下,开发模块会将该VPC ID导出为输出值:

# (this goes within a file in your mymod/dev directory)
output "vpc_id" {
  value = "${aws_vpc.example.id}"
}

然后,您的生产模块将具有一个输入变量来指定此内容:

# (this goes within a file in your mymod2/prod directory)
variable "vpc_id" {
  type = "string"
}

有了这些,您的父模块就可以在两者之间传递值以建立您要查找的依赖项:

module "dev" {
  source = "./mymod/dev"
}

module "prod" {
  source = "./mymod2/prod"

  vpc_id = "${module.dev.vpc_id}"
}

之所以有效,是因为它创建了以下依赖项链:

module.prod's input variable vpc_id depends on
module.dev's output value vpc_id, which depends on
module.dev's aws_vpc.example resource

然后,您可以在生产模块内的任何位置使用var.vpc_id来获取该VPC ID,这将在该依赖项链中创建另一个链接,告诉Terraform在执行任何依赖于该操作的操作之前,它必须等到VPC创建完成VPC存在。

尤其要注意,参与依赖性链的是各个变量和输出,而不是整个模块。这意味着如果prod模块中有任何资源不需要需要VPC存在,那么Terraform可以立即开始创建它们,而无需等待开发模块首先完全完成,同时仍然确保在完成需要所需的任何操作之前,完成VPC的创建。

文档部分Module Composition中提供了有关此模式的更多信息。它是使用Terraform v0.12语法和功能编写的,但是,如果您使用v0.11语法和功能来表示它,则通用模式仍然适用于早期版本,就像我在上面的示例中所做的那样。