We are trying to create a generic module for creating APIs (using API gateway). Ideally, we would like to pass an array of path parts to the module. Then, the module would iterate over these paths creating the necessary resources (chaining a path resource to its parent).
We came up with the following approach:
provider "aws" {
profile = "${var.profile}"
region = "${var.region}"
}
variable "path_parts" {
type = "list",
default = ["a", "b", "c"]
}
resource "aws_api_gateway_rest_api" "api" {
name = "api"
}
resource "aws_api_gateway_resource" "path" {
count = 3
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
parent_id = "${count.index > 0 ? element(aws_api_gateway_resource.path.*.id, count.index - 1) : aws_api_gateway_rest_api.api.root_resource_id}"
path_part = "${element(var.path_parts, count.index)}"
}
But, it does not work. We get the following error:
3 error(s) occurred:
* aws_api_gateway_resource.path[0]: aws_api_gateway_resource.path[0]: self reference not allowed: "aws_api_gateway_resource.path.*.id"
* aws_api_gateway_resource.path[1]: aws_api_gateway_resource.path[1]: self reference not allowed: "aws_api_gateway_resource.path.*.id"
* aws_api_gateway_resource.path[2]: aws_api_gateway_resource.path[2]: self reference not allowed: "aws_api_gateway_resource.path.*.id"
Is this possible or we are just approaching it the wrong way? If it is not currently possible, would you consider adding this feature?
Terraform v0.9.4
Hi @betabandido,
This is indeed not possible, and isn't straightforward to support due to how count works internally. (the resource is a single node in the dependency graph, with all of the counted instances appearing as a sub-graph within that node.)
API Gateway is a common use-case for generating Terraform configurations programmatically, e.g. from a Swagger definition, due to the shear volume of resources needed for even basic usage. There are not built-in features for this, but several people (including me, in a previous role) have written internal tools to generate Terraform configs for API Gateway, with success.
However, to get to your specific use-case, one way we could think of this is to have the aws_api_gateway_resource _optionally_ automatically create any missing intermediate resource nodes, similar to what mkdir -p does in the filesystem. We'd need to think about this a bit because there will almost certainly be some quirky things to deal with when e.g. multiple resources are both created under a single prefix, and they "race" to be the one to create the prefix, or to delete it again when the resources are destroyed.
Indeed, having the possibility to create any missing intermediate nodes would be great. I imagine this would be useful for many people, as lots of services' endpoints follow a similar pattern (/path1/.../pathN/{param1}/.../{paramM}).
@apparentlymart This issue was moved to #766 in the terraform-provider-aws repo, but it's not AWS specific. The ability to reference a previous element when using count is something that would be useful for all providers.
To add a use case: if you could depend on the previous item (count.index - 1), then you could easily support a "rolling deployment" with pure Terraform code, where one old node at a time is replaced with a new node. Without it, we have to resort to shell scripts outside of Terraform.
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.
Most helpful comment
@apparentlymart This issue was moved to #766 in the terraform-provider-aws repo, but it's not AWS specific. The ability to reference a previous element when using
countis something that would be useful for all providers.To add a use case: if you could depend on the previous item (
count.index - 1), then you could easily support a "rolling deployment" with pure Terraform code, where one old node at a time is replaced with a new node. Without it, we have to resort to shell scripts outside of Terraform.