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

No way to pass a null value for aws_autoscaling_group.availability_zones #1187

Closed
joshuaspence opened this issue Jul 19, 2017 · 3 comments · Fixed by #1190
Closed

No way to pass a null value for aws_autoscaling_group.availability_zones #1187

joshuaspence opened this issue Jul 19, 2017 · 3 comments · Fixed by #1190
Labels
bug Addresses a defect in current functionality.

Comments

@joshuaspence
Copy link
Contributor

In hashicorp/terraform#5471, @mitchellh said:

Most resources at the moment must just be written to accept some "zero" value as unset. If a resource doesn't support this please report a bug. We hope that in time we'll have a way to unset a value but at the moment we do not.

It seems that aws_autoscaling_group.availability_zones is an example of this issue. I have a module that I am using to create autoscaling groups both in EC2-Classic and VPC. It is basically a wrapper around the aws_autoscaling_group and aws_launch_configuration resources. In order to support both Classic and VPC, I need to expose an availability_zones variable. The problem is that there is no way to pass a null value to this variable.

I think that the best fix here is to treat [] (an empty list) as being equivalent to null. The reason that I suggest this is because [] is not a valid value anyway. In EC2-Classic, attempting to pass availabilitity_zones = [] produces an error:

resource "aws_autoscaling_group" "test" {
  min_size = 1
  max_size = 1

  availability_zones   = []
  launch_configuration = "${aws_launch_configuration.test.name}"
}

data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"]

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

}
resource "aws_launch_configuration" "test" {
  image_id      = "${data.aws_ami.ubuntu.id}"
  instance_type = "c3.large"

  lifecycle {
    create_before_destroy = true
  }
}
Error applying plan:

1 error(s) occurred:

* aws_autoscaling_group.test: 1 error(s) occurred:

* aws_autoscaling_group.test: Error creating AutoScaling Group: ValidationError: At least one Availability Zone or VPC Subnet is required.
    status code: 400, request id: 5928694d-6ccf-11e7-8f81-7591e9c28ebe

In a VPC, passing availability_zones = [] produces a perpetual set of changes (because the API seems to transparently replace [] with the set of availability zones corresponding to the specified subnets):

resource "aws_vpc" "test" {
  cidr_block = "10.0.0.0/16"
}

data "aws_availability_zones" "available" {}

resource "aws_subnet" "test" {
  vpc_id     = "${aws_vpc.test.id}"
  cidr_block = "${cidrsubnet(aws_vpc.test.cidr_block, ceil(log(2 * length(data.aws_availability_zones.available.names), 2)), count.index)}"
  count      = "${length(data.aws_availability_zones.available.names)}"
}

resource "aws_autoscaling_group" "test" {
  min_size = 1
  max_size = 1

  availability_zones   = []
  launch_configuration = "${aws_launch_configuration.test.name}"
  vpc_zone_identifier  = ["${aws_subnet.test.*.id}"]
}

data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"]

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

}
resource "aws_launch_configuration" "test" {
  image_id      = "${data.aws_ami.ubuntu.id}"
  instance_type = "c3.large"

  lifecycle {
    create_before_destroy = true
  }
}
~ aws_autoscaling_group.test
    availability_zones.#:          "1" => "0"
    availability_zones.1436938394: "ap-southeast-2c" => ""
@Ninir
Copy link
Contributor

Ninir commented Jul 20, 2017

Hey @joshuaspence

Thanks for reporting the issue. This looks more a Core bug to me, especially since it would mean treating [] as nil.
We could make a guard in the AWS code, but as there are many other places this could be annoying...

@apparentlymart Could we have your point of view there? Thanks :)

@Ninir Ninir added the bug Addresses a defect in current functionality. label Jul 20, 2017
@apparentlymart
Copy link
Contributor

I think this demonstrates a limitation of what Mitchell suggested in that other issue.

In most cases it is equivalent to either leave a value unset or to set it to some "empty value", there is one situation where this isn't true: situations where an argument is optional and the API provides some sort of default when it isn't set. (Internally, this is represented as Optional + Computed flags on the attribute).

The trick here is that Terraform uses the absense of the argument as "use what the server says", not the "zero-ness" of it. So by explicitly setting it to [] you are saying "this must be empty", rather than "accept the server's default", and consequently Terraform detects a diff once the server sets it to something other than empty. This comparison behavior exists outside of this specific resource implementation, so it's not something we can easily fix for this resource in isolation.

So unfortunately things are working as designed here, though I understand that it's frustrating in this case. We're in the early stages of discussing improvements to the configuration language we can make over the next few major versions of Terraform and the ability to explicitly "null out" attributes is on the list, so I think this will get addressed one way or another without the need for an explicit issue for it in the core repo.

mdlavin pushed a commit to mdlavin/terraform-provider-aws that referenced this issue Dec 9, 2017
I have a `lambda_function` module, which supports both EC2 classic and VPC. The problem I have, however, is that there is no way to specify a null configuration for `vpc_config`. This pull request changes the behavior so that the following Terraform configuration is //ignored//, instead of failing with an error (the current behavior):

