Value attribute is expected when creating aws internet gateway with terraform - amazon-web-services

I want to create an internet gateway with terraform. Following the [terraform documentation][1] I have the following block
resource "aws_internet_gateway" "prod-igw" {
vpc_id = "${aws_vpc.prod-vpc.id}"
tags = {{
Name = "pos-igw"
}
}
After applying I get this error message.
Error: Missing attribute value
Expected an attribute value, introduced by an equals sign ("=").
There's nothing about value in the documentation though.
[1]: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway

You have a typo:
resource "aws_internet_gateway" "prod-igw" {
vpc_id = aws_vpc.prod-vpc.id
tags = { # <--- there was an extra {
Name = "pos-igw"
}
}
Please make sure to use a modern IDE (e.g., VScode) where there is a terraform extension which will prevent these things from happening and you will not have to ask a question on SO.

Related

How do I retrieve multiple vpc endpoints?

ERROR: no matching VPC Endpoint found
(error referring to data code block)
I am trying to retrieve multiple endpoints from data "aws_vpc_endpoint" resource. I created locals to retrieve service name for multiple endpoints that share the first few characters. Afterwards, the endpoints have unique characters to identify them individually.
I am wanting the data resource to loop through the data and retrieve each endpoint that shares those few characters. Then grab each endpoint id for "aws_route". FYI: The endpoints are being created from resource "aws_networkfirewall_firewall" The main thing to look at in this code snippet is locals, data, and the last line for resource "aws_route" How can I express in locals that the service_name does not end there and the rest of the string is unique to the endpoint without hard coding each service_name?
locals {
endpoints = {
service_name = "com.amazonaws.vpce.us-east-1.vpce-svc-"
}
}
data "aws_vpc_endpoint" "firewall-endpoints" {
for_each = local.endpoints
vpc_id = aws_vpc.vpc.id
service_name = each.value
#filter {
# name = "tag:AWSNetworkFirewallManaged"
# values = [true]
#}
}
resource "aws_route" "tgw_route" {
count = var.number_azs
route_table_id = aws_route_table.tgw_rt[count.index].id
destination_cidr_block = var.tgw_aws_route[0]
vpc_endpoint_id = data.aws_vpc_endpoint.firewall-endpoints["service_name"].id
}
I can't test this, but I think what you want to do is something like this:
resource "aws_route" "tgw_route" {
for_each = aws_networkfirewall_firewall.firewall_status.sync_states
route_table_id = aws_route_table.tgw_rt[???].id
destination_cidr_block = var.tgw_aws_route[0]
vpc_endpoint_id = each.value.attachment.endpoint_id
}
I'm not clear on the structure of the firewall_status output, so that may need to change slightly. The main question is how to get the appropriate route table ID per subnet. Can you access the outputs of the tgw_rt module in some way other than by index? Unfortunately, I have no experience with setting up an AWS firewall, just with Terraform, so I don't know how to solve this part of the puzzle.

Terraform Inappropriate value for attribute "route"

relatively new to terraform and currently trying to build cloud infrastructure in AWS.
I get an error when I use an official example (little bit changed) from the documentation for the resource aws_route_table (https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table)
resource "aws_route_table" "prod-route-table" {
vpc_id = aws_vpc.prod-vpc.id
route = [{
# Route all Traffic to the internet gateway
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
},{
ipv6_cidr_block = "::/0"
gateway_id = aws_internet_gateway.gw.id
}]
}
I get the following error message
Error: Incorrect attribute value type
│ Inappropriate value for attribute "route": element 0: attributes "carrier_gateway_id",
│ "destination_prefix_list_id", "egress_only_gateway_id", "instance_id", "ipv6_cidr_block",
│ "local_gateway_id", "nat_gateway_id", "network_interface_id", "transit_gateway_id", "vpc_endpoint_id",
│ and "vpc_peering_connection_id" are required.
Adding all these attributes solves the error however this blows up the code massively.
Writing it differently (see the following) results in no errors, is the terraform AWS documentation incorrect, as they clearly state the first way of writing it?
resource "aws_route_table" "prod-route-table" {
vpc_id = aws_vpc.prod-vpc.id
route {
# Route all Traffic to the internet gateway
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
route{
ipv6_cidr_block = "::/0"
gateway_id = aws_internet_gateway.gw.id
}
}
I am using terraform v1.0.10 and aws provider version = "3.63.0"
Thanks in advance
The documentation for that argument mentions that it's using the legacy attributes as blocks mode, which is a holdover from Terraform v0.12 for some situations where providers were depending on being able to write certain arguments in both the nested block syntax (like in your second example) and in the attribute syntax (like in your first example).
The syntax currently shown in the doc example -- and your first example in your question -- is contrary to the advice about how to write a fixed value (as opposed to a dynamic value), so indeed the second example you showed here would be the preferred way as far as the general Terraform documentation is concerned.
resource "aws_route_table" "example" {
vpc_id = aws_vpc.example.id
route {
cidr_block = "10.0.1.0/24"
gateway_id = aws_internet_gateway.example.id
}
route {
ipv6_cidr_block = "::/0"
egress_only_gateway_id = aws_egress_only_internet_gateway.example.id
}
tags = {
Name = "example"
}
}
Possibly the AWS provider documentation author here used the attribute syntax in order to show symmetry with the special case of setting route = [] to explicitly state that there should be no routes at all, because entirely omitting this argument unfortunately (for historical reasons) means to ignore any existing routes in the remote API, rather than to remove all existing routes in the remote API.
There's a little more about the behavior you saw in the subsequent section arbitrary expressions with argument syntax:
Because of the rule that argument declarations like this fully override any default value, when creating a list-of-objects expression directly the usual handling of optional arguments does not apply, so all of the arguments must be assigned a value, even if it's an explicit null:
example = [
{
# Cannot omit foo in this case, even though it would be optional in the
# nested block syntax.
foo = null
},
]
Over time providers will gradually phase out this legacy mode, but must do so cautiously because it can be a breaking change for some existing configurations. Until then this is unfortunately a confusing rough edge for some particular provider attributes, though they should at least all link to the relevant documentation page I linked above to note that their behavior doesn't match the normal Terraform argument-handling behaviors.

Terraform - aws_route_tables

Hope someone might be able to help me please. Basically I am trying to use the data source resource for aws_route_tables and then do a lookup on that using the aws_route resource. So what I am trying to achieve here is to create a route to the transit gateway for each route table associated to a specific VPC. However, I keep getting this error:
Error reading config for aws_route[rt_tgw]: parse error at 1:40: expected "}" but found "["
This is the documentation I was following:
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route_tables
I am using Terraform version 11.15 by the way and this is the code I have got:
variable "environment_group" {
description = "Name given to the resource"
default = "test"
}
variable "create_tgw_route" {
description = "Toggle to create the transit gateway route within the VPC route table"
default = true
}
variable "tgw_route_cidr" {
description = "Specify the destination cidr block for the transit gateway route within the VPC route table"
default = "10.0.0.0/8"
}
variable "transit_gateway_id" {
default = ""
description = "Temporary variable that should be replaced by a data lookup in due time"
}
data "aws_vpc" "vpc_id" {
count = "${var.create_tgw_route ? 1 : 0}"
filter {
name = "tag:Name"
values = ["vpc-${var.environment_group}"]
}
}
data "aws_route_tables" "rtb" {
count = "${var.create_tgw_route ? 1 : 0}"
vpc_id = "${data.aws_vpc.vpc_id.id}"
filter {
name = "tag:Name"
values = ["rt-${var.environment_group}-*"]
}
}
resource "aws_route" "rt_tgw" {
count = "${var.create_tgw_route ? 1 : 0}"
route_table_id = "${tolist(data.aws_route_tables.rtb.ids)[count.index]}"
destination_cidr_block = "${var.tgw_route_cidr}"
transit_gateway_id = "${var.transit_gateway_id}"
}
Any help would be much appreciated please. Thank you in advance.
Okay, I have managed to fix this. I changed the resource block to this:
resource "aws_route" "rt_tgw" {
count = "${var.create_tgw_route ? length(data.aws_route_tables.rtb.ids) : 0}"
route_table_id = "${data.aws_route_tables.rtb.ids[count.index]}"
destination_cidr_block = "${var.tgw_route_cidr}"
transit_gateway_id = "${var.transit_gateway_id}"
}
So basically 2 things I changed.
Amending the count value to ensure that what ever route table is looked up in data source will be the number of routes created. In this case is 3 route tables = 3 routes created
Amending the 'route_table_id' value as for some reason version 11 does not like the way it is shown in the documentation.

Scope down statement on WAFv2 using Terraform

I've created a managed rule group statement using Terraform and i'm now trying to add a scope down statement to it in order to exclude requests from a specific url. This can be done very easily on the AWS console however according to Terraform docs it appears that scope_down_statement can't be associated with managed_rule_group_statement.
Am I missing something? Here's is where i'm trying to add the scope_down_statement:
resource "aws_wafv2_web_acl" "example" {
name = "waf-example"
description = "Example of a managed rule"
scope = "REGIONAL"
default_action {
allow {}
}
rule {
name = "AWSManagedRulesAnonymousIpList"
priority = 0
override_action {
none {}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesAnonymousIpList"
vendor_name = "AWS"
}
}
I was experiencing the same issue. You need to upgrade the AWS provider version to 3.50. Please see the https://github.com/hashicorp/terraform-provider-aws/pull/19407
Thanks

Terrafrom datasource aws_vpcs - count.index error

I am trying to use data source aws_vpcs to get the vpc id having specific tag.
For reference:
https://www.terraform.io/docs/providers/aws/d/vpcs.html
Below is my terraform yaml file.
Terrafrom version used is: 0.12.3
data "aws_vpcs" "foo" {
tags = {
Name = "test1-VPC"
}
}
resource "aws_security_group" "cluster" {
count = "${length(data.aws_vpcs.foo.ids)}"
vpc_id = "${tolist(data.aws_vpcs.foo.ids)[count.index]}"
}
resource "aws_security_group_rule" "cluster-ingress-node-https" {
description = "Rule to do xyz"
from_port = 443
protocol = "tcp"
security_group_id = "${aws_security_group.cluster.id}"
to_port = 443
type = "ingress"
}
I am getting below error. Request for help to fix this
terraform plan
Error: Missing resource instance key
on modules/eks/eks-cluster.tf line 40, in resource "aws_security_group_rule" "cluster-ingress-node-https":
40: security_group_id = "${aws_security_group.cluster.id}"
Because aws_security_group.cluster has "count" set, its attributes must be
accessed on specific instances.
For example, to correlate with indices of a referring resource, use:
aws_security_group.cluster[count.index]
You are creating a list of aws_security_group as you are using count on the aws_security_group resource. The error even mentions it:
Because aws_security_group.cluster has "count" set, its attributes
must be accessed on specific instances.
So either you need to include count on the aws_security_group_rule resource and create one aws_security_group_rule for each aws_security_group created, or in the case you expect only one VPC to be returned, create only one aws_security_group by accessing the returned aws_vpcs.foo.ids with index 0.
You will need to convert the list of security group.
Terraform provides flatten function to do that https://nedinthecloud.com/2018/07/16/terraform-fotd-flatten/
You should not get this error afterwards
I know this was posted a while ago. Stumbled upon this issue.
${aws_security_group.cluster.*.id} should do it.
Since the resource aws_security_group is creating multiple security groups with count, resource block aws_security_group_rule needs to reference the correct index in the list.