Skip to content

Commit 800a203

Browse files
author
Felix Furrer
committed
Add passwordless authentication support for Azure China & Government Cloud
1 parent a9e6984 commit 800a203

File tree

3 files changed

+58
-7
lines changed

3 files changed

+58
-7
lines changed

Diff for: postgresql/helpers.go

+17
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"regexp"
88
"strings"
99

10+
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
1011
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1112
"github.com/lib/pq"
1213
)
@@ -657,3 +658,19 @@ func quoteTableName(tableName string) string {
657658
}
658659
return strings.Join(parts, ".")
659660
}
661+
662+
func cloudConfigFromName(name string) (cloud.Configuration, error) {
663+
switch strings.ToLower(name) {
664+
case "china":
665+
return cloud.AzureChina, nil
666+
667+
case "usgovernment":
668+
return cloud.AzureGovernment, nil
669+
670+
case "public":
671+
return cloud.AzurePublic, nil
672+
673+
default:
674+
return cloud.Configuration{}, fmt.Errorf("unsupported Azure Cloud environment: %s", name)
675+
}
676+
}

Diff for: postgresql/provider.go

+40-7
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ import (
77
"github.com/aws/aws-sdk-go-v2/service/sts"
88
"os"
99

10+
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
11+
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
1012
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
1113
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
12-
1314
"github.com/blang/semver"
1415
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1516
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
@@ -21,10 +22,23 @@ import (
2122
)
2223

2324
const (
24-
defaultProviderMaxOpenConnections = 20
25-
defaultExpectedPostgreSQLVersion = "9.0.0"
25+
defaultProviderMaxOpenConnections = 20
26+
defaultExpectedPostgreSQLVersion = "9.0.0"
27+
serviceName cloud.ServiceName = "ossrdbms-aad"
2628
)
2729

30+
func init() {
31+
cloud.AzureChina.Services[serviceName] = cloud.ServiceConfiguration{
32+
Audience: "https://ossrdbms-aad.database.chinacloudapi.cn",
33+
}
34+
cloud.AzureGovernment.Services[serviceName] = cloud.ServiceConfiguration{
35+
Audience: "https://ossrdbms-aad.database.usgovcloudapi.net",
36+
}
37+
cloud.AzurePublic.Services[serviceName] = cloud.ServiceConfiguration{
38+
Audience: "https://ossrdbms-aad.database.windows.net",
39+
}
40+
}
41+
2842
// Provider returns a terraform.ResourceProvider.
2943
func Provider() *schema.Provider {
3044
return &schema.Provider{
@@ -106,6 +120,13 @@ func Provider() *schema.Provider {
106120
"(see: https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/how-to-configure-sign-in-azure-ad-authentication)",
107121
},
108122

123+
"azure_environment": {
124+
Type: schema.TypeString,
125+
Optional: true,
126+
Default: "public",
127+
Description: "MS Azure Cloud environment (see: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#environment)",
128+
},
129+
109130
"azure_tenant_id": {
110131
Type: schema.TypeString,
111132
Optional: true,
@@ -310,14 +331,25 @@ func createGoogleCredsFileIfNeeded() error {
310331
return os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", tmpFile.Name())
311332
}
312333

313-
func acquireAzureOauthToken(tenantId string) (string, error) {
334+
func acquireAzureOauthToken(environment, tenantId string) (string, error) {
335+
cloudConfig, err := cloudConfigFromName(environment)
336+
if err != nil {
337+
return "", err
338+
}
314339
credential, err := azidentity.NewDefaultAzureCredential(
315-
&azidentity.DefaultAzureCredentialOptions{TenantID: tenantId})
340+
&azidentity.DefaultAzureCredentialOptions{
341+
ClientOptions: azcore.ClientOptions{
342+
Cloud: cloudConfig,
343+
},
344+
TenantID: tenantId,
345+
})
316346
if err != nil {
317347
return "", err
318348
}
319349
token, err := credential.GetToken(context.Background(), policy.TokenRequestOptions{
320-
Scopes: []string{"https://ossrdbms-aad.database.windows.net/.default"},
350+
Scopes: []string{
351+
cloudConfig.Services[serviceName].Audience + "/.default",
352+
},
321353
TenantID: tenantId,
322354
})
323355
if err != nil {
@@ -354,12 +386,13 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
354386
return nil, err
355387
}
356388
} else if d.Get("azure_identity_auth").(bool) {
389+
environment := d.Get("azure_environment").(string)
357390
tenantId := d.Get("azure_tenant_id").(string)
358391
if tenantId == "" {
359392
return nil, fmt.Errorf("postgresql: azure_identity_auth is enabled, azure_tenant_id must be provided also")
360393
}
361394
var err error
362-
password, err = acquireAzureOauthToken(tenantId)
395+
password, err = acquireAzureOauthToken(environment, tenantId)
363396
if err != nil {
364397
return nil, err
365398
}

Diff for: website/docs/index.html.markdown

+1
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ The following arguments are supported:
186186
* `aws_rds_iam_provider_role_arn` - (Optional) AWS IAM role to assume while using AWS RDS IAM Auth.
187187
* `azure_identity_auth` - (Optional) If set to `true`, call the Azure OAuth token endpoint for temporary token
188188
* `azure_tenant_id` - (Optional) (Required if `azure_identity_auth` is `true`) Azure tenant ID [read more](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config.html)
189+
* `azure_environment` - (Optional) The Azure Cloud environment. Possible values are `public`, `usgovernment` and `china`. Defaults to `public`.
189190

190191
## GoCloud
191192

0 commit comments

Comments
 (0)