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

Splat doesn't work properly #672

Closed
hashibot opened this issue Jun 13, 2017 · 3 comments
Closed

Splat doesn't work properly #672

hashibot opened this issue Jun 13, 2017 · 3 comments
Labels
enhancement Requests to existing resources that expand the functionality or scope. service/elasticache Issues and PRs that pertain to the elasticache service. upstream-terraform Addresses functionality related to the Terraform core binary.

Comments

@hashibot
Copy link

This issue was originally opened by @slikk66 as hashicorp/terraform#13397. It was migrated here as part of the provider split. The original body of the issue is below.


Hi there,

Thank you for opening an issue. Please note that we try to keep the Terraform issue tracker reserved for bug reports and feature requests. For general usage questions, please see: https://www.terraform.io/community.html.

Terraform Version

terraform -v

Terraform v0.9.2

Affected Resource(s)

Please list the resources as a list, for example:

  • aws_elasticache_cluster (at least)

If this issue appears to affect multiple resources, it may be an issue with Terraform's core, so please mention this. (think it does)

Expected Behavior

create output of multiple cache nodes using splat:

output "memcached_ha_endpoints" {
  value = ["${aws_elasticache_cluster.memcached_ha.cache_nodes.*.address}"]
}

Try to read in these addresses for DNS:

resource "aws_route53_record" "memcached_ha" {

  count   = "${var.cache_engine == "memcached_ha" ? "${var.cache_ha_node_count}" : 0}"

  zone_id = "${aws_route53_zone.dns_internal_zone.zone_id}"
  name    = "${format("memcached-%03d.%s", count.index+1, "${var.internal_dns_tld}")}"
  type    = "CNAME"
  ttl     = "300"
  records = ["${var.memcached_ha_endpoints[count.index]}"]
}

Actual Behavior

Error running plan: 1 error(s) occurred:

* module.dns.module.dns_internal.aws_route53_record.memcached_ha: 1 error(s) occurred:

* module.dns.module.dns_internal.aws_route53_record.memcached_ha[1]: index 1 out of range for list var.memcached_ha_endpoints (max 1) in:

${var.memcached_ha_endpoints[count.index]}

However, if you define the outputs using hardcoded indexes, it works:

output "memcached_ha_endpoints" {
  value = [
    "${aws_elasticache_cluster.memcached_ha.cache_nodes.0.address}",
    "${aws_elasticache_cluster.memcached_ha.cache_nodes.1.address}"
  ]
}
@hashibot hashibot added the enhancement Requests to existing resources that expand the functionality or scope. label Jun 13, 2017
@imauriciovargas
Copy link

Using version 0.10.0

variable "num_nodes" {
  defaul  = 2
}

resource "aws_elasticache_cluster" "memcached" {
  cluster_id = "foo"
  engine = "memcached"
  num_cache_nodes = "${var.num_nodes}"
  ...
}

resource "aws_cloudwatch_metric_alarm" "CPU" {
  count                     = "${var.num_nodes}"
  depends_on                = ["aws_elasticache_cluster.memcached"]
  ...
  dimensions                {
      CachedClusterId = "${aws_elasticache_cluster.memcached.id}",
      CachedNodeId    = "${element(aws_elasticache_cluster.memcached.cache_nodes.*.id, count.index)}"
  }
}

Error applying plan:

2 error(s) occurred:

* module.memcached.aws_cloudwatch_metric_alarm.CPU[1]: Resource 'aws_elasticache_cluster.memcached' does not have attribute 'cache_nodes.*.id' for variable 'aws_elasticache_cluster.memcached.cache_nodes.
*.id'
* module.memcached.aws_cloudwatch_metric_alarm.CPU[0]: Resource 'aws_elasticache_cluster.memcached' does not have attribute 'cache_nodes.*.id' for variable 'aws_elasticache_cluster.memcached.cache_nodes.
*.id'

Checking the aws_elasticache_cluyster output for cache_nodes:

output "memcached_nodes" {
    value = "${aws_elasticache_cluster.memcached.cache_nodes.*.id}"
}

Output should return a list of node IDs, however it returns a string with the number for nodes in cluster:

"outputs": {
                "memcached_nodes": {
                    "sensitive": false,
                    "type": "string",
                    "value": "2"
                }
            },

If remove the splat *;

output "memcached_nodes" {
    value = "${aws_elasticache_cluster.memcached.cache_nodes}"
}

returns a list with all the node info as it should.

"outputs": {
                "memcached_nodes": {
                    "sensitive": false,
                    "type": "list",
                    "value": [
                        {
                            "address": "foo.ncubqb.0001.use1.cache.amazonaws.com",
                            "availability_zone": "us-east-1b",
                            "id": "0001",
                            "port": "11211"
                        },
                        {
                            "address": "foo.ncubqb.0002.use1.cache.amazonaws.com",
                            "availability_zone": "us-east-1c",
                            "id": "0002",
                            "port": "11211"
                        }
                    ]
                }
            },

It seems like splat * just returns count. Also tried with other attributes and get the same issue.

The workaround is to manually create each resource and reference the nodes individually (in this case CloudWatch alarm).

@radeksimko radeksimko added upstream-terraform Addresses functionality related to the Terraform core binary. service/elasticache Issues and PRs that pertain to the elasticache service. labels Jan 27, 2018
@bflad
Copy link
Contributor

bflad commented Jul 24, 2019

Hi folks 👋 This issue is resolved in Terraform 0.12, which fully supports indexed splat (*) notation with list attribute values.

Given this configuration:

terraform {
  required_providers {
    aws = "2.20.0"
  }
  required_version = "0.12.5"
}

provider "aws" {
  region = "us-east-2"
}

resource "aws_elasticache_cluster" "test" {
  cluster_id      = "bflad-testing"
  engine          = "memcached"
  node_type       = "cache.t2.micro"
  num_cache_nodes = 3
}

output "test1" {
  value = aws_elasticache_cluster.test.cache_nodes[*].address
}

output "test2" {
  value = element(aws_elasticache_cluster.test.cache_nodes[*].address, 1)
}

output "test3" {
  value = join(",", formatlist("%s:%s", aws_elasticache_cluster.test.cache_nodes[*].address, aws_elasticache_cluster.test.cache_nodes[*].port))
}

We can get the various expected outputs that were problematic in Terraform 0.11 and earlier:

Outputs:

test1 = [
  "bflad-testing.asxu6y.0001.use2.cache.amazonaws.com",
  "bflad-testing.asxu6y.0002.use2.cache.amazonaws.com",
  "bflad-testing.asxu6y.0003.use2.cache.amazonaws.com",
]
test2 = bflad-testing.asxu6y.0002.use2.cache.amazonaws.com
test3 = bflad-testing.asxu6y.0001.use2.cache.amazonaws.com:11211,bflad-testing.asxu6y.0002.use2.cache.amazonaws.com:11211,bflad-testing.asxu6y.0003.use2.cache.amazonaws.com:11211

Enjoy! 🚀

@bflad bflad closed this as completed Jul 24, 2019
@ghost
Copy link

ghost commented Nov 2, 2019

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 Nov 2, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement Requests to existing resources that expand the functionality or scope. service/elasticache Issues and PRs that pertain to the elasticache service. upstream-terraform Addresses functionality related to the Terraform core binary.
Projects
None yet
Development

No branches or pull requests

4 participants