```
resource "aws_lambda_function" "test" {
  # ...

  vpc_config {
    security_group_ids = []
    subnet_ids         = []
  }
}
```

See also hashicorp#1187 and hashicorp#1190.
mdlavin pushed a commit to mdlavin/terraform-provider-aws that referenced this issue Jan 3, 2018
I have a `lambda_function` module, which supports both EC2 classic and VPC. The problem I have, however, is that there is no way to specify a null configuration for `vpc_config`. This pull request changes the behavior so that the following Terraform configuration is //ignored//, instead of failing with an error (the current behavior):

```
resource "aws_lambda_function" "test" {
  # ...

  vpc_config {
    security_group_ids = []
    subnet_ids         = []
  }
}
```

See also hashicorp#1187 and hashicorp#1190.
mdlavin pushed a commit to mdlavin/terraform-provider-aws that referenced this issue Jan 17, 2018
I have a `lambda_function` module, which supports both EC2 classic and VPC. The problem I have, however, is that there is no way to specify a null configuration for `vpc_config`. This pull request changes the behavior so that the following Terraform configuration is //ignored//, instead of failing with an error (the current behavior):

```
resource "aws_lambda_function" "test" {
  # ...

  vpc_config {
    security_group_ids = []
    subnet_ids         = []
  }
}
```

See also hashicorp#1187 and hashicorp#1190.
mdlavin pushed a commit to mdlavin/terraform-provider-aws that referenced this issue Jan 22, 2018
I have a `lambda_function` module, which supports both EC2 classic and VPC. The problem I have, however, is that there is no way to specify a null configuration for `vpc_config`. This pull request changes the behavior so that the following Terraform configuration is //ignored//, instead of failing with an error (the current behavior):

```
resource "aws_lambda_function" "test" {
  # ...

  vpc_config {
    security_group_ids = []
    subnet_ids         = []
  }
}
```

See also hashicorp#1187 and hashicorp#1190.
philidem pushed a commit to lifeomic/terraform-provider-aws that referenced this issue Mar 28, 2018
I have a `lambda_function` module, which supports both EC2 classic and VPC. The problem I have, however, is that there is no way to specify a null configuration for `vpc_config`. This pull request changes the behavior so that the following Terraform configuration is //ignored//, instead of failing with an error (the current behavior):

```
resource "aws_lambda_function" "test" {
  # ...

  vpc_config {
    security_group_ids = []
    subnet_ids         = []
  }
}
```

See also hashicorp#1187 and hashicorp#1190.
philidem pushed a commit to lifeomic/terraform-provider-aws that referenced this issue Apr 10, 2018
I have a `lambda_function` module, which supports both EC2 classic and VPC. The problem I have, however, is that there is no way to specify a null configuration for `vpc_config`. This pull request changes the behavior so that the following Terraform configuration is //ignored//, instead of failing with an error (the current behavior):

```
resource "aws_lambda_function" "test" {
  # ...

  vpc_config {
    security_group_ids = []
    subnet_ids         = []
  }
}
```

See also hashicorp#1187 and hashicorp#1190.
mdlavin pushed a commit to mdlavin/terraform-provider-aws that referenced this issue May 31, 2018
I have a `lambda_function` module, which supports both EC2 classic and VPC. The problem I have, however, is that there is no way to specify a null configuration for `vpc_config`. This pull request changes the behavior so that the following Terraform configuration is //ignored//, instead of failing with an error (the current behavior):

```
resource "aws_lambda_function" "test" {
  # ...

  vpc_config {
    security_group_ids = []
    subnet_ids         = []
  }
}
```

See also hashicorp#1187 and hashicorp#1190.
mdlavin pushed a commit to lifeomic/terraform-provider-aws that referenced this issue May 31, 2018
I have a `lambda_function` module, which supports both EC2 classic and VPC. The problem I have, however, is that there is no way to specify a null configuration for `vpc_config`. This pull request changes the behavior so that the following Terraform configuration is //ignored//, instead of failing with an error (the current behavior):

```
resource "aws_lambda_function" "test" {
  # ...

  vpc_config {
    security_group_ids = []
    subnet_ids         = []
  }
}
```

See also hashicorp#1187 and hashicorp#1190.
philidem pushed a commit to lifeomic/terraform-provider-aws that referenced this issue Sep 5, 2018
I have a `lambda_function` module, which supports both EC2 classic and VPC. The problem I have, however, is that there is no way to specify a null configuration for `vpc_config`. This pull request changes the behavior so that the following Terraform configuration is //ignored//, instead of failing with an error (the current behavior):

```
resource "aws_lambda_function" "test" {
  # ...

  vpc_config {
    security_group_ids = []
    subnet_ids         = []
  }
}
```

See also hashicorp#1187 and hashicorp#1190.
@ghost
Copy link

ghost commented Apr 11, 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 feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

@ghost ghost locked and limited conversation to collaborators Apr 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Addresses a defect in current functionality.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants