hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.74k stars 9.1k forks source link

[Bug]: Missing `icmpv6` protocol in `aws_lightsail_instance_public_ports` resource #35526

Open fluxth opened 7 months ago

fluxth commented 7 months ago

Terraform Core Version

1.7.1

AWS Provider Version

5.34.0

Affected Resource(s)

Expected Behavior

icmpv6 protocol should be allowed in aws_lightsail_instance_public_ports resources.

This is the diff when setting icmpv6 from the web console:

      - port_info { # forces replacement
          - cidr_list_aliases = [] -> null
          - cidrs             = [] -> null
          - from_port         = -1 -> null
          - ipv6_cidrs        = [
              - "::/0",
            ] -> null
          - protocol          = "icmpv6" -> null
          - to_port           = -1 -> null
        }

Actual Behavior

When icmpv6 protocol is configured as a rule in aws_lightsail_instance_public_ports, terraform throws an error and refuses to continue.

Relevant Error/Panic Output Snippet

Acquiring state lock. This may take a few moments...
╷
│ Error: expected port_info.5.protocol to be one of ["tcp" "all" "udp" "icmp"], got icmpv6
│
│   with module.chisato_server.aws_lightsail_instance_public_ports.this,
│   on ../../modules/lightsail_server/main.tf line 10, in resource "aws_lightsail_instance_public_ports" "this":
│   10: resource "aws_lightsail_instance_public_ports" "this" {
│
╵

Terraform Configuration Files

resource "aws_lightsail_instance_public_ports" "this" {
  instance_name = aws_lightsail_instance.this.name

  port_info {
    protocol   = "icmp"
    from_port  = -1
    to_port    = -1
    cidrs      = ["0.0.0.0/0"]
  }

  port_info {
    protocol   = "icmpv6"
    from_port  = -1
    to_port    = -1
    ipv6_cidrs = ["::/0"]
  }

  port_info {
    protocol   = "tcp"
    from_port  = 80
    to_port    = 80
    cidrs      = ["0.0.0.0/0"]
    ipv6_cidrs = ["::/0"]
  }

  port_info {
    protocol   = "tcp"
    from_port  = 443
    to_port    = 443
    cidrs      = ["0.0.0.0/0"]
    ipv6_cidrs = ["::/0"]
  }

  port_info {
    protocol   = "udp"
    from_port  = 443
    to_port    = 443
    cidrs      = ["0.0.0.0/0"]
    ipv6_cidrs = ["::/0"]
  }
}

Steps to Reproduce

Configure icmpv6 protocol in a rule in aws_lightsail_instance_public_ports resource, terraform will throw an error and refuse to continue.

Debug Output

No response

Panic Output

No response

Important Factoids

No response

References

No response

Would you like to implement a fix?

None

github-actions[bot] commented 7 months ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

acwwat commented 7 months ago

Both the OpenInstancePublicPorts API reference and the Go V2 SDK code do not list icmpv6 as a valid protocol value. I suspect that you'd just specify icmp for protocol and ipv6_cidrs to allow ICMP v6 traffic. This note that I saw from the documentation may also be relevant:

ICMPv6 - The ICMP type for IPv6 addresses. For example, specify 128 as the fromPort (ICMPv6 type), and 0 as toPort (ICMPv6 code).

Could you please try it out if you haven't and post back on the results? If it works, we can improve the documentation with this information.

nbensa commented 5 months ago

api error InvalidParams: ICMP supports only IPv4 CIDRs

I also tried aws-cli:

An error occurred (InvalidInputException) when calling the OpenInstancePublicPorts operation: ICMP supports only IPv4 CIDRs.

acwwat commented 5 months ago

Edit: I misspoke about the Terraform code using OpenInstancePublicPorts - it's actually using PutInstancePublicPorts. But it would still fail with the AWS Go SDK v2 because the enum for the protocols doesn't include icmpv6 resulting in a pre-request validation error.

I decided to apply the same change in the UI and then look at the CloudTrail event, and indeed the API supports the type icmpv6. Here is the relevant portInfos list entry:

            {
                "toPort": -1,
                "cidrs": [],
                "ipv6Cidrs": [
                    "::/0"
                ],
                "protocol": "icmpv6",
                "cidrListAliases": [],
                "fromPort": -1
            },

I also see that the UI uses PutInstancePublicPorts behind the scenes vs. OpenInstancePublicPorts in the Terraform resource code, but I suspect that it doesn't really matter as long as the two APIs are used correctly.

At this point, I would recommend either opening an AWS support ticket (since all tools/SDKs + docs don't seem to support icmpv6), or an issue at the aws-sdk-go-v2 GitHub repository. Only then we can make the downstream changes in the Terraform AWS Provider.

nbensa commented 5 months ago

Oh. It indeed works ok using aws-cli and put-instance-public-ports

aws lightsail put-instance-public-ports --cli-input-json '{"portInfos":[{"fromPort":128,"toPort":0,"protocol":"icmpv6","cidrs":[],"ipv6Cidrs":["::/0"],"cidrListAliases":[]}],"instanceName":"my-lightsail-instance"}'

I got a success response:

{
    "operation": {
        "id": "5ee6b65c-0252-44c6-a4dc-d19a76fd1932",
        "resourceName": "my-lightsail-instance",
        "resourceType": "Instance",
        "createdAt": "2024-04-03T02:22:24.971000-03:00",
        "location": {
            "availabilityZone": "us-east-2a",
            "regionName": "us-east-2"
        },
        "isTerminal": true,
        "operationDetails": "128-0/icmpv6",
        "operationType": "PutInstancePublicPorts",
        "status": "Succeeded",
        "statusChangedAt": "2024-04-03T02:22:24.971000-03:00"
    }
}
acwwat commented 5 months ago

Thanks @nbensa for the additional info. Since there just seems to be inconsistent support, I've opened an AWS support case from my own account asking for the following:

  1. Check and make sure that both OpenInstancePublicPorts and PutInstancePublicPorts APIs do indeed support icmpv6 as the protocol.
  2. Update the API reference for the icmpv6 protcol as appropriate.
  3. Ensure that AWS CLI supports both.
  4. Ensure that AWS Go SDK v2 supports both. Also ensure that all other SDKs support the same.

This issue will probably take some time to resolve but we should be on the right track.