Giter Club home page Giter Club logo

terraform-provider-packetfabric's Introduction

Release release-date contributors commit-activity License

PacketFabric Terraform Provider

Requirements

  • Terraform v1.2.2
  • Go 1.18.2 (to build the provider plugin)

Standard Provider usage

See the PacketFabric Provider documentation for resource definition and data-source structure and examples.

Versioning policy

0.0.0
| | |
| | +-- backward compatible changes (bug fixes)
| +---- backward compatible changes (new features)
+------ backward incompatible changes

We are following a version numbering system (e.g. v1.2.4) and will not make breaking changes to major version (e.g. v1.0.0) except in exceptional circumstances. If a breaking change is necessary, we will release a new major version (e.g. v2.0.0) and provide at least three months of bug fixes for the previous major version to allow users time to make necessary changes to their code.

Building and installing the Provider locally

$ git clone [email protected]:packetfabric/terraform-provider-packetfabric
$ make install
go build -o terraform-provider-packetfabric
mkdir -p ~/.terraform.d/plugins/[YOURHOSTNAME]/packetfabric/packetfabric/0.0.1/linux_amd64
mv terraform-provider-packetfabric ~/.terraform.d/plugins/[YOURHOSTNAME]/packetfabric/packetfabric/0.0.1/linux_amd64

Using the local build/installed provider

terraform {
  required_providers {
    packetfabric = {
      source  = "[YOURHOSTNAME]/packetfabric/packetfabric"
      version = "~> 0.0.1"
    }
  }
}

Contributing Documentation

Markdown documents found in this repository are the source of the PacketFabric Provider documentation. These source documents are generated using the Terraform-Plugin-Docs Tools.

Data-Source and Resource field descriptions are pulled from the internal/provider source-code. It's organized based on the resource and data-source matching markdown template found in templates and merged with examples found in the examples

Updating the provider function field descriptions should be done in internal/provider code schema descriptions. Structural changes to the MD formating should be done in the templates tmpls files.

Caveat: As of tfplugindocs 0.10.1, Nested schema elements are not properly discovered and inserted at generation time. This means data-source function field descriptions must be manually managed in the templates tmpls files for data-sources.

Developing The Provider

To work on the provider, you'll need Go installed on your machine (version 1.11+ is required). You'll need to correctly setup a GOPATH, as well as adding $GOPATH/bin to your $PATH.

To compile, run make build. To compile and install, run make install . This will build (and install) the provider and put the provider binary in the $GOPATH/bin directory.

$ make build
...
$ $GOPATH/bin/terraform-provider-packetfabric
...

To test the provider, run make test.

$ make test

To check changes you made locally to the provider, you can use the binary you compiled by adding the following to your ~/.terraformrc file. This is valid for Terraform 0.14+. See Terraform's documentation for more details.

provider_installation {

  # Use /home/developer/go/bin as an overridden package directory
  # for the PacketFabric/packetfabric provider. This disables the version and checksum
  # verifications for this provider and forces Terraform to look for the
  # packetfabric provider plugin in the given directory.
  dev_overrides {
    "PacketFabric/packetfabric" = "/home/developer/go/bin"
  }

  # For all other providers, install them directly from their origin provider
  # registries as normal. If you omit this, Terraform will _only_ use
  # the dev_overrides block, and so no other providers will be available.
  direct {}
}

For information about writing acceptance tests, see the main Terraform contributing guide.

Acceptance Tests

To run acceptance tests on your local machine, you have to set the following environmental variables:

export PF_HOST="https://api.packetfabric.com"
export PF_TOKEN="api-secret"
export PF_ACCOUNT_ID="123456789"
export PF_USER_EMAIL="[email protected]"

Some tests require specific environment variables to be set. You can find examples of these variables in the source_env_var.sh.sample file.

Warning: Running below command will order various PacketFabric products, then delete them.

You can test the provider using different methods. Here are some common scenarios:

Running All Tests

To run all tests, you can use the all tag. Navigate to the internal/provider directory and run the following command:

$ cd internal/provider;  TF_ACC=1 go test -v -timeout 120m -tags=all

Warning: Add -parallel 1 if running the test in dev environement.

Running Tests with Specific Tags

If you want to run a subset of tests, you can do so by specifying the relevant tag. For example, to run tests that have been tagged with smoke, use the following command:

$ cd internal/provider;  TF_ACC=1 go test -v -timeout 120m -tags=smoke

Running Individual Tests

You can also run individual tests by specifying the test's function name with the -run flag. For example, to run the TestAccPort test, use the following command:

$ cd internal/provider; TF_ACC=1 go test -v -timeout 30m -tags=all -run=TestAccPort

Note: Setting the TF_ACC environment variable to 1 enables acceptance tests, which hit real APIs and can take a long time to run.

If you want to know the current list of acceptance tests available without executing them, run the following command:

cd internal/provider; go test -tags=all -cover -v | grep -v testutil.go | grep -v github.com

Releasing the Provider

This provider is published using GitHub Actions triggered by tagging a branch using semantic versioning with the pattern v*(Example: v1.5.3)

Once the branch is tagged the release is built and publish via the Terraform Registry.

Provider release candidates will be based on main-branch and be committed on their own, dedicated, dev branch. The release branch will be qualified and UAT then merged with main. A new Release branch will be created from main at the merge point. The Release branch will be tagged for publishing. This process allows us to support multiple versions of the provider simultaneously if desired.

terraform-provider-packetfabric's People

Contributors

andreassteinerpf avatar annaclaiborne avatar caitlinwheeless avatar dependabot[bot] avatar elxaptation avatar medzin avatar omegastick avatar pfarmer avatar pontovinte avatar rjouhann avatar solababs avatar vgvm-pf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

terraform-provider-packetfabric's Issues

Ability to filter on packetfabric data sources

We would like to have the option to use a filter{} on following PacketFabric data sources's outputs:

  • packetfabric_port
  • packetfabric_outbound_cross_connect
  • packetfabric_virtual_circuits
  • packetfabric_point_to_point
  • packetfabric_cs_dedicated_connections
  • packetfabric_cloud_router
  • packetfabric_cloud_router_connections
  • packetfabric_cloud_router_bgp_session
  • packetfabric_marketplace_service_requests
  • packetfabric_quick_connect_requests
  • packetfabric_billing
  • packetfabric_locations
  • packetfabric_locations_cloud
  • packetfabric_locations_regions
  • packetfabric_locations_markets
  • packetfabric_activity_log

Example:

Filter on the packetfabric_locations data source, we need to be able to filter on a pop for example to get the site_code.

Example:

data "packetfabric_locations" "main" {
  provider = packetfabric
  filter {
    pop = var.pf_interface_pop
  }
}

# Create Cross Connect
resource "packetfabric_outbound_cross_connect" "crossconnect_1" {
  provider = packetfabric
  description = "${var.tag_name}-${random_pet.name.id}"
  document_uuid = var.pf_document_uuid1
  port = packetfabric_interface.interface_1.id
  site = data.packetfabric_locations.main.site_code
}

packetfabric_backbone_virtual_circuit delete isn't working

The packetfabric_outbound_cross_connect delete isn't using the correct API.

It should be using: DELETE /v2/services/{vc_circuit_id} (https://docs.packetfabric.com/api/v2/swagger/#/Services/delete_service)

Creation works fine but return this error:

╷
│ Error: Status: 404, body: {"message": "Cloud not found: PF-BC-PDX-NYC-1743975-PF", "request_id": "f03bd549-e87b-4195-9580-7dd597b6b85a"}
│ 
│ 

I think this is related to the renaming #50.

packetfabric_cloud_services_aws_create_backbone_dedicated_cr: rename to packetfabric_backbone_virtual_circuit.
The API is a bit misleading but all those resources are pointing to the same API /v2/services/backbone which is also documented here.

packetfabric_cs_aws_hosted_connection: src_svlan should be optional

As per schema, src_svlan should be optional

resource "packetfabric_cs_aws_hosted_connection" "cs_conn1" {
  provider = packetfabric
  description = "${var.tag_name}-${random_pet.name.id}"
  account_uuid = var.pf_account_uuid
  aws_account_id = var.pf_aws_account_id
  port = "PF-AP-WDC1-1726464" # packetfabric_interface.interface_1.id
  speed = var.pf_cs_speed2
  pop = var.pf_cs_pop2
  vlan = var.pf_cs_vlan2
  zone = var.pf_cs_zone2
}

Output and error:

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # packetfabric_cs_aws_hosted_connection.cs_conn1 will be created
  + resource "packetfabric_cs_aws_hosted_connection" "cs_conn1" {
      + account_uuid   = "24a0aef3-2784-48dc-9a8e-52d44d6da646"
      + aws_account_id = "687236962849"
      + description    = "demo-ngena-live-teal"
      + id             = (known after apply)
      + pop            = "DEN1"
      + port           = "PF-AP-WDC1-1726464"
      + speed          = "50Mbps"
      + vlan           = 107
      + zone           = "E"
    }

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

Changes to Outputs:
  + packetfabric_cs_aws_hosted_connection = {
      + account_uuid   = "24a0aef3-2784-48dc-9a8e-52d44d6da646"
      + aws_account_id = "687236962849"
      + description    = "demo-ngena-live-teal"
      + id             = (known after apply)
      + pop            = "DEN1"
      + port           = "PF-AP-WDC1-1726464"
      + speed          = "50Mbps"
      + src_svlan      = null
      + vlan           = 107
      + zone           = "E"
    }
packetfabric_cs_aws_hosted_connection.cs_conn1: Creating...

│ Error: Status: 400, body: {"message": "src_svlan: ensure this value is greater than or equal to 4", "request_id": "bc9b7e7c-0086-42b4-9b70-ea772408197b"}
│ 
│   with packetfabric_cs_aws_hosted_connection.cs_conn1,
│   on main.tf line 53, in resource "packetfabric_cs_aws_hosted_connection" "cs_conn1":
│   53: resource "packetfabric_cs_aws_hosted_connection" "cs_conn1" {
│ 
╵

packetfabric_cloud_router: panic: interface conversion: interface {} is []interface {}, not *schema.Set

I was re-trying the existing cloud_router_aws use case example with the latest code on feature/google-service branch and the provider crashed at the Cloud Router creation. see below

packetfabric_cloud_router.cr: Creating...

╷
│ Error: Plugin did not respond
│ 
│   with packetfabric_cloud_router.cr,
│   on main.tf line 365, in resource "packetfabric_cloud_router" "cr":
│  365: resource "packetfabric_cloud_router" "cr" {
│ 
│ The plugin encountered an error, and failed to respond to the plugin.(*GRPCProvider).ApplyResourceChange call. The plugin
│ logs may contain more details.
╵

Stack trace from the terraform-provider-packetfabric plugin:

panic: interface conversion: interface {} is []interface {}, not *schema.Set

goroutine 31 [running]:
github.com/PacketFabric/terraform-provider-packetfabric/internal/provider.extractRegions(0x10?)
	/working/terraform-provider-packetfabric/internal/provider/resource_cloud_router.go:186 +0x2f6
github.com/PacketFabric/terraform-provider-packetfabric/internal/provider.extractCloudRouter(0xd602c0?)
	/working/terraform-provider-packetfabric/internal/provider/resource_cloud_router.go:179 +0x1d0
github.com/PacketFabric/terraform-provider-packetfabric/internal/provider.resourceCloudRouterCreate({0xd60288?, 0xc0000cb320?}, 0xb615e0?, {0xc35880?, 0xc0003b0480})
	/working/terraform-provider-packetfabric/internal/provider/resource_cloud_router.go:85 +0x8a
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).create(0xc0001229a0, {0xd602c0, 0xc0004daae0}, 0xd?, {0xc35880, 0xc0003b0480})
	/root/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/resource.go:707 +0x12e
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).Apply(0xc0001229a0, {0xd602c0, 0xc0004daae0}, 0xc000099380, 0xc000091c80, {0xc35880, 0xc0003b0480})
	/root/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/resource.go:837 +0xa7a
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).ApplyResourceChange(0xc0002423f0, {0xd60218?, 0xc00007ee40?}, 0xc0004ac9b0)
	/root/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/grpc_provider.go:1021 +0xe3c
