Feed multiple SG IDs to AWS Security Group Rule (Request design pattern help)

1,111 views
Skip to first unread message

p

unread,
Apr 4, 2016, 1:33:22 AM4/4/16
to Terraform
Hello everyone,

Can you please help me incant a terraform module where I can feed multiple security group IDs to a "Security Group Rule". I am trying to create a terraform module such that I can give a list of security group IDs to it, and the security group rule will attach itself to each of the security group IDs. If I were to write it in pseudo code, it might look something like this:

<pseudo code>
security_group_ids=('sg-1234', 'sg-5678', 'sg-4321')

for sgid in ${security_group_ids[@]}; do
  security_group_rule = 'some code that contains the rule here.'
  attach ${security_group_rule} to ${sgid}
done
</pseudo code>

The infrastructure I'm trying to build contains VPCs, public and private subnets, security groups and taking advantage of the module/variable/output design pattern it is beautifully mainly fill in the blanks. I am now stuck only in the creation of the security group rule wherein I would like to call a single module and give that module a list of security group IDs for the security group rule to attach itself to.

I come from writing a Cloudformation/cloudformation-ruby-dsl infrastructure. As great as it is, I like terraform a lot! Thank you in advance.

p


cosmo....@anchor.com.au

unread,
Apr 5, 2016, 2:08:03 AM4/5/16
to Terraform
Hi,

Terraform doesn't have any looping syntax, but you can use the count metaparameter to achieve something similar.

One thing to watch out for is that I don't believe it's currently possible to pass arrays into module inputs, so you'll have to use a comma-separated list instead. Also, be careful that you don't use aws_security_group_rule in combination inline ingress/egress rules, as noted near the top of the resource's documentation.

If I'm interpreting your question correctly, something like this should do the job.

variable "security_group_ids" {}

resource
"aws_security_group_rule" "allow_all" {
    count
= "${length(split(",", var.security_group_ids))}"

    type
= "ingress"
    from_port
= 0
    to_port
= 65535
    protocol
= "tcp"
    cidr_blocks
= ["0.0.0.0/0"]

    security_group_id
= "${element(split(",",var.security_group_ids), count.index)}"}
}

Depending on what you're trying to accomplish, you may also want to consider having your modules create full security groups and offer their IDs as outputs, so long as you're not going to hit the limit on security groups per interface.

p

unread,
Apr 5, 2016, 9:38:02 AM4/5/16
to Terraform
Thank you. I did discover the count builtin, although it appears to have a bug; I am using Terraform 0.6.14

Within the module, I tried this:

count = "${length(split(",", var.security_group_ids))}"
security_group_ids = "${element(split(",", var.security_group_ids), count.index)}"

The interpolation of count is failing. It appears to be a common bug. Strconv.ParseInt invalid syntax.

It's ugly, but I'm just specifying the count as among the variables I need to pass in to the module. Fixing this would be nice because then the module could detect how many are in the list I'm giving it. Thank you.
Reply all
Reply to author
Forward
0 new messages