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

aws_customer_gateway updates existing manually created cgw when it has same IP address #7492

Closed
kiich opened this issue Jul 5, 2016 · 8 comments · Fixed by #12501
Closed

Comments

@kiich
Copy link

kiich commented Jul 5, 2016

Runing terraform on centos 6.6 with Terraform v0.6.15

And using aws_customer_gateway resource like this:

resource "aws_customer_gateway" "cgw" {
   bgp_asn = 65000
   ip_address = "192.1.1.1"
   type = "ipsec.1"
   tags {
      Name                = "terraform test"
      Terraform           = "true"
   }
}

The above all works fine when i do not have any other customer gateway in my AWS. However, if i create a cgw manually from AWS console with the SAME IP first and run the above, it updates the manually created one instead where as i was expecting it to fail like it does when i try to do the same (create another cgw with already existing IP).

This isn't such a big deal but it did confuse me when i couldn't do terraform destroy because it thought the cgw was in use (which it was by another manually created VPN i have) when i expected the destroy to succeed as i assumed the terraform run created its own version of cgw.

Probably not a bug but would be good to get it clarified and some how mentioned in doc.

Expected Behavior

terraform plan to some how show the cgw resource can not be created because it already sees another cgw with the same IP which was created OUTSIDE of terraform with same IP.

Actual Behavior

terraform UPDATES existing customer gateway resource which was not created by terraform.

terraform plan:
[...]

  • module.vpn.aws_customer_gateway.cgw
    bgp_asn: "" => "65000"
    ip_address: "" => "192.1.1.1"
    tags.#: "" => "4"
    tags.Name: "" => "terraform test"
    tags.Terraform: "" => "true"
    type: "" => "ipsec.1"

terraform apply:
module.vpn.aws_customer_gateway.cgw: Creating...
bgp_asn: "" => "65000"
ip_address: "" => "192.1.1.1"
tags.#: "" => "4"
tags.Name: "" => "terraform test"
tags.Terraform: "" => "true"
type: "" => "ipsec.1"

module.vpn.aws_customer_gateway.cgw: Creation complete

but destory fails:
Error applying plan:

1 error(s) occurred:

  • aws_customer_gateway.cgw: IncorrectState: The customer gateway is in use.
    status code: 400, request id: 551be6a7-cf76-45aa-b4f4-8958416ef465

somehow even more dangerous, if the cgw in question is not in use, terraform actually destroys it even though it was not initially created by terraform.

@stack72
Copy link
Contributor

stack72 commented Sep 26, 2016

Hi @kiich

I agree with you that Terraform isn't behaving correct in this scenario - I will try and address that now. when i create a gateway using your config and then add another gateway manually (via the console), I get the following:

screen shot 2016-09-26 at 14 37 31

I am going to try and make Terraform respect the same behaviour

Paul

@stack72
Copy link
Contributor

stack72 commented Sep 26, 2016

Hi @kiich

Ok, on further investigation here, this isn't actually a Terraform bug. I have just followed the following steps:

  1. Create Customer Gateway with the following config:
resource "aws_customer_gateway" "cgw" {
   bgp_asn = 65000
   ip_address = "192.1.1.1"
   type = "ipsec.1"
   tags {
      Name                = "terraform test"
      Terraform           = "true"
   }
}

I can see that this has been created as per the console:

screen shot 2016-09-26 at 15 07 41

On trying to use the console to add another gateway with the same IP and BGP, I get the error above. But when I use the AWS cli, I get the following:

% aws ec2 create-customer-gateway --type ipsec.1 --bgp-asn 65000 --public-ip 192.1.1.1                                                                                                                  2 ↵
{
    "CustomerGateway": {
        "CustomerGatewayId": "cgw-cd528bd3",
        "IpAddress": "192.1.1.1",
        "State": "available",
        "Type": "ipsec.1",
        "BgpAsn": "65000"
    }
}

As you can see, that customer gateway id returned from the CREATE on the CLI is the same as that in the Terraform created configuration (As per the screenshot!)

I believe the SDK is behaving in the same way as the cli and thus why Terraform is taking control of the gateway. I am going to raise this with the SDK team now

Thanks

Paul

@stack72
Copy link
Contributor

stack72 commented Sep 26, 2016