github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server.(*server).ApplyResourceChange(0xc000254d20, {0xd602c0?, 0xc0004da300?}, 0xc000489b20)
	/root/go/pkg/mod/github.com/hashicorp/[email protected]/tfprotov5/tf5server/server.go:812 +0x515
github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5._Provider_ApplyResourceChange_Handler({0xc0bb20?, 0xc000254d20}, {0xd602c0, 0xc0004da300}, 0xc0000cac00, 0x0)
	/root/go/pkg/mod/github.com/hashicorp/[email protected]/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go:385 +0x170
google.golang.org/grpc.(*Server).processUnaryRPC(0xc0002a88c0, {0xd62ff0, 0xc000003d40}, 0xc000405320, 0xc00034b6b0, 0x11e7b20, 0x0)
	/root/go/pkg/mod/google.golang.org/[email protected]/server.go:1283 +0xcfd
google.golang.org/grpc.(*Server).handleStream(0xc0002a88c0, {0xd62ff0, 0xc000003d40}, 0xc000405320, 0x0)
	/root/go/pkg/mod/google.golang.org/[email protected]/server.go:1620 +0xa1b
google.golang.org/grpc.(*Server).serveStreams.func1.2()
	/root/go/pkg/mod/google.golang.org/[email protected]/server.go:922 +0x98
created by google.golang.org/grpc.(*Server).serveStreams.func1
	/root/go/pkg/mod/google.golang.org/[email protected]/server.go:920 +0x28a

Error: The terraform-provider-packetfabric plugin crashed!

This is always indicative of a bug within the plugin. It would be immensely
helpful if you could report the crash with the plugin's maintainers so that it
can be fixed. The output above should help diagnose the issue.

Resource and data source names do not follow Terraform naming best practices

Resource and data source names do not follow Terraform naming best practices. All names should start with the provider's name, followed by an underscore. Please see the following docs:

https://www.terraform.io/plugin/sdkv2/best-practices/naming#resource-names

It is a widely adopted convention - I have never used a provider that would not follow it.

For example following resource:

resource "cloud_router" "new" {
  provider     = packetfabric
  scope        = "private"
  asn          = "1234"
  name         = "Medzin Test"
  account_uuid = "UUID"
  capacity     = "5Gbps"
  regions      = ["US"]
}

Should be renamed to look like this:

resource "packetfabric_cloud_router" "new" {
  provider     = packetfabric
  scope        = "private"
  asn          = "1234"
  name         = "Medzin Test"
  account_uuid = "UUID"
  capacity     = "5Gbps"
  regions      = ["US"]
}

Not possible to setup BFD setting with cloud_router_bgp_session

Everything is in the title, see docs

_BFD settings
Select Enable BFD to enable Bidirectional Forwarding Detection (BFD) for this connection.

When BFD is enabled, test packets are periodically sent to BGP peers. If a peer fails to reply after a specified interval and number of attempts, the BGP session shuts down._

Destroy not working: OutboundCrossConnect not found

When creating 2 ports and 2 outbound cross-connect, the destroy isn't working

╷
│ Error: Status: 404, body: {"message": "OutboundCrossConnect not found: 904b7c1c-db62-4572-bd10-b85ce4c8fd52", "request_id": "9593aa80-5232-40ef-a65f-188ae2f7b605"}
│ 
│ 
╷
│ Error: Status: 404, body: {"message": "OutboundCrossConnect not found: 56c8ac9f-155f-44be-bd42-2e213e5aeb64", "request_id": "f614c5a0-930e-48e6-98c5-6d7f4bdf8f92"}
│ 
│ 
╵

packetfabric_cs_aws_dedicated_connection: Error: Provider produced inconsistent result after apply

While trying to create a dedicated connection using packetfabric_cs_aws_dedicated_connection provider, I am getting this error:

│ Error: Provider produced inconsistent result after apply
│ 
│ When applying changes to packetfabric_cs_aws_dedicated_connection.pf_cs_conn1, provider
│ "provider[\"terraform.local/packetfabric/packetfabric\"]" produced an unexpected new value: Root resource was present, but
│ now absent.
│ 
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
╵

The connection gets created successfully in PacketFabric despite the error in terraform execution.

See below terraform config used:

resource "packetfabric_cs_aws_dedicated_connection" "pf_cs_conn1" {
  provider = packetfabric
  aws_region = var.aws_region1
  account_uuid = var.pf_account_uuid
  description = "${var.tag_name}-${random_pet.name.id}"
  zone = var.pf_cs_zone1
  pop = var.pf_cs_pop1
  subscription_term = var.pf_cs_subterm # 1
  service_class = var.pf_cs_srvclass # longhaul
  autoneg = var.pf_cs_aws_d_autoneg # false
  speed = var.pf_cs_speed # 10Gbps
  should_create_lag = var.should_create_lag # false
}

Data Source packetfabric_cs_<aws/azure/google>_<hosted/dedicated>_connection updates

We were thinking it is better for data source to return all cloud connections, then have the user filter on the output if needed using TF fitler{}.

So the following APIs should be used:

GET /v2/services/cloud/connections/hosted

GET /v2/services/cloud/connections/dedicated

Filter on service_provider=aws for

packetfabric_cs_aws_dedicated_connection
packetfabric_cs_aws_hosted_connection
Filter on service_provider=azure for

packetfabric_cs_azure_dedicated_connection
packetfabric_cs_azure_hosted_connection
Filter on service_provider=google for

packetfabric_cs_google_dedicated_connection
packetfabric_cs_google_hosted_connection

I also updated the Tech Spec google doc with have with the same details.

bandwidth: longhaul_type must be specified for for a longhaul virtual circuit

