Skip to content
Closed
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
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,14 @@ provider "workos" {

```hcl
resource "workos_organization" "example" {
name = "Acme Corporation"
domains = ["acme.com", "acmecorp.com"]
name = "Acme Corporation"
external_id = "acme-corp-123"
domains = ["acme.com", "acmecorp.com"]

metadata = {
tier = "enterprise"
region = "us-east-1"
}
}
```

Expand Down Expand Up @@ -108,6 +114,11 @@ data "workos_organization" "by_domain" {
domain = "acme.com"
}

# Look up organization by external ID
data "workos_organization" "by_external_id" {
external_id = "acme-corp-123"
}

# Look up user by email
data "workos_user" "john" {
email = "john@example.com"
Expand All @@ -133,7 +144,7 @@ data "workos_organization_role" "billing" {

| Data Source | Description |
|-------------|-------------|
| `workos_organization` | Retrieves organization by ID or domain |
| `workos_organization` | Retrieves organization by ID, domain, or external ID |
| `workos_connection` | Retrieves SSO connection by ID or org/type (read-only) |
| `workos_directory` | Retrieves directory by ID or organization (read-only) |
| `workos_directory_user` | Retrieves directory-synced user |
Expand Down
29 changes: 27 additions & 2 deletions docs/data-sources/organization.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ page_title: "workos_organization Data Source - workos"
subcategory: ""
description: |-
Use this data source to get information about a WorkOS Organization.
You can look up an organization by its ID or by one of its domains.
You can look up an organization by its ID, domain, or external ID.
Example Usage
By ID

Expand All @@ -17,13 +17,19 @@ description: |-
data "workos_organization" "example" {
domain = "acme.com"
}

By External ID

data "workos_organization" "example" {
external_id = "my-external-id"
}
---

# workos_organization (Data Source)

Use this data source to get information about a WorkOS Organization.

You can look up an organization by its ID or by one of its domains.
You can look up an organization by its ID, domain, or external ID.

## Example Usage

Expand All @@ -43,6 +49,14 @@ data "workos_organization" "example" {
}
```

### By External ID

```hcl
data "workos_organization" "example" {
external_id = "my-external-id"
}
```

## Example Usage

```terraform
Expand All @@ -63,6 +77,15 @@ data "workos_organization" "by_domain" {
output "org_name_by_domain" {
value = data.workos_organization.by_domain.name
}

# Look up an organization by external ID
data "workos_organization" "by_external_id" {
external_id = "acme-corp-123"
}

output "org_name_by_external_id" {
value = data.workos_organization.by_external_id.name
}
```

<!-- schema generated by tfplugindocs -->
Expand All @@ -71,11 +94,13 @@ output "org_name_by_domain" {
### Optional

- `domain` (String) A domain associated with the organization to look up. The organization that owns this domain will be returned.
- `external_id` (String) The external ID of the organization to look up.
- `id` (String) The unique identifier of the organization to look up (e.g., `org_01HXYZ...`).

### Read-Only

- `created_at` (String) The timestamp when the organization was created (RFC3339 format).
- `domains` (Set of String) The domains associated with the organization.
- `metadata` (Map of String) The metadata of the organization as key-value string pairs.
- `name` (String) The name of the organization.
- `updated_at` (String) The timestamp when the organization was last updated (RFC3339 format).
12 changes: 10 additions & 2 deletions docs/resources/organization.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,14 @@ terraform import workos_organization.example org_01HXYZ...
```terraform
# Manage a WorkOS Organization
resource "workos_organization" "example" {
name = "Acme Corporation"
domains = ["acme.com", "acmecorp.com"]
name = "Acme Corporation"
external_id = "acme-corp-123"
domains = ["acme.com", "acmecorp.com"]

metadata = {
tier = "enterprise"
region = "us-east-1"
}
}

# Output the organization ID for use in other resources
Expand All @@ -72,6 +78,8 @@ output "organization_created_at" {
### Optional

- `domains` (Set of String) The domains associated with the organization. These are used for domain-based SSO routing.
- `external_id` (String) The external ID of the organization. Use this to map the organization to an entity in your application.
- `metadata` (Map of String) Metadata key/value pairs associated with the organization. Maximum of 10 key/value pairs.

### Read-Only

Expand Down
9 changes: 9 additions & 0 deletions examples/data-sources/workos_organization/data-source.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,12 @@ data "workos_organization" "by_domain" {
output "org_name_by_domain" {
value = data.workos_organization.by_domain.name
}

# Look up an organization by external ID
data "workos_organization" "by_external_id" {
external_id = "acme-corp-123"
}

output "org_name_by_external_id" {
value = data.workos_organization.by_external_id.name
}
10 changes: 8 additions & 2 deletions examples/resources/workos_organization/resource.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# Manage a WorkOS Organization
resource "workos_organization" "example" {
name = "Acme Corporation"
domains = ["acme.com", "acmecorp.com"]
name = "Acme Corporation"
external_id = "acme-corp-123"
domains = ["acme.com", "acmecorp.com"]

metadata = {
tier = "enterprise"
region = "us-east-1"
}
}

# Output the organization ID for use in other resources
Expand Down
26 changes: 16 additions & 10 deletions internal/client/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import "time"

// Organization represents a WorkOS Organization
type Organization struct {
ID string `json:"id"`
Object string `json:"object"`
Name string `json:"name"`
Domains []Domain `json:"domains,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ID string `json:"id"`
Object string `json:"object"`
Name string `json:"name"`
ExternalID string `json:"external_id,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
Domains []Domain `json:"domains,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}

// Domain represents a domain associated with an organization
Expand All @@ -27,8 +29,10 @@ type Domain struct {

// OrganizationCreateRequest represents the request to create an organization
type OrganizationCreateRequest struct {
Name string `json:"name"`
DomainData []DomainData `json:"domain_data,omitempty"`
Name string `json:"name"`
DomainData []DomainData `json:"domain_data,omitempty"`
ExternalID string `json:"external_id,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
}

// DomainData represents domain data for organization creation/update
Expand All @@ -39,8 +43,10 @@ type DomainData struct {

// OrganizationUpdateRequest represents the request to update an organization
type OrganizationUpdateRequest struct {
Name string `json:"name,omitempty"`
DomainData []DomainData `json:"domain_data,omitempty"`
Name string `json:"name,omitempty"`
DomainData []DomainData `json:"domain_data,omitempty"`
ExternalID string `json:"external_id,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
}

// OrganizationListResponse represents the response from listing organizations
Expand Down
10 changes: 10 additions & 0 deletions internal/client/organizations.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ func (c *Client) ListOrganizations(ctx context.Context) (*OrganizationListRespon
return &resp, nil
}

// GetOrganizationByExternalID retrieves an organization by external ID
func (c *Client) GetOrganizationByExternalID(ctx context.Context, externalID string) (*Organization, error) {
var org Organization
err := c.Get(ctx, "/organizations/external_id/"+externalID, &org)
if err != nil {
return nil, fmt.Errorf("failed to get organization by external ID: %w", err)
}
return &org, nil
}

// GetOrganizationByDomain finds an organization by domain
func (c *Client) GetOrganizationByDomain(ctx context.Context, domain string) (*Organization, error) {
params := url.Values{}
Expand Down
70 changes: 63 additions & 7 deletions internal/provider/data_source_organization.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ type OrganizationDataSource struct {

// OrganizationDataSourceModel describes the data source data model.
type OrganizationDataSourceModel struct {
ID types.String `tfsdk:"id"`
Domain types.String `tfsdk:"domain"`
Name types.String `tfsdk:"name"`
Domains types.Set `tfsdk:"domains"`
CreatedAt types.String `tfsdk:"created_at"`
UpdatedAt types.String `tfsdk:"updated_at"`
ID types.String `tfsdk:"id"`
Domain types.String `tfsdk:"domain"`
ExternalID types.String `tfsdk:"external_id"`
Name types.String `tfsdk:"name"`
Domains types.Set `tfsdk:"domains"`
Metadata types.Map `tfsdk:"metadata"`
CreatedAt types.String `tfsdk:"created_at"`
UpdatedAt types.String `tfsdk:"updated_at"`
}

func (d *OrganizationDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
Expand All @@ -50,7 +52,7 @@ func (d *OrganizationDataSource) Schema(ctx context.Context, req datasource.Sche
MarkdownDescription: `
Use this data source to get information about a WorkOS Organization.

You can look up an organization by its ID or by one of its domains.
You can look up an organization by its ID, domain, or external ID.

## Example Usage

Expand All @@ -69,6 +71,14 @@ data "workos_organization" "example" {
domain = "acme.com"
}
` + "```" + `

### By External ID

` + "```hcl" + `
data "workos_organization" "example" {
external_id = "my-external-id"
}
` + "```" + `
`,
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Expand All @@ -82,11 +92,23 @@ data "workos_organization" "example" {
MarkdownDescription: "A domain associated with the organization to look up. The organization that owns this domain will be returned.",
Optional: true,
},
"external_id": schema.StringAttribute{
Description: "The external ID of the organization to look up.",
MarkdownDescription: "The external ID of the organization to look up.",
Optional: true,
Computed: true,
},
"name": schema.StringAttribute{
Description: "The name of the organization.",
MarkdownDescription: "The name of the organization.",
Computed: true,
},
"metadata": schema.MapAttribute{
Description: "The metadata of the organization.",
MarkdownDescription: "The metadata of the organization as key-value string pairs.",
Computed: true,
ElementType: types.StringType,
},
"domains": schema.SetAttribute{
Description: "The domains associated with the organization.",
MarkdownDescription: "The domains associated with the organization.",
Expand All @@ -112,6 +134,7 @@ func (d *OrganizationDataSource) ConfigValidators(ctx context.Context) []datasou
datasourcevalidator.ExactlyOneOf(
path.MatchRoot("id"),
path.MatchRoot("domain"),
path.MatchRoot("external_id"),
),
}
}
Expand Down Expand Up @@ -176,6 +199,20 @@ func (d *OrganizationDataSource) Read(ctx context.Context, req datasource.ReadRe
)
return
}
} else if !config.ExternalID.IsNull() {
// Look up by external ID
tflog.Debug(ctx, "Reading organization by external ID", map[string]any{
"external_id": config.ExternalID.ValueString(),
})

org, err = d.client.GetOrganizationByExternalID(ctx, config.ExternalID.ValueString())
if err != nil {
resp.Diagnostics.AddError(
"Error Reading Organization",
"Could not find organization with external ID "+config.ExternalID.ValueString()+": "+err.Error(),
)
return
}
}

// Map response to state
Expand All @@ -184,6 +221,25 @@ func (d *OrganizationDataSource) Read(ctx context.Context, req datasource.ReadRe
config.CreatedAt = types.StringValue(org.CreatedAt.Format(time.RFC3339))
config.UpdatedAt = types.StringValue(org.UpdatedAt.Format(time.RFC3339))

// Map external_id
if org.ExternalID != "" {
config.ExternalID = types.StringValue(org.ExternalID)
} else {
config.ExternalID = types.StringNull()
}

// Map metadata
if len(org.Metadata) > 0 {
metadataMap, diags := types.MapValueFrom(ctx, types.StringType, org.Metadata)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
config.Metadata = metadataMap
} else {
config.Metadata = types.MapNull(types.StringType)
}

// Map domains
if len(org.Domains) > 0 {
domainStrings := make([]string, len(org.Domains))
Expand Down
Loading
Loading