FYI, I raised this issue aws/aws-sdk-go#855

@stack72 stack72 self-assigned this Sep 26, 2016
@kiich
Copy link
Author

kiich commented Sep 26, 2016

Hey @stack72 - cheers for looking into this and raising the bug against the sdk! Will keep an eye on that as well.

@johananl
Copy link
Contributor

johananl commented Jan 1, 2017

Hi @stack72, @kiich,

Looking at the answer from AWS on aws/aws-sdk-go#855, adding a CGW using the CLI or the AWS API is idempotent. I've also verified this myself.

So, this indeed creates a problem since Terraform might "take over" a resource it didn't create and potentially overwrite its tags and / or destroy it by accident. This is exactly what happened to me, which brought me here :-)

I'm not sure now what the expected Terraform behavior should be. Perhaps the existing CGW should not be added to the state and simply "ignored" somehow when it already exists.
This is quite a unique case on AWS since normally you would get an error in these situations.

What do you think?

@kashook
Copy link

kashook commented Feb 9, 2017

I recently ran into this using Terraform 0.8.6. In my case, the Customer Gateway had been created with another Terraform. I didn't realize it until I tried to destroy the second Terraform, and it (fortunately) failed when trying to delete the gateway because it was actually in use by a VPN connection. The second Terraform modified the Name tag of the original resource in AWS (which was quite confusing at first).

