hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
41.67k stars 9.41k forks source link

New Splat operator not working in Terraform 0.12 alpha1 #19181

Closed rberlind closed 5 years ago

rberlind commented 5 years ago

The new Splat operator does not seem to be working in Terraform 0.12 alpha1, at least not in the example below.

Terraform Version

terraform -v
Terraform v0.12.0-alpha1
+ provider.aws v1.40.0-5-g4f24bc8b7

Terraform Configuration Files

terraform {
  required_version = ">= 0.12.0"
}

provider "aws" {
  region = var.aws_region
}

variable "aws_region" {
  description = "AWS region"
  default = "us-east-1"
}

variable "azs" {
  description = "AWS availability zones to use"
  default = ["a", "b", "c"]
}

resource "aws_instance" "ubuntu" {
  count = 3
  ami           = "ami-2e1ef954"
  instance_type = "t2.micro"
  availability_zone = format("%s%s", var.aws_region, var.azs[count.index])
  associate_public_ip_address = true
  tags = {
    Name  = format("terraform-0.12-for-demo-%d", count.index)
  }
  credit_specification {
    cpu_credits = "unlimited"
  }
}

# This uses the old splat expression
output "public_addresses_old" {
  value = [aws_instance.ubuntu.*.public_dns ]
}

# This uses the new full splat operator (*)
output "public_addresses_full_splat" {
  value = [ aws_instance.ubuntu[*].public_dns ]
}

# This uses the new for expression
output "public_addresses_new" {
  value = [
    for instance in aws_instance.ubuntu:
    instance.public_dns
  ]
}

Debug Output

$ terraform apply
Error: Invalid expression
  on main.tf line 40:
  40:   value = [ aws_instance.ubuntu[*].id ]
Expected the start of an expression, but found an invalid expression token.

Expected Behavior

Expected to get list of public_dns attributes from all 3 instances.

Actual Behavior

Got error indicating that my syntax was invalid.

Steps to Reproduce

  1. terraform init
  2. terraform apply

Additional Context

I set this up based on https://github.com/hashicorp/terraform/blob/v0.12-alpha/website/docs/configuration/expressions.html.md#splat-expressions

apparentlymart commented 5 years ago

Thanks for reporting this, @rberlind!

I think this must be a regression over in the HCL2 repository, so once I've investigated further to confirm we'll probably make an issue over there to track it, but we'll use this issue to track that fix being included in Terraform.

rberlind commented 5 years ago

Thanks @apparentlymart

rberlind commented 5 years ago

By the way, it is only the full splat operator that is not working. While aws_instance.ubuntu[*].public_dns gives the error I previously mentioned, I was able to use the following example and get the expected output:

resource "aws_security_group" "allow_some_ingress" {
  name        = "allow_some_ingress"
  description = "Allow some inbound traffic"
  vpc_id      = "vpc-0e56931573507c9dd"

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

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

output "ports" {
  value = aws_security_group.allow_some_ingress.ingress.*.from_port
}

This gave me:

Outputs:

ports = [
  8500,
  8200,
]
Constantin07 commented 5 years ago

I'm getting similar error with the latest 0.12-dev though it works fine with 0.11.10

21:03:43 Upgrading modules...
21:03:43 - core in ../modules/vpc
21:03:43 - key_pairs in ../modules/key_pairs
21:03:43 
21:03:43 Initializing the backend...
21:03:45 
21:03:45 Successfully configured the backend "s3"! Terraform will automatically
21:03:45 use this backend unless the backend configuration changes.
21:03:46 Error refreshing state: 7 problems:
21:03:46 
21:03:46 - Attribute name required: Splat expressions (.*) may not be used here.
21:03:46 - Attribute name required: Splat expressions (.*) may not be used here.
21:03:46 - Attribute name required: Splat expressions (.*) may not be used here.
21:03:46 - Attribute name required: Splat expressions (.*) may not be used here.
21:03:46 - Attribute name required: Splat expressions (.*) may not be used here.
21:03:46 - Attribute name required: Splat expressions (.*) may not be used here.
21:03:46 - Attribute name required: Splat expressions (.*) may not be used here.
apparentlymart commented 5 years ago

Hi @Constantin07! That seems like a different problem than what Roger was describing. Would you mind opening a new issue for that and completing the issue template so we can understand better what's going on there? Thanks!

Constantin07 commented 5 years ago

@apparentlymart sure, will do that.

apparentlymart commented 5 years ago

This was fixed by #19181 and the fix will be included in the next release.

rberlind commented 5 years ago

Thanks @apparentlymart

rberlind commented 5 years ago

I confirmed that this works with terraform 0.12 beta 1. Specifically, this now works:

output "public_addresses_full_splat" {
  value = [ aws_instance.ubuntu[*].public_dns ]
}
ghost commented 4 years ago

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.