There is a problem with:

  • packetfabric_cloud_services_aws_create_backbone_dedicated_cr
  • packetfabric_cloud_services_azr_backbone
  • packetfabric_cloud_services_gcp_backbone
    (which should be consildated into 1 resource packetfabric_create_backbone_virtual_circuit (see #50)

The creation of the VC isn't working even when specifying the longhaul_type attribute.

https://docs.packetfabric.com/api/v2/swagger/#/Services/post_service_backbone
But also here, here and here (same same).

random_pet.name: Refreshing state... [id=intense-polliwog]
packetfabric_interface.interface_1: Refreshing state... [id=PF-AP-PDX1-1742703]
packetfabric_interface.interface_2: Refreshing state... [id=PF-AP-WDC1-1742702]
data.packetfabric_billing.interface_1: Reading...
data.packetfabric_billing.interface_2: Reading...
data.packetfabric_billing.interface_1: Read complete after 1s [id=9ebd5b5b-1c01-4e68-9e93-eae1fd2218ee]
data.packetfabric_billing.interface_2: Read complete after 1s [id=64a85b7b-d39e-408f-8cb0-3edbd61183c7]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated
with the following symbols:
  + create

Terraform will perform the following actions:

  # packetfabric_cloud_services_azr_backbone.vc1 will be created
  + resource "packetfabric_cloud_services_azr_backbone" "vc1" {
      + description = "demo-ngena-intense-polliwog"
      + epl         = false
      + id          = (known after apply)

      + bandwidth {
          + account_uuid      = "24a0aef3-2784-48dc-9a8e-52d44d6da646"
          + longhaul_type     = "dedicated"
          + speed             = "200Mbps"
          + subscription_term = 1
        }

      + interface_a {
          + port_circuit_id = "PF-AP-PDX1-1742703"
          + untagged        = false
          + vlan            = 4
        }

      + interface_z {
          + port_circuit_id = "PF-AP-WDC1-1742702"
          + untagged        = false
          + vlan            = 5
        }
    }

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

Changes to Outputs:
  ~ packetfabric_billing_interface_1 = {
      ~ id         = "bea71536-5bd2-4176-868b-5f0305a04262" -> "9ebd5b5b-1c01-4e68-9e93-eae1fd2218ee"
        # (2 unchanged elements hidden)
    }
  ~ packetfabric_billing_interface_2 = {
      ~ id         = "4d84e2ad-d074-48ad-9b79-08a68c11409e" -> "64a85b7b-d39e-408f-8cb0-3edbd61183c7"
        # (2 unchanged elements hidden)
    }

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

packetfabric_cloud_services_azr_backbone.vc1: Creating...
╷
│ Error: Status: 400, body: {"message": "bandwidth: longhaul_type must be specified for for a longhaul virtual circuit", "request_id": "ca02330a-adbb-4e34-bd60-ce35867d570b"}
│ 
│   with packetfabric_cloud_services_azr_backbone.vc1,
│   on main.tf line 75, in resource "packetfabric_cloud_services_azr_backbone" "vc1":
│   75: resource "packetfabric_cloud_services_azr_backbone" "vc1" {
│ 
╵

Rename packetfabric_interface to packetfabric_port

Discussed with PF UX and also looked at the API and doc, we should not call this resource and data source packetfabric_interface but packetfabric_port so it's more coherent and we don't introduce a new name.

Make sure we also update the variable names in the examples: pf_interface_pop1 to pf_port_pop1

Add missing examples for AWS

  • Need to add an example for all resources with blank in it:
    • packetfabric_cs_aws_hosted_marketplace_connection (or packetfabric_cloud_services_aws_hosted_marketplace see renaming suggestion #50)
    • packetfabric_cs_aws_hosted_connection (or packetfabric_cloud_services_aws_req_hosted_conn see renaming suggestion #50)

Data Source aws_cloud_connections: cloud_settings should not be an array

In the Data Source aws_cloud_connections, "cloud_settings" should not be in an array "cloud_settings": [{}] but "cloud_settings": {} as there can be only 1 item under cloud_settings (see API).

Current:

          "attributes": {
            "aws_cloud_connections": [
              {
                ...
                "cloud_settings": [
                  {
                    "aws_account_id": "123456789",
                    "aws_connection_id": "dxlag-ffrv4nuo",
                    "aws_hosted_type": "hosted-connection",
                    "aws_region": "us-west-2",
                    "nat_public_ip": "",
                    "public_ip": "1.2.3.4/31",
                    "vlan_id_cust": 7,
                    "vlan_id_pf": 5
                  }
                ],
                ...
              }
            ],
            "circuit_id": "PF-L3-CUST-12345",
            "id": "9a109646-55f5-4e21-95c4-4fc90addc771"
          },

Wanted:

          "attributes": {
            "aws_cloud_connections": [
              {
                ...
                "cloud_settings": {
                    "aws_account_id": "123456789",
                    "aws_connection_id": "dxlag-ffrv4nuo",
                    "aws_hosted_type": "hosted-connection",
                    "aws_region": "us-west-2",
                    "nat_public_ip": "",
                    "public_ip": "1.2.3.4/31",
                    "vlan_id_cust": 7,
                    "vlan_id_pf": 5
                  },
                ...
              }
            ],
            "circuit_id": "PF-L3-CUST-12345",
            "id": "9a109646-55f5-4e21-95c4-4fc90addc771"
          },

output packetfabric_cloud_services_gcp_req_hosted_conn1 sensitive = true

When trying to display the output of packetfabric_cloud_services_gcp_req_hosted_conn1 resource, TF is complaining about the need to add sensitive = true. Looking at the API reference, I don't think there is a need to mandate the sensitive flag.

output "packetfabric_cloud_services_gcp_req_hosted_conn1" {
  value = packetfabric_cloud_services_gcp_req_hosted_conn.cs_conn1
}
│ Error: Output refers to sensitive values
│ 
│   on main.tf line 80:
│   80: output "packetfabric_cloud_services_gcp_req_hosted_conn1" {
│ 
│ To reduce the risk of accidentally exporting sensitive data that was intended to be only internal, Terraform
│ requires that any root module output containing sensitive data be explicitly marked as sensitive, to confirm
│ your intent.
│ 
│ If you do intend to export this data, annotate the output value as sensitive by adding the following
│ argument:
│     sensitive = true
╵

packetfabric_cs_aws_dedicated_connection data source does not exist

packetfabric_cs_aws_dedicated_connection data source does not exist, see error below.

We used to have cloud_services_aws_dedicated_conn which should be the same data source so maybe the rename did not happen part of #50?

│ Error: Invalid data source
│ 
│   on main.tf line 111, in data "packetfabric_cs_aws_dedicated_connection" "pf_cs_conn1":
│  111: data "packetfabric_cs_aws_dedicated_connection" "pf_cs_conn1" {
│ 
│ The provider terraform.local/packetfabric/packetfabric does not support data source
│ "packetfabric_cs_aws_dedicated_connection".
│ 
│ Did you intend to use the managed resource type "packetfabric_cs_aws_dedicated_connection"? If so, declare this using a
│ "resource" block instead of a "data" block.
╵

Terraform config"

data "packetfabric_cs_aws_dedicated_connection" "pf_cs_conn1" {
  provider = packetfabric
}
output "packetfabric_cs_aws_dedicated_connection" {
  value = data.packetfabric_cs_aws_dedicated_connection.pf_cs_conn1
}

Can’t destroy an interface PacketFabric terraform provider

I can create a port using the interface PacketFabric terraform provider but when I run the destroy command, I am getting the following error:

 Error: Get "https://api.packetfabric.com/v2/ports/PF-AP-PDX1-1741048": context canceled
│ 
│   with interface.port_1,
│   on main.tf line 47, in resource "interface" "port_1":
│   47: resource "interface" "port_1" {

See following demo.

packetfabric_outbound_cross_connect: Error: Provider produced inconsistent result after apply

Terraform config:
main.tf

terraform {
  required_providers {
    packetfabric = {
      # source  = "PacketFabric/packetfabric"
      # version = "0.2.0"
      source  = "terraform.local/PacketFabric/packetfabric"
      version = "~> 0.0.0"
    }
  }
}

provider "packetfabric" {
  host  = var.pf_api_server
  token = var.pf_api_key
}

# Create random name to use to name objects
resource "random_pet" "name" {}

# Create a PacketFabric interface
resource "packetfabric_interface" "interface1" {
  provider          = packetfabric
  account_uuid      = var.pf_account_uuid
  autoneg           = var.pf_cs_interface_autoneg
  description       = "${var.tag_name}-${random_pet.name.id}"
  media             = var.pf_cs_interface_media
  nni               = var.pf_cs_interface_nni
  pop               = var.pf_cs_interface_pop
  speed             = var.pf_cs_interface_speed
  subscription_term = var.pf_cs_interface_subterm
  zone              = var.pf_cs_interface_avzone
}
output "packetfabric_interface" {
  value = packetfabric_interface.interface1
}

# Get billing information related to the interface created
data "packetfabric_billing" "interface1" {
  provider = packetfabric
  circuit_id = packetfabric_interface.interface1.id
}
output "packetfabric_billing_interface1" {
  value = data.packetfabric_billing.interface1
}

### Get the site filtering on the pop using packetfabric_locations

# Create Cross Connect
resource "packetfabric_outbound_cross_connect" "crossconnect1" {
  provider = packetfabric
  description = "${var.tag_name}-${random_pet.name.id}"
  document_uuid = var.pf_document_uuid
  port = packetfabric_interface.interface1.id
  site = var.pf_cs_interface_site
}
output "packetfabric_outbound_cross_connect" {
  value = packetfabric_outbound_cross_connect.crossconnect1
}

variables.tf

## General VARs
variable "tag_name" {
  default = "demo-ngena"
}


## PacketFabic VARs
variable "pf_api_key" {
  type        = string
  description = "PacketFabric platform API access key"
  sensitive   = true
}
variable "pf_account_uuid" {
  type = string
}
variable "pf_api_server" {
  type        = string
  default     = "https://api.packetfabric.com" # https://api.dev.packetfabric.net
  description = "PacketFabric API endpoint URL"
}
variable "pf_provider_source" {
  type    = string
  default = "packetfabric/packetfabric"
}

# PacketFabric Interface Parameter configuration:
variable "pf_cs_interface_media" {
  type    = string
  default = "LX"
}
variable "pf_cs_interface_avzone" {
  type    = string
  default = "A"
}
variable "pf_cs_interface_pop" {
  type    = string
  default = "MUC1" # PDX1, MUC1
}
variable "pf_cs_interface_subterm" {
  type    = number
  default = 1 # default 1 month
}
# variable "pf_cs_interface_srvclass" {
#   type    = string
#   default = "metro"
# }
variable "pf_cs_interface_autoneg" {
  type    = bool
  default = false
}
variable "pf_cs_interface_speed" {
  type    = string
  default = "1Gbps"
}
variable "pf_cs_interface_nni" {
  type    = bool
  default = false
}

# Cross connect
variable "pf_document_uuid" {
  type    = string
  default = "1d2fb159-b40e-4eda-8f63-1191a80a023e"
}
variable "pf_cs_interface_site" {
  type    = string
  default = "EQ-MU1" # PN-PIT, EQ-MU1
}

Output:

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated
with the following symbols:
  + create
 <= read (data resources)

Terraform will perform the following actions:

  # data.packetfabric_billing.interface1 will be read during apply
  # (config refers to values not yet known)
 <= data "packetfabric_billing" "interface1" {
      + billings   = (known after apply)
      + circuit_id = (known after apply)
      + id         = (known after apply)
    }

  # packetfabric_interface.interface1 will be created
  + resource "packetfabric_interface" "interface1" {
      + account_uuid      = "24a0aef3-2784-48dc-9a8e-52d44d6da646"
      + autoneg           = false
      + description       = (known after apply)
      + id                = (known after apply)
      + media             = "LX"
      + nni               = false
      + pop               = "MUC1"
      + speed             = "1Gbps"
      + subscription_term = 1
      + zone              = "A"
    }

  # packetfabric_outbound_cross_connect.crossconnect1 will be created
  + resource "packetfabric_outbound_cross_connect" "crossconnect1" {
      + description   = (known after apply)
      + document_uuid = "1d2fb159-b40e-4eda-8f63-1191a80a023e"
      + id            = (known after apply)
      + port          = (known after apply)
      + site          = "EQ-MU1"
    }

  # random_pet.name will be created
  + resource "random_pet" "name" {
      + id        = (known after apply)
      + length    = 2
      + separator = "-"
    }

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

Changes to Outputs:
  + packetfabric_billing_interface1     = {
      + billings   = (known after apply)
      + circuit_id = (known after apply)
      + id         = (known after apply)
    }
  + packetfabric_interface              = {
      + account_uuid      = "24a0aef3-2784-48dc-9a8e-52d44d6da646"
      + autoneg           = false
      + description       = (known after apply)
      + id                = (known after apply)
      + media             = "LX"
      + nni               = false
      + pop               = "MUC1"
      + speed             = "1Gbps"
      + subscription_term = 1
      + timeouts          = null
      + zone              = "A"
    }
  + packetfabric_outbound_cross_connect = {
      + data_center_cross_connect_id = null
      + description                  = (known after apply)
      + destination_circuit_id       = null
      + destination_name             = null
      + document_uuid                = "1d2fb159-b40e-4eda-8f63-1191a80a023e"
      + id                           = (known after apply)
      + module                       = null
      + panel                        = null
      + port                         = (known after apply)
      + position                     = null
      + published_quote_line_uuid    = null
      + site                         = "EQ-MU1"
      + timeouts                     = null
      + user_description             = null
    }
╷

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

random_pet.name: Creating...
random_pet.name: Creation complete after 0s [id=premium-duck]

packetfabric_interface.interface1: Creating...
packetfabric_interface.interface1: Still creating... [10s elapsed]
packetfabric_interface.interface1: Still creating... [20s elapsed]
packetfabric_interface.interface1: Still creating... [30s elapsed]
packetfabric_interface.interface1: Still creating... [40s elapsed]
packetfabric_interface.interface1: Still creating... [50s elapsed]
packetfabric_interface.interface1: Still creating... [1m0s elapsed]
packetfabric_interface.interface1: Still creating... [1m10s elapsed]
packetfabric_interface.interface1: Still creating... [1m20s elapsed]
packetfabric_interface.interface1: Creation complete after 1m21s [id=PF-AP-MUC1-1742665]
data.packetfabric_billing.interface1: Reading...
packetfabric_outbound_cross_connect.crossconnect1: Creating...
data.packetfabric_billing.interface1: Read complete after 1s [id=350eadde-7e33-476c-bcb0-1459020c432d]
╷
│ Warning: Outbound Cross Connect Create
│ 
│   with packetfabric_outbound_cross_connect.crossconnect1,
│   on main.tf line 49, in resource "packetfabric_outbound_cross_connect" "crossconnect1":
│   49: resource "packetfabric_outbound_cross_connect" "crossconnect1" {
│ 
│ Outbound Cross Connect is being created
╵
╷
│ Error: Provider produced inconsistent result after apply
│ 
│ When applying changes to packetfabric_outbound_cross_connect.crossconnect1, provider
│ "provider[\"terraform.local/packetfabric/packetfabric\"]" produced an unexpected new value: Root resource was
│ present, but now absent.
│ 
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
╵

However, the cross-connect does get created:
Screen Shot 2022-08-02 at 22 11 02

Error during cloud_services_aws_hosted_connection & cloud_services_aws_req_hosted_conn resources creation

For the following resource:

resource "cloud_services_aws_hosted_connection" "name" {
  provider       = packetfabric
  account_uuid   = "UUID"
  aws_account_id = "123456789012"
  description    = "Test"
  pop            = "LAX1"
  port           = "test"
  speed          = "50Mbps"
  vlan           = 4
}

I get the following error:

panic: interface conversion: interface {} is int, not int64

goroutine 16 [running]:
github.com/PacketFabric/terraform-provider-packetfabric/internal/provider.extractAwsHostedMktConn(0xc0000bf260?)
        /home/medzin/repos/terraform-provider-packetfabric/internal/provider/resource_aws_hosted_mkt_conn.go:102 +0x3ab
github.com/PacketFabric/terraform-provider-packetfabric/internal/provider.resourceAwsHostedMktConnCreate({0xd42c08?, 0xc0000bf260?}, 0xb48f60?, {0xc14420?, 0xc000356540})
        /home/medzin/repos/terraform-provider-packetfabric/internal/provider/resource_aws_hosted_mkt_conn.go:86 +0x8d
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).create(0xc0000eaa80, {0xd42c40, 0xc00046a9f0}, 0xd?, {0xc14420, 0xc000356540})
        /home/medzin/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/resource.go:707 +0x12e
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).Apply(0xc0000eaa80, {0xd42c40, 0xc00046a9f0}, 0xc0001948f0, 0xc000590e00, {0xc14420, 0xc000356540})
        /home/medzin/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/resource.go:837 +0xa7a
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).ApplyResourceChange(0xc00000f0f8, {0xd42b98?, 0xc0000c2800?}, 0xc00046c2d0)
        /home/medzin/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/grpc_provider.go:1021 +0xe3c
github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server.(*server).ApplyResourceChange(0xc0000f00a0, {0xd42c40?, 0xc00046a1e0?}, 0xc00047e000)
        /home/medzin/go/pkg/mod/github.com/hashicorp/[email protected]/tfprotov5/tf5server/server.go:812 +0x515
github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5._Provider_ApplyResourceChange_Handler({0xbf22a0?, 0xc0000f00a0}, {0xd42c40, 0xc00046a1e0}, 0xc0000be420, 0x0)
        /home/medzin/go/pkg/mod/github.com/hashicorp/[email protected]/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go:385 +0x170
google.golang.org/grpc.(*Server).processUnaryRPC(0xc0000ec380, {0xd45930, 0xc0002df380}, 0xc0004b8000, 0xc0002c2a80, 0x11c1b40, 0x0)
        /home/medzin/go/pkg/mod/google.golang.org/[email protected]/server.go:1283 +0xcfd
google.golang.org/grpc.(*Server).handleStream(0xc0000ec380, {0xd45930, 0xc0002df380}, 0xc0004b8000, 0x0)
        /home/medzin/go/pkg/mod/google.golang.org/[email protected]/server.go:1620 +0xa1b
google.golang.org/grpc.(*Server).serveStreams.func1.2()
        /home/medzin/go/pkg/mod/google.golang.org/[email protected]/server.go:922 +0x98
created by google.golang.org/grpc.(*Server).serveStreams.func1
        /home/medzin/go/pkg/mod/google.golang.org/[email protected]/server.go:920 +0x28a

It looks like a problem with the vlan field value type conversion.

packetfabric_cloud_services_gcp_req_hosted_conn: panic: interface conversion: interface {} is nil, not string

Run into this error when trying to use packetfabric_cloud_services_gcp_req_hosted_conn:

Terraform config:

terraform {
  required_providers {
    packetfabric = {
      # source  = "PacketFabric/packetfabric"
      # version = "0.2.0"
      source  = "terraform.local/PacketFabric/packetfabric"
      version = "~> 0.0.0"
    }
  }
}

provider "packetfabric" {
  host  = var.pf_api_server
  token = var.pf_api_key
}

# Create random name to use to name objects
resource "random_pet" "name" {}

resource "packetfabric_interface" "interface_1" {
  provider          = packetfabric
  account_uuid      = var.pf_account_uuid
  autoneg           = var.pf_interface_autoneg
  description       = "${var.tag_name}-${random_pet.name.id}"
  media             = var.pf_interface_media
  nni               = var.pf_interface_nni
  pop               = var.pf_interface_pop1
  speed             = var.pf_interface_speed
  subscription_term = var.pf_interface_subterm
  zone              = var.pf_interface_avzone1
}

resource "packetfabric_cloud_services_gcp_req_hosted_conn" "cs_conn1" {
  provider = packetfabric
  description = "${var.tag_name}-${random_pet.name.id}"
  account_uuid = var.pf_account_uuid
  port = packetfabric_interface.interface_1.id
  speed = var.pf_cs_speed
  googe_pairing_key = var.service_key
  google_vlan_attachment_name = var.vlan_attachement_name
  pop = var.pf_cs_pop1
  vlan = var.pf_cs_vlan1
}

Output:

packetfabric_cloud_services_gcp_req_hosted_conn.cs_conn1: Creating...
╷
│ Error: Plugin did not respond
│ 
│   with packetfabric_cloud_services_gcp_req_hosted_conn.cs_conn1,
│   on main.tf line 68, in resource "packetfabric_cloud_services_gcp_req_hosted_conn" "cs_conn1":
│   68: resource "packetfabric_cloud_services_gcp_req_hosted_conn" "cs_conn1" {
│ 
│ The plugin encountered an error, and failed to respond to the plugin.(*GRPCProvider).ApplyResourceChange
│ call. The plugin logs may contain more details.
╵

Stack trace from the terraform-provider-packetfabric plugin:

panic: interface conversion: interface {} is nil, not string

goroutine 60 [running]:
github.com/PacketFabric/terraform-provider-packetfabric/internal/provider.extractGoogleReqConn(0x11f3620?)
	/working/terraform-provider-packetfabric/internal/provider/resource_google_request_hosted_conn.go:110 +0x3c5
github.com/PacketFabric/terraform-provider-packetfabric/internal/provider.resourceGoogleReqHostConnCreate({0xd5e948?, 0xc0003c2900?}, 0xb600e0?, {0xc33b40?, 0xc0002c3080})
	/working/terraform-provider-packetfabric/internal/provider/resource_google_request_hosted_conn.go:83 +0x8d
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).create(0xc0000b3dc0, {0xd5e980, 0xc00039dfb0}, 0xd?, {0xc33b40, 0xc0002c3080})
	/root/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/resource.go:707 +0x12e
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).Apply(0xc0000b3dc0, {0xd5e980, 0xc00039dfb0}, 0xc000429380, 0xc000127900, {0xc33b40, 0xc0002c3080})
	/root/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/resource.go:837 +0xa7a
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).ApplyResourceChange(0xc0001ca3d8, {0xd5e8d8?, 0xc000283a00?}, 0xc0003cc7d0)
	/root/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/grpc_provider.go:1021 +0xe3c
github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server.(*server).ApplyResourceChange(0xc0001dcb40, {0xd5e980?, 0xc00039d9b0?}, 0xc0004fb2d0)
	/root/go/pkg/mod/github.com/hashicorp/[email protected]/tfprotov5/tf5server/server.go:812 +0x515
github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5._Provider_ApplyResourceChange_Handler({0xc0a500?, 0xc0001dcb40}, {0xd5e980, 0xc00039d9b0}, 0xc0003c2420, 0x0)
	/root/go/pkg/mod/github.com/hashicorp/[email protected]/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go:385 +0x170
google.golang.org/grpc.(*Server).processUnaryRPC(0xc0002308c0, {0xd616b0, 0xc000003a00}, 0xc000425440, 0xc000353620, 0x11e5b00, 0x0)
	/root/go/pkg/mod/google.golang.org/[email protected]/server.go:1283 +0xcfd
google.golang.org/grpc.(*Server).handleStream(0xc0002308c0, {0xd616b0, 0xc000003a00}, 0xc000425440, 0x0)
	/root/go/pkg/mod/google.golang.org/[email protected]/server.go:1620 +0xa1b
google.golang.org/grpc.(*Server).serveStreams.func1.2()
	/root/go/pkg/mod/google.golang.org/[email protected]/server.go:922 +0x98
created by google.golang.org/grpc.(*Server).serveStreams.func1
	/root/go/pkg/mod/google.golang.org/[email protected]/server.go:920 +0x28a

Error: The terraform-provider-packetfabric plugin crashed!

This is always indicative of a bug within the plugin. It would be immensely
helpful if you could report the crash with the plugin's maintainers so that it
can be fixed. The output above should help diagnose the issue.

Rename Data Source packetfabric_aws_cloud_router_connection to packetfabric_cloud_router_connection

Only the creation of a cloud router connection is specific to a cloud provider, the GET Cloud Router Connection details is the same for all.

GET /v2/services/cloud-routers/{circuit_id}/connections/{cloud_connection_circuit_id}

Let's rename existing Data Source packetfabric_aws_cloud_router_connection to packetfabric_cloud_router_connection.

packetfabric_gcp_cloud_router_connection and packetfabric_azr_cloud_router_connection should be removed

AWS, Azure, GCP resources & data source updates (delete/rename)

Screen Shot 2022-08-08 at 17 50 29

############ AWS ############

AWS Resources

  1. packetfabric_cloud_services_aws_create_backbone_dedicated_cr: rename to packetfabric_backbone_virtual_circuit. The API is a bit misleading but all those resources are pointing to the same API /v2/services/backbone which is also documented here.

  2. packetfabric_cloud_services_aws_req_hosted_conn: rename to packetfabric_cs_aws_hosted_connection (removed the req)

  3. packetfabric_cloud_services_aws_hosted_connection: delete? isn't a duplicate of packetfabric_cloud_services_aws_req_hosted_conn

  4. packetfabric_cloud_services_aws_hosted_connections: delete (I believe this is a mistake?)

  5. packetfabric_cloud_services_aws_dedicated: rename to packetfabric_cs_aws_dedicated_connection

  6. packetfabric_cloud_services_aws_hosted_marketplace: rename to packetfabric_cs_aws_hosted_marketplace_connection

  7. packetfabric_cloud_services_aws_provision_requested_mkt_conn: rename to packetfabric_cs_aws_provision_marketplace

AWS Data Source

  1. packetfabric_cloud_services_aws_connection_info: rename to packetfabric_cs_aws_hosted_connection

  2. packetfabric_cloud_services_aws_dedicated_conn: rename to packetfabric_cs_aws_dedicated_connection

  3. packetfabric_aws_services_hosted_requested_mkt_conn: rename to packetfabric_cs_aws_hosted_marketplace_connection

############ Azure ############

Azure Resources

  1. packetfabric_cloud_services_azr_backbone: delete (will be covered with renamed packetfabric_create_backbone_virtual_circuit)

  2. packetfabric_cloud_services_azr_req_express_conn: rename to packetfabric_cs_azure_hosted_connection

  3. packetfabric_cloud_services_azr_req_express_dedicated_conn: renamed to packetfabric_cs_azure_dedicated_connection

  4. packetfabric_cloud_services_azr_hosted_mkt_conn: rename to packetfabric_cs_azure_hosted_marketplace_connection

  5. packetfabric_cloud_services_azr_provision_mkt: rename to packetfabric_cs_azure_provision_marketplace

Azure Data Sources

  1. packetfabric_cloud_services_azr_connection_info: rename to packetfabric_cs_azure_hosted_connection

  2. packetfabric_cloud_services_azr_dedicated_conn: rename to packetfabric_cs_azure_dedicated_connection

  3. packetfabric_azr_services_hosted_requested_mkt_conn: rename to packetfabric_cs_azure_hosted_marketplace_connection

############ Google ############

GCP Resources

  1. packetfabric_cloud_services_gcp_backbone: delete (will be covered with renamed packetfabric_create_backbone_virtual_circuit)

  2. packetfabric_cloud_services_gcp_req_hosted_conn:rename to packetfabric_cs_google_hosted_connection

  3. packetfabric_cloud_services_gcp_dedicated_conn: rename to packetfabric_cs_google_dedicated_connection and missing #55

  4. packetfabric_cloud_services_gcp_hosted_mkt_conn: rename to packetfabric_cs_google_hosted_marketplace_connection

  5. packetfabric_cloud_services_gcp_provision_mkt: rename to packetfabric_cs_google_provision_marketplace

GCP Data Sources

  1. packetfabric_cloud_services_gcp_connection_info: rename to packetfabric_cs_google_hosted_connection

  2. packetfabric_cloud_services_gcp_dedicated_conn: rename to packetfabric_cs_google_dedicated_connection

  3. packetfabric_gcp_services_hosted_requested_mkt_conn: rename to packetfabric_cs_google_hosted_marketplace_connection

unsupported protocol scheme "" error

With the code below:

provider "packetfabric" {
  host  = "api.packetfabric.com"
  token = "xxx"
}

I get the following error:

╷
│ Error: Get "api.packetfabric.com/v2/services/cloud-routers": unsupported protocol scheme ""
│ 
│   with data.cloud_router.current,
│   on main.tf line 15, in data "cloud_router" "current":
│   15: data "cloud_router" "current" {
│ 
╵

Host field uses StringIsNotEmpty validator - I would expect it to use IsURLWithHTTPS or IsURLWithHTTPorHTTPS so the user will get a more meaningful error message.

Cloud router creation with 2 regions (US and UK) creates only with 1 region

Hello,
I was trying to create a CR in the 2 PF regions (US and UK) using the terraform resource cloud_router but I was not able to do it. TF creates the CR with only 1 region.

main.tf

terraform {
  required_providers {
    packetfabric = {
      source  = "PacketFabric/packetfabric"
      version = "0.1.0"
    }
  }
}

provider "packetfabric" {
  host  = var.pf_api_server
  token = var.pf_api_key
}

# Create random name to use to name objects
resource "random_pet" "name" {}

# From the PacketFabric side: Create a cloud router
resource "cloud_router" "cr" {
  provider     = packetfabric
  scope        = var.pf_cr_scope
  asn          = var.pf_cr_asn
  name         = "${var.tag_name}-${random_pet.name.id}"
  account_uuid = var.pf_account_uuid
  capacity     = var.pf_cr_capacity
  regions      = var.pf_cr_regions
}

data "cloud_router" "current" {
  provider = packetfabric
  depends_on = [
    cloud_router.cr
  ]
}
output "cloud_router" {
  value = data.cloud_router.current
}

variable.tf

variable "pf_cr_regions" {
  type    = list(string)
  default = ["US","UK"] # ["US"] or ["US","UK"] or ["UK"]
}

Output

16:00 $ terraform apply -var-file="../secret.tfvars"
random_pet.name: Refreshing state... [id=darling-labrador]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with
the following symbols:
  + create
 <= read (data resources)

Terraform will perform the following actions:

  # data.cloud_router.current will be read during apply
  # (depends on a resource or a module with changes pending)
 <= data "cloud_router" "current" {
      + cloud_routers = (known after apply)
      + id            = (known after apply)
    }

  # cloud_router.cr will be created
  + resource "cloud_router" "cr" {
      + account_uuid = "7576bb7a-a5ac-45de-87bf-1d1d270e55c0"
      + asn          = 64515
      + capacity     = "1Gbps"
      + id           = (known after apply)
      + name         = "DEMO-darling-labrador"
      + regions      = [
          + "US",
          + "UK",
        ]
      + scope        = "private"
    }

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

Changes to Outputs:
  + cloud_router = {
      + cloud_routers = (known after apply)
      + id            = (known after apply)
    }

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

cloud_router.cr: Creating...
cloud_router.cr: Creation complete after 0s [id=PF-L3-CUST-1741310]
data.cloud_router.current: Reading...
data.cloud_router.current: Read complete after 1s [id=60ddfabd-b027-4214-ab23-fca0ef1d2b50]

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

Outputs:

cloud_router = {
  "cloud_routers" = tolist([
    {
      "asn" = 64515
      "capacity" = "1Gbps"
      "name" = "DEMO-darling-labrador"
      "regions" = toset([
        {
          "code" = "US"
          "name" = "Continental U.S."
        },
      ])
      "scope" = "private"
      "time_created" = "2022-07-14T16:01:09.819179-0700"
      "time_updated" = "2022-07-14T16:01:09.819179-0700"
    },
  ])
  "id" = "60ddfabd-b027-4214-ab23-fca0ef1d2b50"
}

In the PF portal:
Screen Shot 2022-07-14 at 16 01 40

When trying to do the same using the API, I can see it create the CR with the 2 regions:
Screen Shot 2022-07-14 at 16 05 46

Unable to destroy cloud_router_bgp_session resource

I'm unable to destroy the cloud_router_bgp_session resource (it was created properly before and I see it in the portal).

{"message": "InvalidParam: At least one in and one out prefix is needed", "request_id": "70a39ce3-a983-4fb5-936c-449f1be5e344"}

make test fails on all branches

make test fails on all branches feature/google-service. Below is the command and the error message:

make test
go test -i $(go list ./... | grep -v 'vendor') || exit 1
tools/tools.go:5:2: import "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs" is a program, not an importable package

data source aws_cloud_connections: Add PacketFabric Router Peering IP/Mask under cloud_settings

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Description

It is currently not very easy to create an AWS Cloud Router Connection using Public VIF (while using both PacketFabric and AWS providers/resources to automate the full process).

The data source aws_cloud_connections only return the public_ip used for Public AWS Router Peering IP/Mask while the UI actually auto-populate the PacketFabric Router Peering IP/Mask (see doc).

Screen Shot 2022-07-28 at 13 32 51

It would be great for the PF terraform Data Source to also automatically calculate the other IP available in the same subnet as the one stored in public_ip. It could be a new attribute called packetfabric_ip.

See below example and suggestions for improvement:

          "attributes": {
            "aws_cloud_connections": [
              {
                ...
                "cloud_settings": [
                  {
                    "aws_account_id": "123456789",
                    "aws_connection_id": "dxlag-ffrv4nuo",
                    "aws_hosted_type": "hosted-connection",
                    "aws_region": "us-west-2",
                    "nat_public_ip": "",
                    "public_ip": "18.16.1.152/31",
                    "packetfabric_ip": "18.16.1.153/31", # <= NEW
                    "vlan_id_cust": 7,
                    "vlan_id_pf": 115
                  }
                ],
                ...
              }
            ],
            "circuit_id": "PF-L3-CUST-12345",
            "id": "9a109646-55f5-4e21-95c4-4fc90addc771"
          },

See below the workaround I found by using cidrhost and split functions in terraform - not very simple.

# From the AWS side: Create and attach a VIF
data "aws_cloud_router_connection" "current" {
  provider   = packetfabric
  circuit_id = cloud_router.cr.id
}
locals {
  aws_cloud_connections = data.aws_cloud_router_connection.current.aws_cloud_connections[*]
  helper_map = { for val in local.aws_cloud_connections :
  val["description"] => val }
  cc1 = local.helper_map["${var.tag_name}-${random_pet.name.id}-${var.pf_crc_pop1}"]
  cc1_vlan_id_pf = one(local.cc1.cloud_settings[*].vlan_id_pf)
  # Public AWS Router Peer IP
  cc1_public_ip = "${cidrhost(one(local.cc1.cloud_settings[*].public_ip), 0)}/${element(split("/", "${one(local.cc1.cloud_settings[*].public_ip)}"), 1)}"
  # PacketFabric Router Peer IP
  cc1_customer_address = "${cidrhost(one(local.cc1.cloud_settings[*].public_ip), 1)}/${element(split("/", "${one(local.cc1.cloud_settings[*].public_ip)}"), 1)}"
}

output "cc1_vlan_id_pf" {
  value = local.cc1_vlan_id_pf
}
output "cc1_public_ip" {
  value = local.cc1_public_ip
}
output "cc1_customer_address" {
  value = local.cc1_customer_address
}
# Example output:
# cc1_customer_address = "18.16.1.153/31"
# cc1_public_ip = "18.16.1.152/31"
# cc1_vlan_id_pf = 114

output "aws_cloud_router_connection" {
  value = data.aws_cloud_router_connection.current.aws_cloud_connections[*]
}

# Example output:
# aws_cloud_router_connection = tolist([
#   {
#     "cloud_circuit_id" = "PF-L3-CON-123455"
#     "cloud_router_circuit_id" = "PF-L3-CUST-123455"
#     "cloud_settings" = toset([
#       {
#         "aws_account_id" = "123456789"
#         "aws_connection_id" = "dxlag-ffrv4nuo"
#         "aws_hosted_type" = "hosted-connection"
#         "aws_region" = "us-west-2"
#         "nat_public_ip" = ""
#         "public_ip" = "18.16.1.152/31"
#         "vlan_id_cust" = 6
#         "vlan_id_pf" = 114
#       },
#     ])
#     "connection_type" = "cloud_hosted"
#     "service_provider" = "aws"
#     "speed" = "50Mbps"
#     "state" = "bgp_not_created"
#   },
# ])

resource "aws_dx_public_virtual_interface" "direct_connect_vif_1" {
  provider         = aws
  name             = "${var.tag_name}-${random_pet.name.id}-${var.pf_crc_pop1}"
  connection_id    = data.aws_dx_connection.current_1.id
  bgp_asn          = var.pf_cr_asn
  vlan             = local.cc1_vlan_id_pf
  address_family   = "ipv4"
  amazon_address   = local.cc1_public_ip 
  customer_address = local.cc1_customer_address

  route_filter_prefixes = [
    local.cc1_customer_address
  ]
  depends_on = [
    data.aws_cloud_router_connection.current
  ]
  lifecycle {
    ignore_changes = [
      vlan
    ]
  }
}

Checklist:

  • tested locally
  • added/updated acceptance tests
  • add examples (in example folder)
  • generate docs

Cannot destroy packetfabric_backbone_virtual_circuit

The destroy of packetfabric_backbone_virtual_circuit resources isn't working. I think the wrong API is being used.

Creation uses POST /v2/services/backbone

Deletion should be using the DEL /v2/services/{vc_circuit_id} (I think it is using DEL /v2/services/cloud/{cloud_circuit_id})

5b02a7d739bd# terraform destroy -auto-approve 
random_pet.name: Refreshing state... [id=smart-rabbit]
packetfabric_interface.port_2: Refreshing state... [id=PF-AP-NYC4-1743848]
packetfabric_interface.port_1: Refreshing state... [id=PF-AP-PDX1-1743849]
packetfabric_backbone_virtual_circuit.vc_1: Refreshing state... [id=PF-BC-PDX-NYC-1743852-PF]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  - destroy

Terraform will perform the following actions:

  # packetfabric_backbone_virtual_circuit.vc_1 will be destroyed
  - resource "packetfabric_backbone_virtual_circuit" "vc_1" {
      - description = "demo-pf-smart-rabbit" -> null
      - epl         = false -> null
      - id          = "PF-BC-PDX-NYC-1743852-PF" -> null

      - bandwidth {
          - account_uuid      = "24a0aef3-2784-48dc-9a8e-52d44d6da646" -> null
          - longhaul_type     = "dedicated" -> null
          - speed             = "200Mbps" -> null
          - subscription_term = 1 -> null
        }

      - interface_a {
          - port_circuit_id = "PF-AP-PDX1-1743849" -> null
          - untagged        = false -> null
          - vlan            = 145 -> null
        }

      - interface_z {
          - port_circuit_id = "PF-AP-NYC4-1743848" -> null
          - untagged        = false -> null
          - vlan            = 146 -> null
        }
    }

  # packetfabric_interface.port_1 will be destroyed
  - resource "packetfabric_interface" "port_1" {
      - account_uuid      = "24a0aef3-2784-48dc-9a8e-52d44d6da646" -> null
      - autoneg           = false -> null
      - description       = "demo-pf-smart-rabbit" -> null
      - id                = "PF-AP-PDX1-1743849" -> null
      - media             = "LX" -> null
      - nni               = false -> null
      - pop               = "PDX1" -> null
      - speed             = "1Gbps" -> null
      - subscription_term = 1 -> null
      - zone              = "A" -> null
    }

  # packetfabric_interface.port_2 will be destroyed
  - resource "packetfabric_interface" "port_2" {
      - account_uuid      = "24a0aef3-2784-48dc-9a8e-52d44d6da646" -> null
      - autoneg           = false -> null
      - description       = "demo-pf-smart-rabbit" -> null
      - id                = "PF-AP-NYC4-1743848" -> null
      - media             = "LX" -> null
      - nni               = false -> null
      - pop               = "NYC4" -> null
      - speed             = "1Gbps" -> null
      - subscription_term = 1 -> null
      - zone              = "A" -> null
    }

  # random_pet.name will be destroyed
  - resource "random_pet" "name" {
      - id        = "smart-rabbit" -> null
      - length    = 2 -> null
      - separator = "-" -> null
    }

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

Changes to Outputs:
  - packetfabric_port_1         = {
      - account_uuid      = "24a0aef3-2784-48dc-9a8e-52d44d6da646"
      - autoneg           = false
      - description       = "demo-pf-smart-rabbit"
      - id                = "PF-AP-PDX1-1743849"
      - media             = "LX"
      - nni               = false
      - pop               = "PDX1"
      - speed             = "1Gbps"
      - subscription_term = 1
      - timeouts          = null
      - zone              = "A"
    } -> null
  - packetfabric_port_2         = {
      - account_uuid      = "24a0aef3-2784-48dc-9a8e-52d44d6da646"
      - autoneg           = false
      - description       = "demo-pf-smart-rabbit"
      - id                = "PF-AP-NYC4-1743848"
      - media             = "LX"
      - nni               = false
      - pop               = "NYC4"
      - speed             = "1Gbps"
      - subscription_term = 1
      - timeouts          = null
      - zone              = "A"
    } -> null
packetfabric_backbone_virtual_circuit.vc_1: Destroying... [id=PF-BC-PDX-NYC-1743852-PF]
╷
│ Error: Status: 404, body: {"message": "Cloud not found: PF-BC-PDX-NYC-1743852-PF", "request_id": "20432214-a1f7-4af5-a231-da7e22c43c9a"}
│ 
│ 
╵

Can’t destroy cloud_router_bgp_session and cloud_router_bgp_prefixes

When destroying ALL the terraform resources, terraform is failing with the following error:

cloud_router_bgp_prefixes.crbp_2: Destroying... [id=d14b9a03-43bf-4d1b-a920-7d608904ecb2]
cloud_router_bgp_prefixes.crbp_1: Destroying... [id=e6724ff2-4ef2-424a-8ec2-bd33c0f3b365]
cloud_router_bgp_prefixes.crbp_1: Destruction complete after 0s
cloud_router_bgp_prefixes.crbp_2: Destruction complete after 0s
cloud_router_bgp_session.crbs_2: Destroying... [id=11a749fd-596c-4110-bde1-6ebecdb0ec9a]
cloud_router_bgp_session.crbs_1: Destroying... [id=b4add9b1-a478-492e-a7af-21a6460116d7]
╷
│ Warning: Prefixes cannot be deleted
│ 
│ Status: 400, body: {"message": "Request body must be a list of prefix UUIDs to delete.", "request_id":
│ "b84bc9e9-10a8-4b05-acb6-3f3758f2ca94"}
╵
╷
│ Warning: Prefixes cannot be deleted
│ 
│ Delete "https://api.packetfabric.com/v2/bgp-settings/11a749fd-596c-4110-bde1-6ebecdb0ec9a/prefixes": context canceled
╵
╷
│ Error: could not find BGP session associated with the provided Cloud Router ID%!(EXTRA *url.Error=Get "https://api.packetfabric.com/v2/services/cloud-routers/PF-L3-CUST-1740878/connections/PF-L3-CON-1740888/bgp/b4add9b1-a478-492e-a7af-21a6460116d7": context canceled)
│ 
│ 
╵
╷
│ Error: could not find BGP session associated with the provided Cloud Router ID%!(EXTRA *errors.errorString=Status: 404, body: {"message": "BGP Settings not found: 11a749fd-596c-4110-bde1-6ebecdb0ec9a", "request_id": "02afbc2b-a974-4f4b-a919-b5a5010426d7"})
│ 
│ 
╵

See following demo.

The BGP sessions and Prefixes don't need to be part of the destroy plan as those are removed automatically when removing the Cloud Router Connection.

It would be great to handle this so users don't have to use the workaround below.

Workaround: remove the cloud_router_bgp_session and cloud_router_bgp_prefixes states before destroy

terraform state rm cloud_router_bgp_session.crbs_1
terraform state rm cloud_router_bgp_session.crbs_2
terraform state rm cloud_router_bgp_prefixes.crbp_1
terraform state rm cloud_router_bgp_prefixes.crbp_2
terraform destroy -var-file="../secret.tfvars"

packetfabric_cs_google_hosted_connection: Error: Plugin did not respond

Terraform config:

terraform {
  required_providers {
    packetfabric = {
      # source  = "PacketFabric/packetfabric"
      # version = "0.2.0"
      source  = "terraform.local/PacketFabric/packetfabric"
      version = "~> 0.0.0"
    }
    google = {
      source  = "hashicorp/google"
      version = "4.30.0"
    }
  }
}

provider "packetfabric" {
  host  = var.pf_api_server
  token = var.pf_api_key
}

# Make sure you enabled Compute Engine API
provider "google" {
  project     = var.gcp_project_id
  credentials = file(var.gcp_credentials)
  region      = var.gcp_region1
  zone        = var.gcp_zone1
}

# create random name to use to name objects
resource "random_pet" "name" {}

resource "google_compute_network" "vpc_1" {
  provider                = google
  name                    = "${var.tag_name}-${random_pet.name.id}"
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "subnet_1" {
  provider      = google
  name          = "${var.tag_name}-${random_pet.name.id}"
  ip_cidr_range = var.subnet_cidr1
  region        = var.gcp_region1
  network       = google_compute_network.vpc_1.id
}

output "google_compute_network" {
  value = google_compute_network.vpc_1
}

# From the Google side: Create a Google Cloud Router with ASN 16550.
resource "google_compute_router" "router_1" {
  provider = google
  name     = "${var.tag_name}-${random_pet.name.id}"
  network  = google_compute_network.vpc_1.id
  bgp {
    # You must select or create a Cloud Router with its Google ASN set to 16550. This is a Google requirement for all Partner Interconnects.
    asn               = var.peer_asn
    advertise_mode    = "CUSTOM"
    advertised_groups = ["ALL_SUBNETS"]
  }
}

# From the Google side: Create a VLAN attachment.
resource "google_compute_interconnect_attachment" "interconnect_1" {
  provider      = google
  name          = "${var.tag_name}-${random_pet.name.id}"
  region        = var.gcp_region1
  description   = "Interconnect to PacketFabric Network"
  type          = "PARTNER"
  admin_enabled = true # From the Google side: Accept (automatically) the connection.
  router        = google_compute_router.router_1.id
}

# From the PacketFabric side: Create a GCP Hosted Connection 
resource "packetfabric_cs_google_hosted_connection" "pf_cs_conn1" {
  provider                    = packetfabric
  description                 = "${var.tag_name}-${random_pet.name.id}"
  account_uuid                = var.pf_account_uuid
  port                        = var.pf_port_circuit_id
  speed                       = var.pf_cs_speed
  google_pairing_key           = google_compute_interconnect_attachment.interconnect_1.pairing_key
  google_vlan_attachment_name = "${var.tag_name}-${random_pet.name.id}"
  pop                         = var.pf_cs_pop1
  vlan                        = var.pf_cs_vlan1
}

output "packetfabric_cs_google_hosted_connection" {
  value     = packetfabric_cs_google_hosted_connection.pf_cs_conn1
  sensitive = true
}

Output/Error:

random_pet.name: Refreshing state... [id=fancy-quagga]
google_compute_network.vpc_1: Refreshing state... [id=projects/prefab-setting-357415/global/networks/demo-pf-google-fancy-quagga]
data.google_compute_router.router_1: Reading...
google_compute_subnetwork.subnet_1: Refreshing state... [id=projects/prefab-setting-357415/regions/us-west1/subnetworks/demo-pf-google-fancy-quagga]
google_compute_router.router_1: Refreshing state... [id=projects/prefab-setting-357415/regions/us-west1/routers/demo-pf-google-fancy-quagga]
data.google_compute_router.router_1: Read complete after 0s [id=demo-pf-google-fancy-quagga]
google_compute_interconnect_attachment.interconnect_1: Refreshing state... [id=projects/prefab-setting-357415/regions/us-west1/interconnectAttachments/demo-pf-google-fancy-quagga]
packetfabric_cs_google_hosted_connection.pf_cs_conn1: Refreshing state... [id=c983e47c-f2f8-4f22-9f32-5f809d69f281]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  - destroy

Terraform will perform the following actions:

  # google_compute_interconnect_attachment.interconnect_1 will be destroyed
  - resource "google_compute_interconnect_attachment" "interconnect_1" {
      - admin_enabled              = true -> null
      - bandwidth                  = "BPS_50M" -> null
      - cloud_router_ip_address    = "169.254.172.153/29" -> null
      - creation_timestamp         = "2022-08-19T12:47:16.927-07:00" -> null
      - customer_router_ip_address = "169.254.172.154/29" -> null
      - description                = "Interconnect to PacketFabric Network" -> null
      - edge_availability_domain   = "AVAILABILITY_DOMAIN_1" -> null
      - encryption                 = "NONE" -> null
      - id                         = "projects/prefab-setting-357415/regions/us-west1/interconnectAttachments/demo-pf-google-fancy-quagga" -> null
      - ipsec_internal_addresses   = [] -> null
      - name                       = "demo-pf-google-fancy-quagga" -> null
      - pairing_key                = "087e4c80-3a23-4248-8794-ade960d5deff/us-west1/any" -> null
      - private_interconnect_info  = [] -> null
      - project                    = "prefab-setting-357415" -> null
      - region                     = "https://www.googleapis.com/compute/v1/projects/prefab-setting-357415/regions/us-west1" -> null
      - router                     = "https://www.googleapis.com/compute/v1/projects/prefab-setting-357415/regions/us-west1/routers/demo-pf-google-fancy-quagga" -> null
      - self_link                  = "https://www.googleapis.com/compute/v1/projects/prefab-setting-357415/regions/us-west1/interconnectAttachments/demo-pf-google-fancy-quagga" -> null
      - state                      = "ACTIVE" -> null
      - type                       = "PARTNER" -> null
      - vlan_tag8021q              = 107 -> null
    }

  # google_compute_network.vpc_1 will be destroyed
  - resource "google_compute_network" "vpc_1" {
      - auto_create_subnetworks         = false -> null
      - delete_default_routes_on_create = false -> null
      - enable_ula_internal_ipv6        = false -> null
      - id                              = "projects/prefab-setting-357415/global/networks/demo-pf-google-fancy-quagga" -> null
      - mtu                             = 0 -> null
      - name                            = "demo-pf-google-fancy-quagga" -> null
      - project                         = "prefab-setting-357415" -> null
      - routing_mode                    = "REGIONAL" -> null
      - self_link                       = "https://www.googleapis.com/compute/v1/projects/prefab-setting-357415/global/networks/demo-pf-google-fancy-quagga" -> null
    }

  # google_compute_router.router_1 will be destroyed
  - resource "google_compute_router" "router_1" {
      - creation_timestamp            = "2022-08-19T12:45:08.494-07:00" -> null
      - encrypted_interconnect_router = false -> null
      - id                            = "projects/prefab-setting-357415/regions/us-west1/routers/demo-pf-google-fancy-quagga" -> null
      - name                          = "demo-pf-google-fancy-quagga" -> null
      - network                       = "https://www.googleapis.com/compute/v1/projects/prefab-setting-357415/global/networks/demo-pf-google-fancy-quagga" -> null
      - project                       = "prefab-setting-357415" -> null
      - region                        = "us-west1" -> null
      - self_link                     = "https://www.googleapis.com/compute/v1/projects/prefab-setting-357415/regions/us-west1/routers/demo-pf-google-fancy-quagga" -> null

      - bgp {
          - advertise_mode     = "CUSTOM" -> null
          - advertised_groups  = [
              - "ALL_SUBNETS",
            ] -> null
          - asn                = 16550 -> null
          - keepalive_interval = 20 -> null
        }
    }

  # google_compute_subnetwork.subnet_1 will be destroyed
  - resource "google_compute_subnetwork" "subnet_1" {
      - creation_timestamp         = "2022-08-19T12:45:09.406-07:00" -> null
      - gateway_address            = "10.5.1.1" -> null
      - id                         = "projects/prefab-setting-357415/regions/us-west1/subnetworks/demo-pf-google-fancy-quagga" -> null
      - ip_cidr_range              = "10.5.1.0/24" -> null
      - name                       = "demo-pf-google-fancy-quagga" -> null
      - network                    = "https://www.googleapis.com/compute/v1/projects/prefab-setting-357415/global/networks/demo-pf-google-fancy-quagga" -> null
      - private_ip_google_access   = false -> null
      - private_ipv6_google_access = "DISABLE_GOOGLE_ACCESS" -> null
      - project                    = "prefab-setting-357415" -> null
      - purpose                    = "PRIVATE" -> null
      - region                     = "us-west1" -> null
      - secondary_ip_range         = [] -> null
      - self_link                  = "https://www.googleapis.com/compute/v1/projects/prefab-setting-357415/regions/us-west1/subnetworks/demo-pf-google-fancy-quagga" -> null
      - stack_type                 = "IPV4_ONLY" -> null
    }

  # packetfabric_cs_google_hosted_connection.pf_cs_conn1 will be destroyed
  - resource "packetfabric_cs_google_hosted_connection" "pf_cs_conn1" {
      - account_uuid                = "24a0aef3-2784-48dc-9a8e-52d44d6da646" -> null
      - description                 = "demo-pf-google-fancy-quagga" -> null
      - google_pairing_key          = "087e4c80-3a23-4248-8794-ade960d5deff/us-west1/any" -> null
      - google_vlan_attachment_name = "demo-pf-google-fancy-quagga" -> null
      - id                          = "c983e47c-f2f8-4f22-9f32-5f809d69f281" -> null
      - pop                         = "SFO1" -> null
      - port                        = "PF-AP-WDC1-1726464" -> null
      - speed                       = "50Mbps" -> null
      - vlan                        = 105 -> null
    }

  # random_pet.name will be destroyed
  - resource "random_pet" "name" {
      - id        = "fancy-quagga" -> null
      - length    = 2 -> null
      - separator = "-" -> null
    }

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

Changes to Outputs:
  - google_compute_network                   = {
      - auto_create_subnetworks         = false
      - delete_default_routes_on_create = false
      - description                     = ""
      - enable_ula_internal_ipv6        = false
      - gateway_ipv4                    = ""
      - id                              = "projects/prefab-setting-357415/global/networks/demo-pf-google-fancy-quagga"
      - internal_ipv6_range             = ""
      - mtu                             = 0
      - name                            = "demo-pf-google-fancy-quagga"
      - project                         = "prefab-setting-357415"
      - routing_mode                    = "REGIONAL"
      - self_link                       = "https://www.googleapis.com/compute/v1/projects/prefab-setting-357415/global/networks/demo-pf-google-fancy-quagga"
      - timeouts                        = null
    } -> null
  - google_compute_router                    = {
      - bgp                           = [
          - {
              - advertise_mode       = "CUSTOM"
              - advertised_groups    = [
                  - "ALL_SUBNETS",
                ]
              - advertised_ip_ranges = []
              - asn                  = 16550
              - keepalive_interval   = 20
            },
        ]
      - creation_timestamp            = "2022-08-19T12:45:08.494-07:00"
      - description                   = ""
      - encrypted_interconnect_router = false
      - id                            = "demo-pf-google-fancy-quagga"
      - name                          = "demo-pf-google-fancy-quagga"
      - network                       = "https://www.googleapis.com/compute/v1/projects/prefab-setting-357415/global/networks/demo-pf-google-fancy-quagga"
      - project                       = "prefab-setting-357415"
      - region                        = "us-west1"
      - self_link                     = "https://www.googleapis.com/compute/v1/projects/prefab-setting-357415/regions/us-west1/routers/demo-pf-google-fancy-quagga"
    } -> null
  - packetfabric_cs_google_hosted_connection = (sensitive value)
packetfabric_cs_google_hosted_connection.pf_cs_conn1: Destroying... [id=c983e47c-f2f8-4f22-9f32-5f809d69f281]
google_compute_subnetwork.subnet_1: Destroying... [id=projects/prefab-setting-357415/regions/us-west1/subnetworks/demo-pf-google-fancy-quagga]
google_compute_subnetwork.subnet_1: Still destroying... [id=projects/prefab-setting-357415/regions/...ubnetworks/demo-pf-google-fancy-quagga, 10s elapsed]
google_compute_subnetwork.subnet_1: Destruction complete after 11s
╷
│ Warning: Value for undeclared variable
│ 
│ The root module does not declare a variable named "subscription_id" but a value was found in file "secret.tfvars". If you
│ meant to use this value, add a "variable" block to the configuration.
│ 
│ To silence these warnings, use TF_VAR_... environment variables to provide certain "global" settings to all configurations
│ in your organization. To reduce the verbosity of these warnings, use the -compact-warnings option.
╵
╷
│ Warning: Value for undeclared variable
│ 
│ The root module does not declare a variable named "tenant_id" but a value was found in file "secret.tfvars". If you meant
│ to use this value, add a "variable" block to the configuration.
│ 
│ To silence these warnings, use TF_VAR_... environment variables to provide certain "global" settings to all configurations
│ in your organization. To reduce the verbosity of these warnings, use the -compact-warnings option.
╵
╷
│ Warning: Values for undeclared variables
│ 
│ In addition to the other similar warnings shown, 14 other variable(s) defined without being declared.
╵
╷
│ Error: Plugin did not respond
│ 
│ The plugin encountered an error, and failed to respond to the plugin.(*GRPCProvider).ApplyResourceChange call. The plugin
│ logs may contain more details.
╵

Stack trace from the terraform-provider-packetfabric plugin:

panic: runtime error: index out of range [0] with length 0

goroutine 37 [running]:
github.com/PacketFabric/terraform-provider-packetfabric/internal/packetfabric.(*PFClient).DeleteBackbone(0xc0003c65a0, {0xc000126f60, 0x24})
	/working/terraform-provider-packetfabric/internal/packetfabric/cloud_service.go:149 +0x44c
github.com/PacketFabric/terraform-provider-packetfabric/internal/provider.resourceBackboneDelete({0xd5d7e8?, 0xc0003c72c0?}, 0xd5d820?, {0xc32be0?, 0xc0003c65a0}, 0x1176592e000?)
	/working/terraform-provider-packetfabric/internal/provider/resource_backbone.go:179 +0xc5
github.com/PacketFabric/terraform-provider-packetfabric/internal/provider.resourceGoogleReqHostConnDelete({0xd5d7e8?, 0xc0003c72c0?}, 0x7f05ef764108?, {0xc32be0?, 0xc0003c65a0?})
	/working/terraform-provider-packetfabric/internal/provider/resource_google_request_hosted_conn.go:105 +0x55
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).delete(0xc000125a40, {0xd5d820, 0xc0003fe660}, 0xd?, {0xc32be0, 0xc0003c65a0})
	/root/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/resource.go:758 +0x12e
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).Apply(0xc000125a40, {0xd5d820, 0xc0003fe660}, 0xc00041fee0, 0xc00009b300, {0xc32be0, 0xc0003c65a0})
	/root/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/resource.go:806 +0x5fa
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).ApplyResourceChange(0xc000242420, {0xd5d778?, 0xc000443840?}, 0xc0003fc370)
	/root/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/grpc_provider.go:1021 +0xe3c
github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server.(*server).ApplyResourceChange(0xc000252aa0, {0xd5d820?, 0xc0003e1e60?}, 0xc0003d68c0)
	/root/go/pkg/mod/github.com/hashicorp/[email protected]/tfprotov5/tf5server/server.go:812 +0x515
github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5._Provider_ApplyResourceChange_Handler({0xc095a0?, 0xc000252aa0}, {0xd5d820, 0xc0003e1e60}, 0xc0003c6ba0, 0x0)
	/root/go/pkg/mod/github.com/hashicorp/[email protected]/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go:385 +0x170
google.golang.org/grpc.(*Server).processUnaryRPC(0xc0002a68c0, {0xd60550, 0xc000003d40}, 0xc0000f3200, 0xc0003478f0, 0x11e4b20, 0x0)
	/root/go/pkg/mod/google.golang.org/[email protected]/server.go:1283 +0xcfd
google.golang.org/grpc.(*Server).handleStream(0xc0002a68c0, {0xd60550, 0xc000003d40}, 0xc0000f3200, 0x0)
	/root/go/pkg/mod/google.golang.org/[email protected]/server.go:1620 +0xa1b
google.golang.org/grpc.(*Server).serveStreams.func1.2()
	/root/go/pkg/mod/google.golang.org/[email protected]/server.go:922 +0x98
created by google.golang.org/grpc.(*Server).serveStreams.func1
	/root/go/pkg/mod/google.golang.org/[email protected]/server.go:920 +0x28a

Error: The terraform-provider-packetfabric plugin crashed!

This is always indicative of a bug within the plugin. It would be immensely
helpful if you could report the crash with the plugin's maintainers so that it
can be fixed. The output above should help diagnose the issue.

List states:

b7b65185ee94# terraform state list
google_compute_interconnect_attachment.interconnect_1
google_compute_network.vpc_1
google_compute_router.router_1
packetfabric_cs_google_hosted_connection.pf_cs_conn1
random_pet.name

packetfabric_interface status checks needs to be updated ("These ports are not active")

I noticed the packetfabric_interface finished too soon. It must be only looking at the status attribute showing active to make the resource completed. We should look for the state attribute instead which will show active when the interface is ready to be used.

packetfabric_interface.interface_2: Creating...
packetfabric_interface.interface_1: Creating...
packetfabric_interface.interface_1: Still creating... [10s elapsed]
packetfabric_interface.interface_2: Still creating... [10s elapsed]
packetfabric_interface.interface_1: Still creating... [20s elapsed]
packetfabric_interface.interface_2: Still creating... [20s elapsed]
packetfabric_interface.interface_2: Still creating... [30s elapsed]
packetfabric_interface.interface_1: Still creating... [30s elapsed]
packetfabric_interface.interface_1: Creation complete after 33s [id=PF-AP-PDX1-1742703]
data.packetfabric_billing.interface_1: Reading...
data.packetfabric_billing.interface_1: Read complete after 1s [id=77d7c127-0998-490d-abfc-1a89fbdbc13b]
packetfabric_interface.interface_2: Creation complete after 37s [id=PF-AP-WDC1-1742702]
data.packetfabric_billing.interface_2: Reading...
packetfabric_cloud_services_gcp_backbone.vc1: Creating...
data.packetfabric_billing.interface_2: Read complete after 1s [id=0b0059e6-9a70-48d1-849a-78be09d03193]
╷
│ Error: Status: 400, body: {"message": "These ports are not active: ['PF-AP-WDC1-1742702']", "request_id": "b8ec24d3-400a-4e96-9089-ed6d5dfabae1"}
│ 
│   with packetfabric_cloud_services_gcp_backbone.vc1,
│   on main.tf line 75, in resource "packetfabric_cloud_services_gcp_backbone" "vc1":
│   75: resource "packetfabric_cloud_services_gcp_backbone" "vc1" {

Interface creation in progress:
{
...
"port_circuit_id": "PF-AP-WDC1-1742702",
"state": "requested",
...
"description": "demo-ngena-intense-polliwog",
...
"status": "active",
...
"operational_status": null,
"admin_status": null,
...
}

Interface ready:

{
    ...
    "port_circuit_id": "PF-AP-WDC1-1742702",
    "state": "active",
    ...
    "description": "demo-ngena-intense-polliwog",
    ...
    "status": "active",
    ...
    "operational_status": "down",
    "admin_status": "up",
    ...
}

Removed the scope attribute when creating a new Cloud Router

We just released a new release of the platform and we have removed the scope attribute when creating a new Cloud Router. We'll need to update the terraform provider for that - it used to be required.
FYI, the API doesn't return an error if you specify scope, so currently attribute will be just ignored.

interface conversion: interface {} is nil, not int on src_svlan

For the following resource:

resource "packetfabric_cloud_services_aws_hosted_connection" "medzin" {
  account_uuid   = local.default_billing_account_uuid
  aws_account_id = "1234567890"
  description    = "test-aws-medzin-uat"
  pop            = "LAX1"
  port           = "test"
  speed          = "50Mbps"
  vlan           = 4
  src_svlan      = 5
}

I get the following error:

panic: interface conversion: interface {} is nil, not int

goroutine 71 [running]:
github.com/PacketFabric/terraform-provider-packetfabric/internal/provider.extractAwsHostedMktConn(0xc0000bb860?)
        /home/medzin/repos/terraform-provider-packetfabric/internal/provider/resource_aws_hosted_mkt_conn.go:117 +0x39c
github.com/PacketFabric/terraform-provider-packetfabric/internal/provider.resourceAwsHostedMktConnCreate({0xd5d628?, 0xc0000bb860?}, 0xb5f0e0?, {0xc32b40?, 0xc0000bafc0})
        /home/medzin/repos/terraform-provider-packetfabric/internal/provider/resource_aws_hosted_mkt_conn.go:86 +0x8d
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).create(0xc0003d8a80, {0xd5d660, 0xc000303050}, 0xd?, {0xc32b40, 0xc0000bafc0})
        /home/medzin/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/resource.go:707 +0x12e
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).Apply(0xc0003d8a80, {0xd5d660, 0xc000303050}, 0xc0004f71e0, 0xc00053db80, {0xc32b40, 0xc0000bafc0})
        /home/medzin/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/resource.go:837 +0xa7a
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).ApplyResourceChange(0xc000311188, {0xd5d5b8?, 0xc00011d040?}, 0xc000716aa0)
        /home/medzin/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/grpc_provider.go:1021 +0xe3c
github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server.(*server).ApplyResourceChange(0xc00036c460, {0xd5d660?, 0xc0003027e0?}, 0xc00022e2a0)
        /home/medzin/go/pkg/mod/github.com/hashicorp/[email protected]/tfprotov5/tf5server/server.go:812 +0x515
github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5._Provider_ApplyResourceChange_Handler({0xc09500?, 0xc00036c460}, {0xd5d660, 0xc0003027e0}, 0xc0000bb0e0, 0x0)
        /home/medzin/go/pkg/mod/github.com/hashicorp/[email protected]/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go:385 +0x170
google.golang.org/grpc.(*Server).processUnaryRPC(0xc000328700, {0xd60390, 0xc0004216c0}, 0xc000585b00, 0xc0003f5b60, 0x11e6b40, 0x0)
        /home/medzin/go/pkg/mod/google.golang.org/[email protected]/server.go:1283 +0xcfd
google.golang.org/grpc.(*Server).handleStream(0xc000328700, {0xd60390, 0xc0004216c0}, 0xc000585b00, 0x0)
        /home/medzin/go/pkg/mod/google.golang.org/[email protected]/server.go:1620 +0xa1b
google.golang.org/grpc.(*Server).serveStreams.func1.2()
        /home/medzin/go/pkg/mod/google.golang.org/[email protected]/server.go:922 +0x98
created by google.golang.org/grpc.(*Server).serveStreams.func1
        /home/medzin/go/pkg/mod/google.golang.org/[email protected]/server.go:920 +0x28a

Error: The terraform-provider-packetfabric plugin crashed!

This is always indicative of a bug within the plugin. It would be immensely
helpful if you could report the crash with the plugin's maintainers so that it
can be fixed. The output above should help diagnose the issue

packetfabric_cs_azure_hosted_connection: json: cannot unmarshal string into Go struct field

Using:

# From the PacketFabric side: Create a PacketFabric Hosted Cloud Connection.
resource "packetfabric_cs_azure_hosted_connection" "cs_conn1" {
  provider          = packetfabric
  description       = "${var.tag_name}-${random_pet.name.id}"
  account_uuid      = var.pf_account_uuid
  azure_service_key = azurerm_express_route_circuit.azure_express_route_1.service_key
  port              = var.pf_port_circuit_id
  speed             = var.pf_cs_speed # will be deprecated
  vlan_private      = var.pf_cs_vlan_private
  #vlan_microsoft = var.pf_cs_vlan_microsoft
}

With those variables: (set your own account_uuid and azure_service_key)

# Azure Hosted Connection
variable "pf_port_circuit_id" {
  type    = string
  default = "PF-AP-WDC1-1726464" # replace with a port you have created in your account
}
variable "pf_cs_speed" {
  type    = string
  default = "50Mbps"
}
variable "pf_cs_vlan_private" {
  type    = number
  default = 100
}
variable "pf_cs_vlan_microsoft" {
  type    = number
  default = 101
}

Getting this error:

packetfabric_cs_azure_hosted_connection.cs_conn1: Still creating... [10s elapsed]
╷
│ Error: json: cannot unmarshal string into Go struct field AzureComponents.components.ifd_port_circuit_id_cust of type int
│ 
│   with packetfabric_cs_azure_hosted_connection.cs_conn1,
│   on main.tf line 91, in resource "packetfabric_cs_azure_hosted_connection" "cs_conn1":
│   91: resource "packetfabric_cs_azure_hosted_connection" "cs_conn1" {
│ 
╵

More meaningful examples of resources usage

Current examples of all resource usage are not very representative - they just assign values from variables, and the examples should contain the values similar to when someone will write the actual code. Below is an example cloud router that represents resource usage more than the one in the current documentation.

resource "cloud_router" "router" {
  provider     = packetfabric
  scope        = "private"
  asn          = "1234"
  name         = "Router A"
  account_uuid = "484eece8-f889-11ec-b939-0242ac120002"
  capacity     = "100Mbps"
  regions      = ["US"]
}

Add new resource to upload LOA document

Now we have the new resource packetfabric_outbound_cross_connect, one of the mandatory parameter is document_uuid. Today, we cannot use PF terraform to upload a new LOA but can only reference the ID.

We need a new resource to upload the LOA so we can automate the end 2 end process of ordering a cross connect.

resource "packetfabric_outbound_cross_connect" "crossconnect1" {
  provider = packetfabric
  description = "${var.tag_name}-${random_pet.name.id}"
  document_uuid = var.pf_document_uuid
  port = packetfabric_interface.interface1.id
  site = var.pf_cs_interface_pop
}

Data source Cloud Service AWS/Google/Azure hosted/dedicated connection change

In all below data sources, we used the GET /v2/services/cloud/connections/{cloud_circuit_id} which requires cloud_circuit_id attributes. The problem is the customer does not know that cloud_circuit_id.

I suggest instead of using the above GET, we use the below 2 GET APIs which will retrieve all hosted (including marketplace) & dedicated connections and add filtering capabilities.

Example filter:

    filter {
      name   = "port_circuit_id"
      values = ["PF-AP-LAX1-1234"]
    }

or

    filter {
      name   = "description"
      values = ["My Dedicated Cloud Connection"]
    }

List of data sources impacted:

AWS:

  • packetfabric_cs_aws_hosted_connection
  • packetfabric_cs_aws_dedicated_connection
  • packetfabric_cs_aws_hosted_marketplace_connection

Google:

  • packetfabric_cs_google_hosted_connection
  • packetfabric_cs_google_dedicated_connection
  • packetfabric_cs_google_hosted_marketplace_connection

Azure:

  • packetfabric_cs_azure_hosted_connection
  • packetfabric_cs_azure_dedicated_connection
  • packetfabric_cs_azure_marketplace_connection

aws_cloud_router_connection fix resources and examples

Incorrect or missing aws cloud router connection data object: here and here and here.

data "aws_cloud_router_connection" "current" {
 provider   = packetfabric
 circuit_id = cloud_router.new.id
}

Otherwise, user get the following error:

$ terraform apply
╷
│ Error: Missing required argument
│ 
│   on main.tf line 19, in data "aws_cloud_router_connection" "current":
│   19: data "aws_cloud_router_connection" "current" { 
│ 
│ The argument "circuit_id" is required, but no definition was found.

or

$ terraform apply
╷
│ Error: Reference to undeclared resource
│ 
│   on main.tf line 57, in output "aws_cloud_router_connection":
│   57:   value = data.aws_cloud_router_connection.current
│ 
│ A data resource "aws_cloud_router_connection" "current" has not been declared in the root module.

Example of a good working example: (using modified variables.tf example file)

terraform {
  required_providers {
    packetfabric = {
      source = "PacketFabric/packetfabric"
      version = "0.1.0"
    }
  }
}

provider "packetfabric" {
  host = var.pf_api_server
  token = var.pf_api_key
}

data "cloud_router" "current" {
  provider = packetfabric
}

data "aws_cloud_router_connection" "current" { 
  provider   = packetfabric
  circuit_id = cloud_router.new.id
}

resource "cloud_router" "new" {
  provider = packetfabric
  scope        = var.pf_cr_scope
  asn          = var.pf_cr_asn
  name         = var.pf_cr_name
  account_uuid = var.pf_account_uuid
  capacity     = var.pf_cr_capacity
  regions      = var.pf_cr_regions
}


resource "aws_cloud_router_connection" "new" {
  provider       = packetfabric
  circuit_id     = cloud_router.new.id
  account_uuid   = var.pf_account_uuid
  aws_account_id = var.pf_aws_account_id
  maybe_nat      = var.pf_crc_maybe_nat
  description    = var.pf_crc_description
  pop            = var.pf_crc_pop
  zone           = var.pf_crc_zone
  is_public      = var.pf_crc_is_public
  speed          = var.pf_crc_speed
  depends_on = [
    cloud_router.new,
    data.cloud_router.current
  ]
}

output "cloud_router" {
  value = data.cloud_router.current
}

output "aws_cloud_router_connection" {
  value = data.aws_cloud_router_connection.current
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.