Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws_instance security_groups getting only default when using -target= that points to a module security group #1858

Closed
stephenchu opened this issue May 7, 2015 · 15 comments · Fixed by #2555
Assignees

Comments

@stephenchu
Copy link
Contributor

It seems my aws_instance.security_groups value cannot contain (or mix with) a modularized aws_security_group resource and a locally defined aws_security_group resource.

Suppose I have the following folder structure:

.
├── main.tf
├── modules.tf
├── security_groups_module
│   └── all.tf
└── variables.tf

... and the following files:

$ cat main.tf
resource "aws_security_group" "consul_dns" {
  name = "Consul Server (DNS)"
  description = "Consul Server (DNS)"
  ingress {
    from_port   = 8600
    to_port     = 8600
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "buggy" {
  instance_type   = "t2.medium"
  ami             = "ami-b7f97daa"
  key_name        = "${var.key_name}"
  security_groups = [
    "${module.security_groups.ssh}",
    "${aws_security_group.consul_dns.name}"
  ]
}
$ cat modules.tf
module "security_groups" {
  source = "./security_groups_module"
}
$ cat security_groups_module/all.tf
resource "aws_security_group" "ssh" {
  name = "SSH"
  description = "SSH"

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
$ cat variables
provider "aws" {
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
  region = "${var.region}"
}

variable "access_key" { default = "" }
variable "secret_key" { default = "" }
variable "region"     { default = "sa-east-1" }
variable "key_name"   { default = "..." }

Then, when I apply with terraform apply -input=false, the buggy instance will correctly be associated with the new security groups "consul_dns" and "ssh".

However, when I apply with terraform apply -input=false -target=aws_instance.buggy, which I assume the implicit dependencies will also create and associate it with "consul_dns" and "ssh", Terraform will only create "consul_dns" (but not "ssh"), and fails to associate "consul_dns" to my buggy instance; it just associates the default security group to buggy.

If I also added -target=aws_security_group.ssh, then Terraform will create but not associate it.

Is this expected? Ultimately I want to create buggy (through use of -target=) and have both security groups associated, despite one defined as a module and one elsewhere.

Thanks.

@stephenchu
Copy link
Contributor Author

Terraform v0.4.2 was used.

@phinze
Copy link
Contributor

phinze commented May 7, 2015

👋 hi @stephenchu 😀

Thanks for the solid bug report. It's so nice to get well written issues. 🙇

Good news! This should be fixed in 0.5.0 which is coming out very shortly. If you'd like to test master in the meantime you are welcome to. I'm going to be optimistic and close this for now, but feel free to reopen if master (or 0.5.0 once its out) gives you trouble.

@phinze phinze closed this as completed May 7, 2015
@stephenchu
Copy link
Contributor Author

It looks like you aren't off the hook yet @phinze 👊

This is from a terraform bin hot off from master:

$ terraform -version                                                                             
Terraform v0.5.0-dev (4874179e9aabfa275ccc08449720019fa9c0114f+CHANGES)

$ terraform plan -input=false -target=aws_instance.buggy                                    
...

+ aws_instance.buggy
    ami:                        "" => "ami-b7f97daa"
    availability_zone:          "" => "<computed>"
    ebs_block_device.#:         "" => "<computed>"
    ephemeral_block_device.#:   "" => "<computed>"
    instance_type:              "" => "t2.medium"
    key_name:                   "" => "CosmosPairing"
    placement_group:            "" => "<computed>"
    private_dns:                "" => "<computed>"
    private_ip:                 "" => "<computed>"
    public_dns:                 "" => "<computed>"
    public_ip:                  "" => "<computed>"
    root_block_device.#:        "" => "<computed>"
    security_groups.#:          "" => "2"
    security_groups.0:          "" => ""
    security_groups.1926560890: "" => "Consul Server (DNS)"
    subnet_id:                  "" => "<computed>"
    tenancy:                    "" => "<computed>"
    vpc_security_group_ids.#:   "" => "<computed>"

+ aws_security_group.consul_dns
    description:                          "" => "Consul Server (DNS)"
    egress.#:                             "" => "<computed>"
    ingress.#:                            "" => "1"
    ingress.1403602808.cidr_blocks.#:     "" => "1"
    ingress.1403602808.cidr_blocks.0:     "" => "0.0.0.0/0"
    ingress.1403602808.from_port:         "" => "8600"
    ingress.1403602808.protocol:          "" => "-1"
    ingress.1403602808.security_groups.#: "" => "0"
    ingress.1403602808.self:              "" => "0"
    ingress.1403602808.to_port:           "" => "8600"
    name:                                 "" => "Consul Server (DNS)"
    owner_id:                             "" => "<computed>"
    vpc_id:                               "" => "<computed>"

Notice the security_groups.0: "" => "" line. It comes from the security group defined in my module.

I am still not getting a buggy with 2 security groups when I apply the above.

@phinze
Copy link
Contributor

phinze commented May 7, 2015

Thanks for testing master! Reopening and we'll take a look.

@phinze phinze reopened this May 7, 2015
@phinze
Copy link
Contributor

phinze commented May 7, 2015

Ah I see it now. This is just something we need to detect and error message on.

When you say:

 "${module.security_groups.ssh}"

I believe you're attempting to access the aws_security_group.ssh resource from inside the "security_groups" module? This does not work, because module resources are encapsulated within the module boundary. A module is a black box whose inputs and outputs must be declared (with variable and output declarations, respectively).

So what you'll want to do is add to your module something like:

output "sg_name" {
  value = "${aws_security_group.name}"
}

And then reference that value from the top level like this:

security_groups = ["${module.security_groups.sg_name}"]

Let me know if that makes sense!

@stephenchu
Copy link
Contributor Author

Ops. Paste error. I actually do have the following module output:

$ cat security_groups_module/all.tf
resource "aws_security_group" "ssh" {
  name = "SSH"
  description = "SSH"

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

output "ssh" { value = "${aws_security_group.ssh.name}" }

@stephenchu
Copy link
Contributor Author

Oh but I do see your output does not contain ".ssh"... Let me try that.

@phinze
Copy link
Contributor

phinze commented May 7, 2015

Oh with the output that may still be a problem. I'll spin up a test over here too.

@phinze
Copy link
Contributor

phinze commented May 7, 2015

Bingo - reproduced. Definitely a targeting bug. I'll dig in and get back to you.

@phinze phinze self-assigned this May 7, 2015
@phinze
Copy link
Contributor

phinze commented May 8, 2015

@stephenchu FYI as a workaround you can tack on as many -target args as you want until the set looks right. 😉

@stephenchu
Copy link
Contributor Author

Yea, I think I tried that trick already with 0.4.2, but it didn't do it for me. I didn't get a chance to try it with today's 0.5.0 yet but I will and report back. Thanks for keeping me updated! Also, 0.5.0 looks like an awesome release!

@stephenchu
Copy link
Contributor Author

Confirmed that having multiple -target in the command line does not help. I am getting a error MissingParameter: When specifying a security group you must specify one of group id or group name for each item still after doing this with 0.5.0:

$ terraform plan -input=false -target=aws_instance.buggy -target=aws_security_group.ssh -target=aws_security_group.consul_dns

On a side note: I did have to fix my protocol = "-1" to just "tcp" after being on 0.5.0.

@phinze
Copy link
Contributor

phinze commented May 13, 2015

Thanks for following up - that's helpful data. I'll get this looked at soon!

phinze added a commit that referenced this issue Jun 29, 2015
Allows target dependencies to be properly calculated across module
boundaries, fixing scenarios where a target depends on something inside
a module, but the contents of the module are not included in the
targeted resources.

fixes #1858
@stephenchu
Copy link
Contributor Author

🙇

@ghost
Copy link

ghost commented May 1, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators May 1, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants