Skip to content

Commit e5262b4

Browse files
author
Felix Furrer
committed
Add passwordless authentication support for Azure China & Government Cloud
1 parent c3f634b commit e5262b4

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
)
@@ -619,3 +620,19 @@ func quoteTableName(tableName string) string {
619620
}
620621
return strings.Join(parts, ".")
621622
}
623+
624+
func cloudConfigFromName(name string) (cloud.Configuration, error) {
625+
switch strings.ToLower(name) {
626+
case "china":
627+
return cloud.AzureChina, nil
628+
629+
case "usgovernment":
630+
return cloud.AzureGovernment, nil
631+
632+
case "public":
633+
return cloud.AzurePublic, nil
634+
635+
default:
636+
return cloud.Configuration{}, fmt.Errorf("unsupported Azure Cloud environment: %s", name)
637+
}
638+
}

Diff for: postgresql/provider.go

+40-7
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import (
55
"fmt"
66
"os"
77

8+
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
9+
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
810
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
911
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
10-
1112
"github.com/blang/semver"
1213
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1314
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
@@ -19,10 +20,23 @@ import (
1920
)
2021

2122
const (
22-
defaultProviderMaxOpenConnections = 20
23-
defaultExpectedPostgreSQLVersion = "9.0.0"
23+
defaultProviderMaxOpenConnections = 20
24+
defaultExpectedPostgreSQLVersion = "9.0.0"
25+
serviceName cloud.ServiceName = "ossrdbms-aad"
2426
)
2527

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

114+
"azure_environment": {
115+
Type: schema.TypeString,
116+
Optional: true,
117+
Default: "public",
118+
Description: "MS Azure Cloud environment (see: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#environment)",
119+
},
120+
100121
"azure_tenant_id": {
101122
Type: schema.TypeString,
102123
Optional: true,
@@ -274,14 +295,25 @@ func createGoogleCredsFileIfNeeded() error {
274295
return os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", tmpFile.Name())
275296
}
276297

277-
func acquireAzureOauthToken(tenantId string) (string, error) {
298+
func acquireAzureOauthToken(environment, tenantId string) (string, error) {
299+
cloudConfig, err := cloudConfigFromName(environment)
300+
if err != nil {
301+
return "", err
302+
}
278303
credential, err := azidentity.NewDefaultAzureCredential(
279-
&azidentity.DefaultAzureCredentialOptions{TenantID: tenantId})
304+
&azidentity.DefaultAzureCredentialOptions{
305+
ClientOptions: azcore.ClientOptions{
306+
Cloud: cloudConfig,
307+
},
308+
TenantID: tenantId,
309+
})
280310
if err != nil {
281311
return "", err
282312
}
283313
token, err := credential.GetToken(context.Background(), policy.TokenRequestOptions{
284-
Scopes: []string{"https://ossrdbms-aad.database.windows.net/.default"},
314+
Scopes: []string{
315+
cloudConfig.Services[serviceName].Audience + "/.default",
316+
},
285317
TenantID: tenantId,
286318
})
287319
if err != nil {
@@ -317,12 +349,13 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
317349
return nil, err
318350
}
319351
} else if d.Get("azure_identity_auth").(bool) {
352+
environment := d.Get("azure_environment").(string)
320353
tenantId := d.Get("azure_tenant_id").(string)
321354
if tenantId == "" {
322355
return nil, fmt.Errorf("postgresql: azure_identity_auth is enabled, azure_tenant_id must be provided also")
323356
}
324357
var err error
325-
password, err = acquireAzureOauthToken(tenantId)
358+
password, err = acquireAzureOauthToken(environment, tenantId)
326359
if err != nil {
327360
return nil, err
328361
}

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

+1
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ The following arguments are supported:
185185
* `aws_rds_iam_region` - (Optional) The AWS region to use while using AWS RDS IAM Auth.
186186
* `azure_identity_auth` - (Optional) If set to `true`, call the Azure OAuth token endpoint for temporary token
187187
* `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)
188+
* `azure_environment` - (Optional) The Azure Cloud environment. Possible values are `public`, `usgovernment` and `china`. Defaults to `public`.
188189

189190
## GoCloud
190191

0 commit comments

Comments
 (0)