The AWS documentation does clearly state that calling create-customer-gateway with the same VPN type, IP address, and BGP ASN parameter values will return the existing gateway. However, consider this Terraform example. (The IP is of course not actually a VPN device, but that doesn't matter for this example).

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

resource "aws_customer_gateway" "my_customer_gateway" {
  bgp_asn    = "65530"
  ip_address = "8.8.8.8"
  type       = "ipsec.1"

  tags {
    Name = "test"
  }
}

resource "aws_customer_gateway" "my_customer_gateway2" {
  bgp_asn    = "65530"
  ip_address = "8.8.8.8"
  type       = "ipsec.1"

  tags {
    Name = "test2"
  }
}

When I run that, only one gateway is actually created. However, Terraform acts like it created two separate resources. Whichever one had the create call issued last "wins". (The Name tag on the one actual resource is modified). The tfstate file has two different gateways in it, each with the Name as specified in the tf file, but they happen to have the same id.

E:\hg\ca\terraform-testcg>terraform apply
aws_customer_gateway.my_customer_gateway2: Creating...
  bgp_asn:    "" => "65530"
  ip_address: "" => "8.8.8.8"
  tags.%:     "" => "1"
  tags.Name:  "" => "test2"
  type:       "" => "ipsec.1"
aws_customer_gateway.my_customer_gateway: Creating...
  bgp_asn:    "" => "65530"
  ip_address: "" => "8.8.8.8"
  tags.%:     "" => "1"
  tags.Name:  "" => "test"
  type:       "" => "ipsec.1"
aws_customer_gateway.my_customer_gateway2: Still creating... (10s elapsed)
aws_customer_gateway.my_customer_gateway: Still creating... (10s elapsed)
aws_customer_gateway.my_customer_gateway2: Creation complete
aws_customer_gateway.my_customer_gateway: Creation complete

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Now, when I run a plan, Terraform shows that it is going to modify the resource that "lost" because the name tag doesn't match. I am running the exact same Terraform twice in a row with no changes, yet it wants to modify something (and always will).

E:\hg\ca\terraform-testcg>terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but
will not be persisted to local or remote state storage.

aws_customer_gateway.my_customer_gateway: Refreshing state... (ID: cgw-9a6188f3)
aws_customer_gateway.my_customer_gateway2: Refreshing state... (ID: cgw-9a6188f3)

The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed. Cyan entries are data sources to be read.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

~ aws_customer_gateway.my_customer_gateway2
    tags.Name: "test" => "test2"


Plan: 0 to add, 1 to change, 0 to destroy.

When I destroy, Terraform once again acts like there are two resources:

E:\hg\ca\terraform-testcg>terraform destroy -force
aws_customer_gateway.my_customer_gateway2: Refreshing state... (ID: cgw-9a6188f3)
aws_customer_gateway.my_customer_gateway: Refreshing state... (ID: cgw-9a6188f3)
aws_customer_gateway.my_customer_gateway: Destroying...
aws_customer_gateway.my_customer_gateway2: Destroying...
aws_customer_gateway.my_customer_gateway: Destruction complete
aws_customer_gateway.my_customer_gateway2: Destruction complete

Destroy complete! Resources: 2 destroyed.

The fact that Terraform is giving the impression that there are two resources when there really aren't seems weird to me.

This example is a bit contrived, but I think it shows odd behavior. If this behavior was addressed, it would also happen to fix the real life scenario myself and the OP described where some customer gateway already exists and was created externally to the terraform.

If Terraform is actually supposed to behave this way, then at the very least I think the docs should have a warning similar to the warning in the AWS documentation IMHO.

stack72 added a commit that referenced this issue Mar 7, 2017
Fixes: #7492

When we use the same IP Address, BGP ASN and VPN Type as an existing
aws_customer_gateway, terraform will take control of that gateway (not
import it!) and try and modify it. This could be very bad

There is a warning on the AWS documentation that one gateway of the same
parameters can be created, Terraform is now going to error if a gateway
of the same parameters is attempted to be created

```
% make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSCustomerGateway_'
==> Checking that code complies with gofmt requirements...
go generate $(go list ./... | grep -v /terraform/vendor/)
2017/03/07 18:40:39 Generated command/internal_plugin_list.go
TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSCustomerGateway_ -timeout 120m
=== RUN   TestAccAWSCustomerGateway_importBasic
--- PASS: TestAccAWSCustomerGateway_importBasic (31.11s)
=== RUN   TestAccAWSCustomerGateway_basic
--- PASS: TestAccAWSCustomerGateway_basic (68.72s)
=== RUN   TestAccAWSCustomerGateway_similarAlreadyExists
--- PASS: TestAccAWSCustomerGateway_similarAlreadyExists (35.18s)
=== RUN   TestAccAWSCustomerGateway_disappears
--- PASS: TestAccAWSCustomerGateway_disappears (25.13s)
PASS
ok  	github.com/hashicorp/terraform/builtin/providers/aws	160.172s
```
stack72 added a commit that referenced this issue Mar 7, 2017
Fixes: #7492

When we use the same IP Address, BGP ASN and VPN Type as an existing
aws_customer_gateway, terraform will take control of that gateway (not
import it!) and try and modify it. This could be very bad

There is a warning on the AWS documentation that one gateway of the same
parameters can be created, Terraform is now going to error if a gateway
of the same parameters is attempted to be created

```
% make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSCustomerGateway_'
==> Checking that code complies with gofmt requirements...
go generate $(go list ./... | grep -v /terraform/vendor/)
2017/03/07 18:40:39 Generated command/internal_plugin_list.go
TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSCustomerGateway_ -timeout 120m
=== RUN   TestAccAWSCustomerGateway_importBasic
--- PASS: TestAccAWSCustomerGateway_importBasic (31.11s)
=== RUN   TestAccAWSCustomerGateway_basic
--- PASS: TestAccAWSCustomerGateway_basic (68.72s)
=== RUN   TestAccAWSCustomerGateway_similarAlreadyExists
--- PASS: TestAccAWSCustomerGateway_similarAlreadyExists (35.18s)
=== RUN   TestAccAWSCustomerGateway_disappears
--- PASS: TestAccAWSCustomerGateway_disappears (25.13s)
PASS
ok  	github.com/hashicorp/terraform/builtin/providers/aws	160.172s
```
stack72 added a commit that referenced this issue Mar 8, 2017
#12501)

Fixes: #7492

When we use the same IP Address, BGP ASN and VPN Type as an existing
aws_customer_gateway, terraform will take control of that gateway (not
import it!) and try and modify it. This could be very bad

There is a warning on the AWS documentation that one gateway of the same
parameters can be created, Terraform is now going to error if a gateway
of the same parameters is attempted to be created

```
% make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSCustomerGateway_'
==> Checking that code complies with gofmt requirements...
go generate $(go list ./... | grep -v /terraform/vendor/)
2017/03/07 18:40:39 Generated command/internal_plugin_list.go
TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSCustomerGateway_ -timeout 120m
=== RUN   TestAccAWSCustomerGateway_importBasic
--- PASS: TestAccAWSCustomerGateway_importBasic (31.11s)
=== RUN   TestAccAWSCustomerGateway_basic
--- PASS: TestAccAWSCustomerGateway_basic (68.72s)
=== RUN   TestAccAWSCustomerGateway_similarAlreadyExists
--- PASS: TestAccAWSCustomerGateway_similarAlreadyExists (35.18s)
=== RUN   TestAccAWSCustomerGateway_disappears
--- PASS: TestAccAWSCustomerGateway_disappears (25.13s)
PASS
ok  	github.com/hashicorp/terraform/builtin/providers/aws	160.172s
```
stack72 added a commit that referenced this issue Mar 8, 2017
#12501)

Fixes: #7492

When we use the same IP Address, BGP ASN and VPN Type as an existing
aws_customer_gateway, terraform will take control of that gateway (not
import it!) and try and modify it. This could be very bad

There is a warning on the AWS documentation that one gateway of the same
parameters can be created, Terraform is now going to error if a gateway
of the same parameters is attempted to be created

```
% make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSCustomerGateway_'
==> Checking that code complies with gofmt requirements...
go generate $(go list ./... | grep -v /terraform/vendor/)
2017/03/07 18:40:39 Generated command/internal_plugin_list.go
TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSCustomerGateway_ -timeout 120m
=== RUN   TestAccAWSCustomerGateway_importBasic
--- PASS: TestAccAWSCustomerGateway_importBasic (31.11s)
=== RUN   TestAccAWSCustomerGateway_basic
--- PASS: TestAccAWSCustomerGateway_basic (68.72s)
=== RUN   TestAccAWSCustomerGateway_similarAlreadyExists
--- PASS: TestAccAWSCustomerGateway_similarAlreadyExists (35.18s)
=== RUN   TestAccAWSCustomerGateway_disappears
--- PASS: TestAccAWSCustomerGateway_disappears (25.13s)
PASS
ok  	github.com/hashicorp/terraform/builtin/providers/aws	160.172s
```
yanndegat pushed a commit to yanndegat/terraform that referenced this issue Mar 13, 2017
hashicorp#12501)

Fixes: hashicorp#7492

When we use the same IP Address, BGP ASN and VPN Type as an existing
aws_customer_gateway, terraform will take control of that gateway (not
import it!) and try and modify it. This could be very bad

There is a warning on the AWS documentation that one gateway of the same
parameters can be created, Terraform is now going to error if a gateway
of the same parameters is attempted to be created

```
% make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSCustomerGateway_'
==> Checking that code complies with gofmt requirements...
go generate $(go list ./... | grep -v /terraform/vendor/)
2017/03/07 18:40:39 Generated command/internal_plugin_list.go
TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSCustomerGateway_ -timeout 120m
=== RUN   TestAccAWSCustomerGateway_importBasic
--- PASS: TestAccAWSCustomerGateway_importBasic (31.11s)
=== RUN   TestAccAWSCustomerGateway_basic
--- PASS: TestAccAWSCustomerGateway_basic (68.72s)
=== RUN   TestAccAWSCustomerGateway_similarAlreadyExists
--- PASS: TestAccAWSCustomerGateway_similarAlreadyExists (35.18s)
=== RUN   TestAccAWSCustomerGateway_disappears
--- PASS: TestAccAWSCustomerGateway_disappears (25.13s)
PASS
ok  	github.com/hashicorp/terraform/builtin/providers/aws	160.172s
```
@kiich
Copy link
Author

kiich commented Mar 20, 2017

@johananl Ignoring existing resource TF didn't create sounds like an option and somehow catch that the call to create CGW returned with already existing resource. I guess when I initially created this issue, i was more concerned about the deletion of cgw that TF didn't create.

dmrzzz added a commit to techservicesillinois/aws-enterprise-vpc that referenced this issue May 10, 2017
…and also that several workarounds formerly attributed to hashicorp/terraform#1497 are actually more closely related to hashicorp/terraform#4149 (and are still necessary for greenfield VPC construction since the value used in count comes from a resource created by Terraform)
@ghost
Copy link

ghost commented Apr 15, 2020

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.

@ghost ghost locked and limited conversation to collaborators Apr 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants