簡體   English   中英

我如何從 Terraform 中模塊的 output 中的元組中獲取任何值?

[英]How i get any value from the tuple in output of module in Terraform?

我在 Terraform 中創建了三個模塊,一個用於 EC2、VPC 和安全組。 我為三個模塊運行完整堆棧,並使用安全組的 output 和 EC2 模塊中的 VPC 模塊,但我得到了這個錯誤:

creating EC2 Instance: InvalidSubnetID.NotFound: The subnet ID 'module.vpc_main.primary_private_subnets_id.value[0]' does not exist
        status code: 400, request id: d94befb9-a846-47f9-a7c2-c588996a723c

  on .terraform/modules/main_ec2/main.tf line 66, in resource "aws_instance" "create_instance":
  66: resource "aws_instance" "create_instance" {

VPC模塊的output:

output "primary_public_subnets_id" {
  description = "public subnet ID"
  value       = aws_subnet.primary_public_subnets[*].id
}

output "primary_private_subnets_id" {
  description = "public subnet ID"
  value       = aws_subnet.primary_private_subnets[*].id
}

state 文件中的 output

outputs": {
    "primary_private_subnets_id": {
      "value": [
        "subnet-098d3aab6a102656c",
        "subnet-073699d0e266072d6",
        "subnet-07755f92e02ca8756",
        "subnet-0a2f21a6e9b80d91e"
      ],
      "type": [
        "tuple",
        [
          "string",
          "string",
          "string",
          "string"
        ]
      ]
    },
    "primary_public_subnets_id": {
      "value": [
        "subnet-0aea672a2f19cee51",
        "subnet-0a014df85bc56acd3"
      ],
      "type": [
        "tuple",
        [
          "string",
          "string"
        ]
      ]
    },

變量

variable "subnet_id" {
  type = list(string)
  default = [ "module.vpc_main.primary_public_subnets_id[0]", "module.vpc_main.primary_private_subnets_id[1]" ]
}

EC2模塊部分:

resource "aws_instance" "create_instance" {

  ami = "${element(data.aws_ami.ami_id.*.id, count.index)}"

  instance_type = var.EC2_Type[count.index]

  subnet_id = var.subnet_id[count.index]

  associate_public_ip_address = var.associate_public_ip_address[count.index]

  vpc_security_group_ids = [ var.vpc_security_group_ids[count.index] ]

  key_name = "${local.name}-KP-${var.Server_Name[count.index]}"

  iam_instance_profile = aws_iam_instance_profile.iam_profile.name

  private_ip = var.EC2_IP[count.index]
  count = length(var.ami_name)

}

EC2 調用模塊:

module "main_ec2" {
    source  = "/home/reham/Data/projectes/terraform/modules/EC2Module"
    EC2_Type = var.EC2_Type
    EC2_IP = var.EC2_IP
    subnet_id = var.subnet_id
    associate_public_ip_address = var.associate_public_ip_address
    vpc_security_group_ids = var.vpc_security_group_ids
}

請注意,任何模塊都可以很好地單獨工作。 請問如何從 Terraform 模塊的 output 中的元組中獲取任何值?

如果我們認為 VPC 模塊也被調用,您不必將默認值添加到變量subnet_id 相反,您可以將變量定義保留為沒有任何值:

variable "subnet_id" {
  type = list(string)
}

請注意,您使用的是list(string)類型的變量,而 EC2 實例的參數只需要一個值,因此它是string類型。 此外,在 EC2 模塊中,您將count元參數設置為取決於變量ami_name的長度。 因此,即使您要進行正確的價值分配,我認為您也會得到很多意想不到的結果。 在對 EC2 模塊進行任何調用之前,我建議將其修復為看起來更像:

resource "aws_instance" "create_instance" {
  count                       = length(var.subnet_id)
  ami                         = element(data.aws_ami.ami_id.*.id, count.index)
  instance_type               = var.EC2_Type[count.index]
  subnet_id                   = var.subnet_id[count.index]
  associate_public_ip_address = var.associate_public_ip_address[count.index]
  vpc_security_group_ids      = [var.vpc_security_group_ids[count.index]]
  key_name                    = "${local.name}-KP-${var.Server_Name[count.index]}"
  iam_instance_profile        = aws_iam_instance_profile.iam_profile.name
  private_ip                  = var.EC2_IP[count.index]
}

將元參數移動到resource塊的頂部也是一個很好的做法,因為它對讀者更可見。 我已將count設置為使用subnet_id變量的長度,因為我猜您希望每個子網中都有一個 EC2 實例。

另一件不清楚的事情是,如果您想在私有子網、公共子網或兩者中擁有 EC2 實例。 為簡單起見,假設您希望它們在公共子網中(因為您定義了associate_public_ip_address參數。這里您犯了另一個錯誤,即嘗試設置一個bool參數(它只能具有truefalse值)以使用一個帶有count.index的變量( var.associate_public_ip_address[count.index] )。除非您的associate_public_ip_address是 boolean 值的列表,否則這也不起作用。如果是這樣,該代碼可以保持不變。最后但並非最不重要的,因為VPC 模塊提供您想要的輸出,使用這些輸出的方法如下:

module "vpc" {
 ... your module call goes here ...
}

module "main_ec2" {
  source                      = "/home/reham/Data/projectes/terraform/modules/EC2Module"
  EC2_Type                    = var.EC2_Type
  EC2_IP                      = var.EC2_IP
  subnet_id                   = module.vpc.primary_public_subnets_id
  associate_public_ip_address = var.associate_public_ip_address
  vpc_security_group_ids      = var.vpc_security_group_ids
}

此外,如果 VPC 模塊提供了其他輸出(例如,安全組 ID),您可以將其稱為與子網 ID 相同的名稱:

module.vpc.<name of the output>

即使有我回答中的詳細信息,也不能保證它會起作用。 要使代碼正常工作,需要進行大量重構。 此外,我強烈建議了解資源期望( stringlist(string)bool等)中值 arguments 的類型 [1]。 您還需要確保您了解如何引用模塊輸出 [2]。


[1] https://www.terraform.io/language/expressions/types

[2] https://www.terraform.io/language/expressions/references#child-module-outputs

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM