terraform如何知道应该首先运行哪种资源来提升基础架构?

时间:2019-06-19 19:20:54

标签: terraform terraform-provider-aws

我正在使用Terraform启动Aws-DMS。要启动DMS,我们需要子网组,dms复制任务,dms端点,dms复制实例。我已经使用terraform文档配置了所有内容。我的问题是,terraform将如何知道首先完成哪个任务以启动其他依赖项任务? 我们需要在terraform中的某个地方声明它还是terraform足够智能以进行相应的运行?

3 个答案:

答案 0 :(得分:2)

Terraform使用配置中的引用来推断顺序。

考虑以下示例:

resource "aws_s3_bucket" "example" {
  bucket = "terraform-dependencies-example"
  acl    = "private"
}

resource "aws_s3_bucket_object" "example" {
  bucket  = aws_s3_bucket.example.bucket # reference to aws_s3_bucket.example
  key     = "example"
  content = "example"
}

在上面的示例中,aws_s3_bucket_object.example资源包含一个引用aws_s3_bucket.example.bucket的表达式,因此Terraform可以推断出aws_s3_bucket.example必须在aws_s3_bucket_object.example之前创建。


这些由引用创建的隐式依赖关系是在Terraform中创建排序的主要方法。在极少数情况下,我们需要表示不能由表达式推断的依赖项,因此,仅在那些例外情况下,我们可以使用depends_on元参数添加其他显式依赖项。

一种可能发生的情况是AWS IAM策略,其中由引用自然创建的图将倾向于具有以下形状:

both aws_lambda_function and aws_iam_role_policy depend only on aws_iam_role

由于AWS IAM的数据模型,我们必须首先创建一个角色,然后为它分配策略作为一个单独的步骤,但是承担该角色的对象(例如,在本例中为AWS Lambda函数)仅采用一个引用角色本身,而不是策略。借助引用隐式创建的依赖关系,Lambda函数可能会在其角色具有所需访问权限之前创建,如果该函数在分配策略之前尝试采取任何措施,则会导致错误。

要解决此问题,我们可以在depends_on资源块中使用aws_lambda_function来强制这种额外的依赖关系,从而创建正确的执行顺序:

resource "aws_iam_role" "example" {
  # ...
}

resource "aws_iam_role_policy" "example" {
  # ...
}

resource "aws_lambda_function" "exmaple" {
  depends_on = [aws_iam_role_policy.example]
}

Now the aws_lambda_function also depends on the aws_iam_role_policy


有关Terraform中的资源依赖关系的更多信息,请参见Terraform文档中的Resource Dependencies

答案 1 :(得分:1)

Terraform将按照可以满足所有依赖性的顺序自动创建资源。

例如:如果您在DMS定义中将安全组ID设置为"${aws_security_group.my_sg.id}",则Terraform会识别此依赖性,并在DMS资源之前创建安全组。

答案 2 :(得分:-1)

来自:https://learn.hashicorp.com/terraform/getting-started/dependencies.html 如果不是隐式依赖项,那么您正在寻找depends_on。

# New resource for the S3 bucket our application will use.
resource "aws_s3_bucket" "example" {
  # NOTE: S3 bucket names must be unique across _all_ AWS accounts, so
  # this name must be changed before applying this example to avoid naming
  # conflicts.
  bucket = "terraform-getting-started-guide"
  acl    = "private"
}

# Change the aws_instance we declared earlier to now include "depends_on"
resource "aws_instance" "example" {
  ami           = "ami-2757f631"
  instance_type = "t2.micro"

  # Tells Terraform that this EC2 instance must be created only after the
  # S3 bucket has been created.
  depends_on = [aws_s3_bucket.example]
}