Skip to content

Commit

Permalink
Feature: migrate Resource object to new TF SDK, breaking changes for …
Browse files Browse the repository at this point in the history
…protocols section (Twingate#412)

* convert resource object

* added feature branch

* Update go mod file

* fix test

* remove feature branch

* breaking change: set IsBrowserShortcutEnabled=false by default

* remove feature branch

* added security_policy_id to resource definition

* remove feature branch from CI

* added feature branch to CI

* remove feature branch

* added schema upgrader

* fix updating resource without protocols

* fix setting default ports value

* fix diff supress for empty ports array

* fix default ports value

* fix test TestAccTwingateResourceImport

* fix test

* restore ci.yml

* docs update

* added migration guide

* update formatting

* enable test on feature branch

* revert ci changes

* Update migration guide

* removed is_admin from user(s) datasources

* enable tests

* fix fmt

* drop terraform 1.3.*

* remove feature branch

* Fix typo in the guide

---------

Co-authored-by: Alex Bertsch <[email protected]>
  • Loading branch information
vmanilo and alexb-twingate authored Jan 5, 2024
1 parent 5c7602f commit af0c800
Show file tree
Hide file tree
Showing 29 changed files with 2,061 additions and 1,134 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ jobs:
fail-fast: false
matrix:
terraform:
- '1.3.*'
- '1.4.*'
- '1.5.*'
- 'latest'
steps:

Expand Down
1 change: 0 additions & 1 deletion docs/data-sources/user.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ data "twingate_user" "foo" {

- `email` (String) The email address of the User
- `first_name` (String) The first name of the User
- `is_admin` (Boolean, Deprecated) Indicates whether the User is an admin
- `last_name` (String) The last name of the User
- `role` (String) Indicates the User's role. Either ADMIN, DEVOPS, SUPPORT, or MEMBER
- `type` (String) Indicates the User's type. Either MANUAL or SYNCED.
1 change: 0 additions & 1 deletion docs/data-sources/users.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ Read-Only:
- `email` (String) The email address of the User
- `first_name` (String) The first name of the User
- `id` (String) The ID of the User
- `is_admin` (Boolean, Deprecated) Indicates whether the User is an admin
- `last_name` (String) The last name of the User
- `role` (String) Indicates the User's role. Either ADMIN, DEVOPS, SUPPORT, or MEMBER.
- `type` (String) Indicates the User's type. Either MANUAL or SYNCED.
73 changes: 73 additions & 0 deletions docs/guides/migration-v1-to-v2-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
subcategory: "migration"
page_title: "v1 to v2 Migration Guide"
description: |-
This document covers how to migrate from v1 to v2 of the Twingate Terraform provider.
---

# Migration Guide
j
This guide covers how to migrate from v1 to v2 of the Twingate Terraform provider. Migration needs to be done for the following objects:
- Resources
- `twingate_resource`
- Data sources
- `twingate_user`
- `twingate_users`

## Migrating Resources

The `protocols` attribute in the `twingate_resource` Resource has been changed from a block to an object.

In v1, the following was valid:

```terraform
resource "twingate_resource" "resource" {
name = "resource"
address = "internal.int"
remote_network_id = twingate_remote_network.aws_network.id
protocols {
allow_icmp = true
tcp {
policy = "RESTRICTED"
ports = ["80", "82-83"]
}
udp {
policy = "ALLOW_ALL"
}
}
}
```

The `protocols`, `tcp` and `udp` attributes were blocks and not objects. In v2, these are now objects:

```
protocols { -> protocols = {
tcp { -> tcp = {
udp { -> udp = {
```

In v2, the above resource needs to be rewritten like this:

```terraform
resource "twingate_resource" "resource" {
name = "resource"
address = "internal.int"
remote_network_id = twingate_remote_network.aws_network.id
protocols = {
allow_icmp = true
tcp = {
policy = "RESTRICTED"
ports = ["80", "82-83"]
}
udp = {
policy = "ALLOW_ALL"
}
}
}
```

## Migrating data sources

The attribute `is_admin` has been removed from the `twingate_user` and `twingate_users` data sources. Similar information is now available via the [`role` attribute](https://registry.terraform.io/providers/Twingate/twingate/latest/docs/data-sources/users#role).
43 changes: 17 additions & 26 deletions docs/resources/resource.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ resource "twingate_resource" "resource" {
security_policy_id = data.twingate_security_policy.test_policy.id
protocols {
protocols = {
allow_icmp = true
tcp {
tcp = {
policy = "RESTRICTED"
ports = ["80", "82-83"]
}
udp {
udp = {
policy = "ALLOW_ALL"
}
}
Expand All @@ -72,14 +72,14 @@ resource "twingate_resource" "resource" {

### Optional

- `access` (Block List, Max: 1) Restrict access to certain groups or service accounts (see [below for nested schema](#nestedblock--access))
- `access` (Block List) Restrict access to certain groups or service accounts (see [below for nested schema](#nestedblock--access))
- `alias` (String) Set a DNS alias address for the Resource. Must be a DNS-valid name string.
- `is_active` (Boolean) Set the resource as active or inactive. Default is `true`.
- `is_authoritative` (Boolean) Determines whether assignments in the access block will override any existing assignments. Default is `true`. If set to `false`, assignments made outside of Terraform will be ignored.
- `is_browser_shortcut_enabled` (Boolean) Controls whether an "Open in Browser" shortcut will be shown for this Resource in the Twingate Client.
- `is_visible` (Boolean) Controls whether this Resource will be visible in the main Resource list in the Twingate Client.
- `protocols` (Block List, Max: 1) Restrict access to certain protocols and ports. By default or when this argument is not defined, there is no restriction, and all protocols and ports are allowed. (see [below for nested schema](#nestedblock--protocols))
- `security_policy_id` (String) The ID of a `twingate_security_policy` to set as this Resource's Security Policy. Default is `Default Policy`
- `is_browser_shortcut_enabled` (Boolean) Controls whether an "Open in Browser" shortcut will be shown for this Resource in the Twingate Client. Default is `false`.
- `is_visible` (Boolean) Controls whether this Resource will be visible in the main Resource list in the Twingate Client. Default is `true`.
- `protocols` (Attributes) Restrict access to certain protocols and ports. By default or when this argument is not defined, there is no restriction, and all protocols and ports are allowed. (see [below for nested schema](#nestedatt--protocols))
- `security_policy_id` (String) The ID of a `twingate_security_policy` to set as this Resource's Security Policy. Default is `Default Policy`.

### Read-Only

Expand All @@ -94,40 +94,31 @@ Optional:
- `service_account_ids` (Set of String) List of Service Account IDs that will have permission to access the Resource.


<a id="nestedblock--protocols"></a>
<a id="nestedatt--protocols"></a>
### Nested Schema for `protocols`

Required:

- `tcp` (Block List, Min: 1, Max: 1) (see [below for nested schema](#nestedblock--protocols--tcp))
- `udp` (Block List, Min: 1, Max: 1) (see [below for nested schema](#nestedblock--protocols--udp))

Optional:

- `allow_icmp` (Boolean) Whether to allow ICMP (ping) traffic
- `tcp` (Attributes) (see [below for nested schema](#nestedatt--protocols--tcp))
- `udp` (Attributes) (see [below for nested schema](#nestedatt--protocols--udp))

<a id="nestedblock--protocols--tcp"></a>
<a id="nestedatt--protocols--tcp"></a>
### Nested Schema for `protocols.tcp`

Required:

- `policy` (String) Whether to allow or deny all ports, or restrict protocol access within certain port ranges: Can be `RESTRICTED` (only listed ports are allowed), `ALLOW_ALL`, or `DENY_ALL`

Optional:

- `ports` (List of String) List of port ranges between 1 and 65535 inclusive, in the format `100-200` for a range, or `8080` for a single port
- `policy` (String) Whether to allow or deny all ports, or restrict protocol access within certain port ranges: Can be `RESTRICTED` (only listed ports are allowed), `ALLOW_ALL`, or `DENY_ALL`
- `ports` (Set of String) List of port ranges between 1 and 65535 inclusive, in the format `100-200` for a range, or `8080` for a single port


<a id="nestedblock--protocols--udp"></a>
<a id="nestedatt--protocols--udp"></a>
### Nested Schema for `protocols.udp`

Required:

- `policy` (String) Whether to allow or deny all ports, or restrict protocol access within certain port ranges: Can be `RESTRICTED` (only listed ports are allowed), `ALLOW_ALL`, or `DENY_ALL`

Optional:

- `ports` (List of String) List of port ranges between 1 and 65535 inclusive, in the format `100-200` for a range, or `8080` for a single port
- `policy` (String) Whether to allow or deny all ports, or restrict protocol access within certain port ranges: Can be `RESTRICTED` (only listed ports are allowed), `ALLOW_ALL`, or `DENY_ALL`
- `ports` (Set of String) List of port ranges between 1 and 65535 inclusive, in the format `100-200` for a range, or `8080` for a single port

## Import

Expand Down
6 changes: 3 additions & 3 deletions examples/resources/twingate_resource/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ resource "twingate_resource" "resource" {

security_policy_id = data.twingate_security_policy.test_policy.id

protocols {
protocols = {
allow_icmp = true
tcp {
tcp = {
policy = "RESTRICTED"
ports = ["80", "82-83"]
}
udp {
udp = {
policy = "ALLOW_ALL"
}
}
Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ require (
github.com/hashicorp/terraform-plugin-framework v1.4.2
github.com/hashicorp/terraform-plugin-framework-validators v0.12.0
github.com/hashicorp/terraform-plugin-go v0.19.1
github.com/hashicorp/terraform-plugin-mux v0.12.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0
github.com/hashicorp/terraform-plugin-testing v1.5.1
github.com/hasura/go-graphql-client v0.10.1
github.com/iancoleman/strcase v0.3.0
Expand Down Expand Up @@ -57,6 +55,7 @@ require (
github.com/hashicorp/terraform-exec v0.19.0 // indirect
github.com/hashicorp/terraform-json v0.17.1 // indirect
github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect
github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 // indirect
github.com/hashicorp/terraform-registry-address v0.2.3 // indirect
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,6 @@ github.com/hashicorp/terraform-plugin-go v0.19.1 h1:lf/jTGTeELcz5IIbn/94mJdmnTjR
github.com/hashicorp/terraform-plugin-go v0.19.1/go.mod h1:5NMIS+DXkfacX6o5HCpswda5yjkSYfKzn1Nfl9l+qRs=
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
github.com/hashicorp/terraform-plugin-mux v0.12.0 h1:TJlmeslQ11WlQtIFAfth0vXx+gSNgvMEng2Rn9z3WZY=
github.com/hashicorp/terraform-plugin-mux v0.12.0/go.mod h1:8MR0AgmV+Q03DIjyrAKxXyYlq2EUnYBQP8gxAAA0zeM=
github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 h1:X7vB6vn5tON2b49ILa4W7mFAsndeqJ7bZFOGbVO+0Cc=
github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0/go.mod h1:ydFcxbdj6klCqYEPkPvdvFKiNGKZLUs+896ODUXCyao=
github.com/hashicorp/terraform-plugin-testing v1.5.1 h1:T4aQh9JAhmWo4+t1A7x+rnxAJHCDIYW9kXyo4sVO92c=
Expand Down
1 change: 1 addition & 0 deletions golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ linters-settings:
- github.com/hashicorp/terraform-plugin-framework/datasource.DataSource
- github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier.Set
- github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier.Bool
- github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier.String
- github.com/hashicorp/terraform-plugin-testing/plancheck.PlanCheck
errcheck:
check-type-assertions: false
Expand Down
39 changes: 7 additions & 32 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,52 +6,27 @@ import (
"log"

"github.com/Twingate/terraform-provider-twingate/twingate"
twingateV2 "github.com/Twingate/terraform-provider-twingate/twingate/v2"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server"

"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-plugin-mux/tf5to6server"
"github.com/hashicorp/terraform-plugin-mux/tf6muxserver"
)

var (
version = "dev"
)

const registry = "registry.terraform.io/Twingate/twingate"

func main() {
var debug bool

flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers")
flag.Parse()

ctx := context.Background()
upgradedSdkProvider, err := tf5to6server.UpgradeServer(ctx, twingate.Provider(version).GRPCProvider)
if err != nil {
log.Fatal(err)
}
providers := []func() tfprotov6.ProviderServer{
func() tfprotov6.ProviderServer {
return upgradedSdkProvider
err := providerserver.Serve(context.Background(), twingate.New(version),
providerserver.ServeOpts{
Debug: debug,
Address: registry,
ProtocolVersion: 6,
},
providerserver.NewProtocol6(twingateV2.New(version)()),
}

muxServer, err := tf6muxserver.NewMuxServer(ctx, providers...)

if err != nil {
log.Fatal(err)
}

var serveOpts []tf6server.ServeOpt
if debug {
serveOpts = append(serveOpts, tf6server.WithManagedDebug())
}

err = tf6server.Serve(
"registry.terraform.io/Twingate/twingate",
muxServer.ProviderServer,
serveOpts...,
)

if err != nil {
Expand Down
73 changes: 73 additions & 0 deletions templates/guides/migration-v1-to-v2-guide.md.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
subcategory: "migration"
page_title: "v1 to v2 Migration Guide"
description: |-
This document covers how to migrate from v1 to v2 of the Twingate Terraform provider.
---

# Migration Guide
j
This guide covers how to migrate from v1 to v2 of the Twingate Terraform provider. Migration needs to be done for the following objects:
- Resources
- `twingate_resource`
- Data sources
- `twingate_user`
- `twingate_users`

## Migrating Resources

The `protocols` attribute in the `twingate_resource` Resource has been changed from a block to an object.

In v1, the following was valid:

```terraform
resource "twingate_resource" "resource" {
name = "resource"
address = "internal.int"
remote_network_id = twingate_remote_network.aws_network.id

protocols {
allow_icmp = true
tcp {
policy = "RESTRICTED"
ports = ["80", "82-83"]
}
udp {
policy = "ALLOW_ALL"
}
}
}
```

The `protocols`, `tcp` and `udp` attributes were blocks and not objects. In v2, these are now objects:

```
protocols { -> protocols = {
tcp { -> tcp = {
udp { -> udp = {
```

In v2, the above resource needs to be rewritten like this:

```terraform
resource "twingate_resource" "resource" {
name = "resource"
address = "internal.int"
remote_network_id = twingate_remote_network.aws_network.id

protocols = {
allow_icmp = true
tcp = {
policy = "RESTRICTED"
ports = ["80", "82-83"]
}
udp = {
policy = "ALLOW_ALL"
}
}
}
```

## Migrating data sources

The attribute `is_admin` has been removed from the `twingate_user` and `twingate_users` data sources. Similar information is now available via the [`role` attribute](https://registry.terraform.io/providers/Twingate/twingate/latest/docs/data-sources/users#role).
Loading

0 comments on commit af0c800

Please sign in to comment.