0

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"
}
cjspencer
  • 77
  • 1
  • 6
  • This question is too broad to answer as is since the other TF configs are not supplied, so I will link to the relevant documentation that explains how to do this in general: https://www.terraform.io/docs/providers/aws/r/security_group.html#attributes-reference – Matthew Schuchard Jun 22 '20 at 12:50
  • this is the link to my original question: https://stackoverflow.com/questions/62470490/terraform-use-security-group-id-created-in-separate-file-for-ec2-instance-crea/62480424?noredirect=1#comment110553471_62480424 I have used modules but someone suggested in the replies to make this one. – cjspencer Jun 22 '20 at 12:58
  • So you refactored from single-resource modules to this, which is good. However, my comment still stands: the question is too broad to answer as is, so please either update with the requested information, or use the documentation I provided to move forward. Also note there is no difference in your situation between same config file or different config file. – Matthew Schuchard Jun 22 '20 at 13:43
  • Hi, thanks for getting back to me - since posting I have changed things around a bit and got it working although ran into a different issue which I believe may be due to Terraform Cloud having different state files for each workspace.. do you mind having a quick look and see if you have any suggestions / work arounds? https://stackoverflow.com/questions/62515965/terraform-config-isnt-using-output-from-other-file-for-already-created-resource – cjspencer Jun 22 '20 at 13:59

2 Answers2

1

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
}
Alain O'Dea
  • 21,033
  • 1
  • 58
  • 84
0

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.

saurabh14292
  • 1,281
  • 2
  • 10
  • 12
  • Thanks for the response, I am using a terraform security group module but I cannot get the output to work.. original post https://stackoverflow.com/questions/62470490/terraform-use-security-group-id-created-in-separate-file-for-ec2-instance-crea/62480424?noredirect=1#comment110553471_62480424 – cjspencer Jun 22 '20 at 12:59
  • in terraform/aws/global/vpc/security_groups.tf I have created a security group, I then reference it within terraform/aws/layers/bastion/main.tf with ["${module.vpc.bastion-sg}"] but rather than use the output from the already created sg it tries to create the security group again? – cjspencer Jun 22 '20 at 13:30