Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[zitadel/terraform-provider-zitadel#205] Add idp_oidc #206

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions docs/resources/idp_oidc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
page_title: "zitadel_idp_oidc Resource - terraform-provider-zitadel"
subcategory: ""
description: |-
Resource representing a generic OIDC IdP on the instance.
---

# zitadel_org_idp_oidc (Resource)

Resource representing a generic OIDC IdP on the organization.

## Example Usage

```terraform
resource "zitadel_idp_oidc" "default" {
name = "My Generic OIDC IDP"
client_id = "a_client_id"
client_secret = "a_client_secret"
scopes = ["openid", "profile", "email"]
issuer = "https://example.com"
is_linking_allowed = false
is_creation_allowed = true
is_auto_creation = false
is_auto_update = true
is_id_token_mapping = true
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `client_id` (String) client id generated by the identity provider
- `client_secret` (String, Sensitive) client secret generated by the identity provider
- `is_auto_creation` (Boolean) enable if a new account in ZITADEL should be created automatically on login with an external account
- `is_auto_update` (Boolean) enable if a the ZITADEL account fields should be updated automatically on each login
- `is_creation_allowed` (Boolean) enable if users should be able to create a new account in ZITADEL when using an external account
- `is_id_token_mapping` (Boolean) if true, provider information get mapped from the id token, not from the userinfo endpoint
- `is_linking_allowed` (Boolean) enable if users should be able to link an existing ZITADEL user with an external account
- `issuer` (String) the issuer of the idp

### Optional

- `name` (String) Name of the IDP
- `scopes` (Set of String) the scopes requested by ZITADEL during the request on the identity provider

### Read-Only

- `id` (String) The ID of this resource.

## Import

```bash
# The resource can be imported using the ID format `<id[:client_secret]>`, e.g.
terraform import zitadel_idp_oidc.imported '123456789012345678:1234567890abcdef'
```
3 changes: 3 additions & 0 deletions examples/provider/data-sources/idp_oidc.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "zitadel_idp_oidc" "default" {
id = "123456789012345678"
}
2 changes: 2 additions & 0 deletions examples/provider/resources/idp_oidc-import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# The resource can be imported using the ID format `<id[:client_secret]>`, e.g.
terraform import zitadel_idp_oidc.imported '123456789012345678:1234567890abcdef'
12 changes: 12 additions & 0 deletions examples/provider/resources/idp_oidc.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
resource "zitadel_idp_oidc" "default" {
name = "My Generic OIDC IDP"
client_id = "a_client_id"
client_secret = "a_client_secret"
scopes = ["openid", "profile", "email"]
issuer = "https://example.com"
is_linking_allowed = false
is_creation_allowed = true
is_auto_creation = false
is_auto_update = true
is_id_token_mapping = true
}
16 changes: 16 additions & 0 deletions templates/data-sources/idp_oidc.md.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this template is not yet generated for the docs.

page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}"
subcategory: ""
description: |-
{{ .Description | plainmarkdown | trimspace | prefixlines " " }}
---

# {{.Name}} ({{.Type}})

{{ .Description | trimspace }}

## Example Usage

{{ tffile "examples/provider/data-sources/idp_oidc.tf" }}

{{ .SchemaMarkdown | trimspace }}
20 changes: 20 additions & 0 deletions templates/resources/idp_oidc.md.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}"
subcategory: ""
description: |-
{{ .Description | plainmarkdown | trimspace | prefixlines " " }}
---

# {{.Name}} ({{.Type}})

{{ .Description | trimspace }}

## Example Usage

{{ tffile "examples/provider/resources/idp_oidc.tf" }}

{{ .SchemaMarkdown | trimspace }}

## Import

{{ codefile "bash" "examples/provider/resources/idp_oidc-import.sh" }}
27 changes: 27 additions & 0 deletions zitadel/idp_oidc/datasource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package idp_oidc

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

"github.com/zitadel/terraform-provider-zitadel/v2/zitadel/idp_utils"
)

func GetDatasource() *schema.Resource {
return &schema.Resource{
Description: "Datasource representing a generic OIDC IdP on the instance.",
Schema: map[string]*schema.Schema{
idp_utils.IdpIDVar: idp_utils.IdPIDDataSourceField,
idp_utils.NameVar: idp_utils.NameDataSourceField,
idp_utils.ClientIDVar: idp_utils.ClientIDDataSourceField,
idp_utils.ClientSecretVar: idp_utils.ClientSecretDataSourceField,
idp_utils.ScopesVar: idp_utils.ScopesDataSourceField,
idp_utils.IsLinkingAllowedVar: idp_utils.IsLinkingAllowedDataSourceField,
idp_utils.IsCreationAllowedVar: idp_utils.IsCreationAllowedDataSourceField,
idp_utils.IsAutoCreationVar: idp_utils.IsAutoCreationDataSourceField,
idp_utils.IsAutoUpdateVar: idp_utils.IsAutoUpdateDataSourceField,
IssuerVar: IssuerDatasourceField,
IsIdTokenMappingVar: IsIdTokenMappingDatasourceField,
},
ReadContext: read,
}
}
105 changes: 105 additions & 0 deletions zitadel/idp_oidc/funcs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package idp_oidc

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/zitadel/zitadel-go/v3/pkg/client/zitadel/admin"

"github.com/zitadel/terraform-provider-zitadel/v2/zitadel/helper"
"github.com/zitadel/terraform-provider-zitadel/v2/zitadel/idp_utils"
)

func create(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
clientinfo, ok := m.(*helper.ClientInfo)
if !ok {
return diag.Errorf("failed to get client")
}
client, err := helper.GetAdminClient(ctx, clientinfo)
if err != nil {
return diag.FromErr(err)
}
resp, err := client.AddGenericOIDCProvider(ctx, &admin.AddGenericOIDCProviderRequest{
Name: idp_utils.StringValue(d, idp_utils.NameVar),
ClientId: idp_utils.StringValue(d, idp_utils.ClientIDVar),
ClientSecret: idp_utils.StringValue(d, idp_utils.ClientSecretVar),
Scopes: idp_utils.ScopesValue(d),
ProviderOptions: idp_utils.ProviderOptionsValue(d),
Issuer: idp_utils.StringValue(d, IssuerVar),
IsIdTokenMapping: idp_utils.BoolValue(d, IsIdTokenMappingVar),
})
if err != nil {
return diag.Errorf("failed to create idp: %v", err)
}
d.SetId(resp.GetId())
return nil
}

func update(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
clientinfo, ok := m.(*helper.ClientInfo)
if !ok {
return diag.Errorf("failed to get client")
}
client, err := helper.GetAdminClient(ctx, clientinfo)
if err != nil {
return diag.FromErr(err)
}
_, err = client.UpdateGenericOIDCProvider(ctx, &admin.UpdateGenericOIDCProviderRequest{
Id: d.Id(),
Name: idp_utils.StringValue(d, idp_utils.NameVar),
Issuer: idp_utils.StringValue(d, IssuerVar),
ClientId: idp_utils.StringValue(d, idp_utils.ClientIDVar),
ClientSecret: idp_utils.StringValue(d, idp_utils.ClientSecretVar),
Scopes: idp_utils.ScopesValue(d),
ProviderOptions: idp_utils.ProviderOptionsValue(d),
IsIdTokenMapping: idp_utils.BoolValue(d, IsIdTokenMappingVar),
})
if err != nil {
return diag.Errorf("failed to update idp: %v", err)
}
return nil
}

func read(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
clientinfo, ok := m.(*helper.ClientInfo)
if !ok {
return diag.Errorf("failed to get client")
}
client, err := helper.GetAdminClient(ctx, clientinfo)
if err != nil {
return diag.FromErr(err)
}
resp, err := client.GetProviderByID(ctx, &admin.GetProviderByIDRequest{Id: helper.GetID(d, idp_utils.IdpIDVar)})
if err != nil && helper.IgnoreIfNotFoundError(err) == nil {
d.SetId("")
return nil
}
if err != nil {
return diag.Errorf("failed to get idp")
}
idp := resp.GetIdp()
cfg := idp.GetConfig()
specificCfg := cfg.GetOidc()
generalCfg := cfg.GetOptions()
set := map[string]interface{}{
helper.OrgIDVar: idp.GetDetails().GetResourceOwner(),
idp_utils.NameVar: idp.GetName(),
idp_utils.ClientIDVar: specificCfg.GetClientId(),
idp_utils.ClientSecretVar: idp_utils.StringValue(d, idp_utils.ClientSecretVar),
idp_utils.ScopesVar: specificCfg.GetScopes(),
idp_utils.IsLinkingAllowedVar: generalCfg.GetIsLinkingAllowed(),
idp_utils.IsCreationAllowedVar: generalCfg.GetIsCreationAllowed(),
idp_utils.IsAutoCreationVar: generalCfg.GetIsAutoCreation(),
idp_utils.IsAutoUpdateVar: generalCfg.GetIsAutoUpdate(),
IssuerVar: specificCfg.GetIssuer(),
IsIdTokenMappingVar: specificCfg.GetIsIdTokenMapping(),
}
for k, v := range set {
if err := d.Set(k, v); err != nil {
return diag.Errorf("failed to set %s of oidc idp: %v", k, err)
}
}
d.SetId(idp.Id)
return nil
}
32 changes: 32 additions & 0 deletions zitadel/idp_oidc/resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package idp_oidc

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

"github.com/zitadel/terraform-provider-zitadel/v2/zitadel/helper"
"github.com/zitadel/terraform-provider-zitadel/v2/zitadel/idp_utils"
)

func GetResource() *schema.Resource {
return &schema.Resource{
Description: "Resource representing an OIDC IDP on the instance.",
Schema: map[string]*schema.Schema{
helper.OrgIDVar: helper.OrgIDResourceField,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idp_oidc does not need an OrgID as it is an instance level resource, please have a look at the other like idp_oauth resource as a reference.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also the reason the testing fails in the pipeline.

idp_utils.NameVar: idp_utils.NameResourceField,
idp_utils.ClientIDVar: idp_utils.ClientIDResourceField,
idp_utils.ClientSecretVar: idp_utils.ClientSecretResourceField,
idp_utils.ScopesVar: idp_utils.ScopesResourceField,
idp_utils.IsLinkingAllowedVar: idp_utils.IsLinkingAllowedResourceField,
idp_utils.IsCreationAllowedVar: idp_utils.IsCreationAllowedResourceField,
idp_utils.IsAutoCreationVar: idp_utils.IsAutoCreationResourceField,
idp_utils.IsAutoUpdateVar: idp_utils.IsAutoUpdateResourceField,
IssuerVar: IssuerResourceField,
IsIdTokenMappingVar: IsIdTokenMappingResourceField,
},
ReadContext: read,
UpdateContext: update,
CreateContext: create,
DeleteContext: idp_utils.Delete,
Importer: helper.ImportWithIDAndOptionalOrgAndSecret(idp_utils.IdpIDVar, idp_utils.ClientSecretVar),
}
}
12 changes: 12 additions & 0 deletions zitadel/idp_oidc/resource_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package idp_oidc_test

import (
"testing"

"github.com/zitadel/terraform-provider-zitadel/v2/zitadel/idp_utils"
"github.com/zitadel/terraform-provider-zitadel/v2/zitadel/idp_utils/idp_test_utils"
)

func TestAccInstanceIdPOIDC(t *testing.T) {
idp_test_utils.RunInstanceIDPLifecyleTest(t, "zitadel_idp_oidc", idp_utils.ClientSecretVar)
}
31 changes: 31 additions & 0 deletions zitadel/idp_oidc/schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package idp_oidc

import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

const (
IsIdTokenMappingVar = "is_id_token_mapping"
IssuerVar = "issuer"
)

var (
IsIdTokenMappingResourceField = &schema.Schema{
Type: schema.TypeBool,
Required: true,
Description: "if true, provider information get mapped from the id token, not from the userinfo endpoint",
}
IsIdTokenMappingDatasourceField = &schema.Schema{
Type: schema.TypeBool,
Computed: true,
Description: "if true, provider information get mapped from the id token, not from the userinfo endpoint.",
}
IssuerResourceField = &schema.Schema{
Type: schema.TypeString,
Required: true,
Description: "the issuer of the idp",
}
IssuerDatasourceField = &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "the issuer of the idp",
}
)
3 changes: 3 additions & 0 deletions zitadel/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import (
"github.com/zitadel/terraform-provider-zitadel/v2/zitadel/idp_google"
"github.com/zitadel/terraform-provider-zitadel/v2/zitadel/idp_ldap"
"github.com/zitadel/terraform-provider-zitadel/v2/zitadel/idp_oauth"
"github.com/zitadel/terraform-provider-zitadel/v2/zitadel/idp_oidc"
stebenz marked this conversation as resolved.
Show resolved Hide resolved
"github.com/zitadel/terraform-provider-zitadel/v2/zitadel/idp_saml"
"github.com/zitadel/terraform-provider-zitadel/v2/zitadel/init_message_text"
"github.com/zitadel/terraform-provider-zitadel/v2/zitadel/instance_member"
Expand Down Expand Up @@ -236,6 +237,7 @@ func Provider() *schema.Provider {
"zitadel_idp_ldap": idp_ldap.GetDatasource(),
"zitadel_idp_saml": idp_saml.GetDatasource(),
"zitadel_idp_oauth": idp_oauth.GetDatasource(),
"zitadel_idp_oidc": idp_oidc.GetDatasource(),
"zitadel_org_jwt_idp": org_idp_jwt.GetDatasource(),
"zitadel_org_oidc_idp": org_idp_oidc.GetDatasource(),
"zitadel_org_idp_github": org_idp_github.GetDatasource(),
Expand Down Expand Up @@ -327,6 +329,7 @@ func Provider() *schema.Provider {
"zitadel_idp_ldap": idp_ldap.GetResource(),
"zitadel_idp_saml": idp_saml.GetResource(),
"zitadel_idp_oauth": idp_oauth.GetResource(),
"zitadel_idp_oidc": idp_oidc.GetResource(),
"zitadel_org_idp_jwt": org_idp_jwt.GetResource(),
"zitadel_org_idp_oidc": org_idp_oidc.GetResource(),
"zitadel_org_idp_github": org_idp_github.GetResource(),
Expand Down
Loading