Terraform配置未将其他文件的输出用于已创建的资源,而是尝试重新创建它并失败(安全组ID) [英] Terraform config isn't using output from other file for already created resource, instead tries to recreate it and fails (security group id)

查看:180
本文介绍了Terraform配置未将其他文件的输出用于已创建的资源,而是尝试重新创建它并失败(安全组ID)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在terraform/aws/global/vpc/security_groups.tf中,我具有以下代码来创建我的堡垒安全组,以及下面的output.tf文件.但是在terraform/aws/layers/bastion/main.tf(也在下面的代码中)中,我引用了该安全组,因为我需要它的安全组ID来创建我的EC2实例,所以我遇到的问题是,不是从已经存在的ID中获取ID.由/vpc/security_groups.tf配置创建的现有安全组,它尝试创建整个安全组,并且运行显然失败,因为它已经存在.如何更改代码以获取现有SG的ID?我不想在与实例相同的配置文件中创建SG,因此我的一些安全组在不同的资源之间共享.我正在使用Terraform Cloud,VPC具有自己的工作区,所以我认为这实际上可能是状态不同的问题.是否可以解决此问题?

In terraform/aws/global/vpc/security_groups.tf I have the below code to create my bastion security group, and the output.tf file as well which is below. But in terraform/aws/layers/bastion/main.tf (code also below) I reference that security group as I need its security group ID to create my EC2 instance, the issue I have is that rather than getting the ID from the already existing security group created by the /vpc/security_groups.tf config it tries to create the whole security group and the run obviously fails because it already exists. How can I change my code to get the ID of the existing SG? I don't want to create my SG in the same config file as my instance, some of my security groups are shared between different resources. I am using Terraform Cloud and VPC has its own workspace, so I assume this could actually be an issue with the states being different.. is there a work around for this?

terraform/aws/global/vpc/security_groups.tf

    provider "aws" {
    region = "eu-west-1"
}

resource "aws_security_group" "bastion" {
  name        = "Bastion_Terraform"
  description = "Bastion SSH access Terraform"
  vpc_id      = "vpc-12345"

  ingress {
    description = "Bastion SSH"
    from_port   = ##
    to_port     = ##
    protocol    = "##"
    cidr_blocks = ["1.2.3.4/56"]
  }
  ingress {
    description = "Bastion SSH"
    from_port   = ##
    to_port     = ##
    protocol    = "##"
    cidr_blocks = ["1.2.3.4/0"]    
  }
  egress {
    description = "Access to "
    from_port   = ##
    to_port     = ##
    protocol    = "tcp"
    security_groups = ["sg-12345"]
  }
  egress {
    description = "Access to ##"
    from_port   = ##
    to_port     = ##
    protocol    = "tcp"
    security_groups = ["sg-12345"]
  }

  tags = {
    Name = "Bastion Terraform"
  }
}

terraform/aws/global/vpc/outputs.tf

output "bastion-sg" {
  value = aws_security_group.bastion.id
}

地形/aws/layers/bastion/main.tf

    provider "aws" {
    region = var.region
}

module "vpc" {
    source = "../../global/vpc"
}

module "ec2-instance" {
    source = "terraform-aws-modules/ec2-instance/aws"

    name = "bastion"
    instance_count = 1
    ami = var.image_id
    instance_type = var.instance_type
    vpc_security_group_ids = ["${module.vpc.bastion-sg}"]
    subnet_id = var.subnet
    iam_instance_profile = var.iam_role

    tags = {
        Layer = "Bastion"
    }
}

推荐答案

当TF模块中有这样的子模块块时:

When you have a child module block like this in a TF module:

module "ec2-instance" {
    source = "terraform-aws-modules/ec2-instance/aws"

    name = "bastion"
    instance_count = 1
    ami = var.image_id
    instance_type = var.instance_type
    vpc_security_group_ids = ["${module.vpc.bastion-sg}"]
    subnet_id = var.subnet
    iam_instance_profile = var.iam_role

    tags = {
        Layer = "Bastion"
    }
}

它不仅引用该子模块,而且还实例化了一个仅对父模块及其状态唯一的全新实例.认为这不像是分配或指针,而是构造模块的全新实例(使用模块作为模板),并重新创建其所有资源.

It doesn't just reference that child module, it instatiates a completely new instance of it unique only to the parent module and its state. Think of this not like an assignment or a pointer but the construction of a whole new instance of the module (using the module as a template) with all of its resources created again.

您将需要直接在具有模块块的父模块中引用子模块的输出,或者需要使用terraform_remote_state数据源或Terragrunt依赖项从状态文件加载输出.

You will need to either directly reference the outputs of the child module in the parent module that has its module block or you will need to use a terraform_remote_state data source or Terragrunt dependency to load the outputs from the state file.

这篇关于Terraform配置未将其他文件的输出用于已创建的资源,而是尝试重新创建它并失败(安全组ID)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