【问题标题】:Terraform - Use security group ID created in separate file for EC2 instance creationTerraform - 使用在单独文件中创建的安全组 ID 来创建 EC2 实例
【发布时间】:2020-10-09 17:18:27
【问题描述】:

我使用this 模块在 AWS VPC 中创建了一个安全组。如何在单独的文件中引用由此创建的资源?我正在同一个 repo 的单独目录中创建我们的堡垒实例。

我的堡垒配置如下所示,使用 Terraform EC2 模块,如果我硬编码 vpc 安全组 ID,它就可以工作,但我希望它能够直接从创建安全组时获取它,因为这可能会改变未来..

terraform/aws/layers/bastion/main.tf

    provider "aws" {
        region = var.region
    }

    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 = ["${}"]
      subnet_id              = var.subnet
      iam_instance_profile   = "aws-example-ec2-role"

      tags = {
        Layer = "Bastion"
      }
    }

这就是我创建安全组的方式: terraform/aws/global/vpc/bastion_sg.tf

        module "bastion-sg" {
          source = "terraform-aws-modules/security-group/aws"
    
      name        = "Bastion"
      description = "Bastion example group"
      vpc_id      = "vpc-12345"
    
      ingress_with_cidr_blocks = [
        {
          from_port   = ##
          to_port     = ##
          protocol    = "##"
          description = "Bastion SSH"
          cidr_blocks = "1.2.3.4/5"
        },
        {
          from_port   = ##
          to_port     = ##
          protocol    = "##"
          description = "Bastion SSH"
          cidr_blocks = "1.2.3.4/5"
        }
      ]
      egress_with_source_security_group_id = [
        {
          from_port                = ##
          to_port                  = ##
          protocol                 = "##"
          description              = "Access to default server security group"
          source_security_group_id = "sg-12345"
        },
        {
          from_port                = ##
          to_port                  = ##
          protocol                 = "##"
          description              = "Access to db"
          source_security_group_id = "sg-12345"      
        }
      ]
    }

我是否需要将安全组 ID 输出到由 bastion_sg.tf 创建的 outputs.tf,然后才能在 bastion/main.tf 中引用它,如下所示?

    module "bastion_sg"
        source "../../global/vpc"

然后以某种方式将 ID 传递给 vpc_security_group_id = ?

【问题讨论】:

  • 您好,您当前如何存储状态,是项目本地还是远程,例如 S3 文件夹?
  • @einonsy 嗨,它在 terraform 云中,如此遥远。

标签: amazon-web-services amazon-ec2 terraform aws-security-group infrastructure-as-code


【解决方案1】:

我不会使用 terraform-aws-modules。我会直接使用 aws_security_group 和 aws_security_group_rules 等 aws 提供程序资源。从 Terraform 0.12 开始,这些单资源模块没有任何好处,只是增加了复杂性。

这是一个示例,说明您的代码可以使用直接的 aws 提供程序资源并且没有多余的模块:

provider "aws" {
    region = var.region
}

resource "aws_instance" "bastion" {
  name                   = "bastion"
  ami                    = var.image_id
  instance_type          = var.instance_type
  vpc_security_group_ids = [aws_security_group.bastion.id]
  subnet_id              = var.subnet
  iam_instance_profile   = "aws-example-ec2-role"

  tags = {
    Layer = "Bastion"
  }
}

resource "aws_security_group" "bastion_from_ssh" {
  name        = "Bastion"
  description = "Bastion example group"
  vpc_id      = "vpc-12345"
}

resource "aws_security_group_rule" "allow_ssh" {
  type                     = "ingress"
  from_port   = ##
  to_port     = ##
  protocol    = "##"
  description = "Bastion SSH"
  cidr_blocks = ["1.2.3.4/5"]
}

resource "aws_security_group_rule" "bastion_to_db" {
  type                     = "egress"
  from_port                = ##
  to_port                  = ##
  protocol                 = "##"
  description              = "Access to default server security group"
  source_security_group_id = "sg-12345"
}

output "security_group_id" {
    value = aws_security_group.bastion_from_ssh.id
}

示例:引用另一个模块中的输出:

module "bastion" {
   source = "path/to/dir/with/code/above"
   // ... any variables it needs
}

resource "aws_security_group" "app_server" {
  name        = "AppServer"
  description = "App Server group"
  vpc_id      = "vpc-12345"
}

resource "aws_security_group_rule" "allow_ssh_to_app_server" {
  security_group_id = module.bastion.security_group_id
  type = "egress"

  from_port   = 22
  to_port     = 22
  protocol    = "tcp"
  description = "SSH to App Server"
  source_security_group_id = aws_security_group.app_server.id
}

resource "aws_security_group_rule" "allow_ssh_from_bastion" {
  security_group_id = aws_security_group.app_server.id
  type = "ingress"

  from_port   = 22
  to_port     = 22
  protocol    = "tcp"
  description = "SSH from Bastion"
  source_security_group_id = module.bastion.security_group_id
}

【讨论】:

  • 您好,感谢您的回复。但是如果安全组被其他实例使用怎么办?如果规则相同,我不想为每个实例类型创建一个安全组
  • 哦,这里也完全涵盖了。您可以在多个实例上引用相同的安全组。那是一个单独的问题。如果您想进一步探索它,请发布一个单独的问题并将我链接到此处。
  • @cjspencer 我可以看看后续问题。如果这个答案适用于这个问题,请接受它作为正确答案。
  • 从技术上讲,它目前还不能正常工作,但如果我能够在 Terraform 中创建一个可以在单独的配置文件中使用的安全组,那么它就可以工作
【解决方案2】:

在您使用的模块文档中,这些是outputs

reference them in your own terraform 的方法是:

module.bastion-sg.this_security_group_id

所以你的terraform/aws/layers/bastion/main.tf 文件看起来像:

provider "aws" {
    region = var.region
}

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.bastion-sg.this_security_group_id]
  subnet_id              = var.subnet
  iam_instance_profile   = "aws-example-ec2-role"

  tags = {
    Layer = "Bastion"
  }
}

【讨论】:

  • 感谢您的响应,当我尝试运行 terraform plan 时出现错误:在模块“ec2-instance”中的 main.tf 第 12 行引用未声明的模块:12:vpc_security_group_ids = [module.tf] bastion-sg.this_security_group_id] 没有在根模块中声明名为“bastion-sg”的模块调用。所以我然后将它添加到 bastion/main.tf: module "bastion-sg" { source = "../../global/vpc" }
  • 我现在得到的错误是:在 main.tf 第 16 行,在模块“ec2-instance”中:16: vpc_security_group_ids = [module.bastion-sg.this_security_group_id] 一个输出值,名称为“this_security_group_id”尚未在 module.bastion-sg 中声明。
猜你喜欢
  • 2021-07-28
  • 2020-10-07
  • 2019-02-23
  • 2019-11-21
  • 2021-08-19
  • 1970-01-01
  • 2020-07-19
  • 2020-11-30
  • 2021-11-17
相关资源
最近更新 更多