cjspencer
cjspencer

Reputation: 77

How do I create a AWS security group and use it in different .tf files?

As the title says, if I'm using terraform/aws/layers/bastion/main.tf to create an EC2 instance, I know I can also create a security group within this same main.tf file for the bastion instance to use, but what if I wanted to create a security group that can be used in a different file?

For example, if terraform/aws/layers/worker/main.tf needed to use the same security group as bastion/main.tf how would I go about this?

bastion/main.tf

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" {
  from_port   = ##
  to_port     = ##
  protocol    = "##"
  description = "Bastion SSH"
  cidr_blocks = ["1.2.3.4/5"]
}

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

Upvotes: 0

Views: 1554

Answers (2)

Alain O'Dea
Alain O'Dea

Reputation: 21706

Declare an output in the module who's security group ID you want to expose and use in other modules:

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

Example: Referencing the output in another module:

module "bastion" {
   source = "path/to/bastion/dir"
   // ... 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
}

Upvotes: 1

saurabh14292
saurabh14292

Reputation: 1401

You can use "modules" to group together shared resources and then call them from your .tf file.

Another alternative is, if feasible, in .tf file where required Security Group is generated, output its required attributes such as ID. Use S3 backend to store the tfstate of this stack. Now, in other stacks where this Security Group is required, use the tfstate as Data to fetch the ID of that Security Group.

Upvotes: 0

Related Questions