Skip to content

Commit 5276eeb

Browse files
committed
feat: add Azure DevOps Pipelines support
1 parent b7e9548 commit 5276eeb

File tree

3 files changed

+65
-5
lines changed

3 files changed

+65
-5
lines changed

providers/dns/azuredns/azuredns.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ const (
3434
EnvOIDCRequestToken = envNamespace + "OIDC_REQUEST_TOKEN"
3535
EnvGitHubOIDCRequestToken = "ACTIONS_ID_TOKEN_REQUEST_TOKEN"
3636

37+
EnvServiceConnectionID = envNamespace + "SERVICE_CONNECTION_ID"
38+
altEnvServiceConnectionID = "SERVICE_CONNECTION_ID"
39+
altEnvArmAdoPipelineServiceConnectionID = "ARM_ADO_PIPELINE_SERVICE_CONNECTION_ID"
40+
altEnvArmOIDCAzureServiceConnectionID = "ARM_OIDC_AZURE_SERVICE_CONNECTION_ID"
41+
EnvSystemAccessToken = envNamespace + "SYSTEM_ACCESS_TOKEN"
42+
altEnvSystemAccessToken = "SYSTEM_ACCESSTOKEN"
43+
altEnvArmOIDCRequestToken = "ARM_OIDC_REQUEST_TOKEN"
44+
3745
EnvAuthMethod = envNamespace + "AUTH_METHOD"
3846
EnvAuthMSITimeout = envNamespace + "AUTH_MSI_TIMEOUT"
3947

@@ -66,6 +74,9 @@ type Config struct {
6674
OIDCRequestURL string
6775
OIDCRequestToken string
6876

77+
ServiceConnectionID string
78+
SystemAccessToken string
79+
6980
AuthMethod string
7081
AuthMSITimeout time.Duration
7182

@@ -134,6 +145,15 @@ func NewDNSProvider() (*DNSProvider, error) {
134145
config.OIDCRequestURL = oidcValues[EnvOIDCRequestURL]
135146
config.OIDCRequestToken = oidcValues[EnvOIDCRequestToken]
136147

148+
// https://registry.terraform.io/providers/hashicorp/Azurerm/latest/docs/guides/service_principal_oidc
149+
pipelineValues, _ := env.GetWithFallback(
150+
[]string{EnvServiceConnectionID, altEnvServiceConnectionID, altEnvArmAdoPipelineServiceConnectionID, altEnvArmOIDCAzureServiceConnectionID},
151+
[]string{EnvSystemAccessToken, altEnvSystemAccessToken, altEnvArmOIDCRequestToken},
152+
)
153+
154+
config.ServiceConnectionID = pipelineValues[EnvServiceConnectionID]
155+
config.SystemAccessToken = pipelineValues[EnvSystemAccessToken]
156+
137157
config.AuthMethod = env.GetOrFile(EnvAuthMethod)
138158
config.AuthMSITimeout = env.GetOrDefaultSecond(EnvAuthMSITimeout, 2*time.Second)
139159

providers/dns/azuredns/azuredns.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ This authentication method can be specifically used by setting the `AZURE_AUTH_M
174174
Open ID Connect is a mechanism that establish a trust relationship between a running environment and the Azure AD identity provider.
175175
It can be enabled by setting the `AZURE_AUTH_METHOD` environment variable to `oidc`.
176176
177+
### Azure DevOps Pipelines
178+
179+
It can be enabled by setting the `AZURE_AUTH_METHOD` environment variable to `pipeline`.
180+
177181
'''
178182

179183
[Configuration]

providers/dns/azuredns/credentials.go

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,44 +13,68 @@ import (
1313
"github.com/go-acme/lego/v4/challenge/dns01"
1414
)
1515

16+
const (
17+
authMethodEnv = "env"
18+
authMethodWLI = "wli"
19+
authMethodMSI = "msi"
20+
authMethodCLI = "cli"
21+
authMethodOIDC = "oidc"
22+
authMethodPipeline = "pipeline"
23+
)
24+
25+
//nolint:gocyclo // The complexity is related to the number of possible configurations.
1626
func getCredentials(config *Config) (azcore.TokenCredential, error) {
1727
clientOptions := azcore.ClientOptions{Cloud: config.Environment}
1828

1929
switch strings.ToLower(config.AuthMethod) {
20-
case "env":
30+
case authMethodEnv:
2131
if config.ClientID != "" && config.ClientSecret != "" && config.TenantID != "" {
2232
return azidentity.NewClientSecretCredential(config.TenantID, config.ClientID, config.ClientSecret,
2333
&azidentity.ClientSecretCredentialOptions{ClientOptions: clientOptions})
2434
}
2535

2636
return azidentity.NewEnvironmentCredential(&azidentity.EnvironmentCredentialOptions{ClientOptions: clientOptions})
2737

28-
case "wli":
38+
case authMethodWLI:
2939
return azidentity.NewWorkloadIdentityCredential(&azidentity.WorkloadIdentityCredentialOptions{ClientOptions: clientOptions})
3040

31-
case "msi":
41+
case authMethodMSI:
3242
cred, err := azidentity.NewManagedIdentityCredential(&azidentity.ManagedIdentityCredentialOptions{ClientOptions: clientOptions})
3343
if err != nil {
3444
return nil, err
3545
}
3646

3747
return &timeoutTokenCredential{cred: cred, timeout: config.AuthMSITimeout}, nil
3848

39-
case "cli":
49+
case authMethodCLI:
4050
var credOptions *azidentity.AzureCLICredentialOptions
4151
if config.TenantID != "" {
4252
credOptions = &azidentity.AzureCLICredentialOptions{TenantID: config.TenantID}
4353
}
4454
return azidentity.NewAzureCLICredential(credOptions)
4555

46-
case "oidc":
56+
case authMethodOIDC:
4757
err := checkOIDCConfig(config)
4858
if err != nil {
4959
return nil, err
5060
}
5161

5262
return azidentity.NewClientAssertionCredential(config.TenantID, config.ClientID, getOIDCAssertion(config), &azidentity.ClientAssertionCredentialOptions{ClientOptions: clientOptions})
5363

64+
case authMethodPipeline:
65+
err := checkPipelineConfig(config)
66+
if err != nil {
67+
return nil, err
68+
}
69+
70+
// Uses the env var `SYSTEM_OIDCREQUESTURI`,
71+
// but the constant is not exported,
72+
// and there is no way to set it programmatically.
73+
// https://github.com/Azure/azure-sdk-for-go/blob/aae2fb75ffccafc669db72bebc3c1a66332f48d7/sdk/azidentity/azure_pipelines_credential.go#L22
74+
// https://github.com/Azure/azure-sdk-for-go/blob/aae2fb75ffccafc669db72bebc3c1a66332f48d7/sdk/azidentity/azure_pipelines_credential.go#L79
75+
76+
return azidentity.NewAzurePipelinesCredential(config.TenantID, config.ClientID, config.ServiceConnectionID, config.SystemAccessToken, &azidentity.AzurePipelinesCredentialOptions{ClientOptions: clientOptions})
77+
5478
default:
5579
return azidentity.NewDefaultAzureCredential(&azidentity.DefaultAzureCredentialOptions{ClientOptions: clientOptions})
5680
}
@@ -97,3 +121,15 @@ func getZoneName(config *Config, fqdn string) (string, error) {
97121

98122
return authZone, nil
99123
}
124+
125+
func checkPipelineConfig(config *Config) error {
126+
if config.ServiceConnectionID == "" {
127+
return errors.New("azuredns: ServiceConnectionID is missing")
128+
}
129+
130+
if config.SystemAccessToken == "" {
131+
return errors.New("azuredns: SystemAccessToken is missing")
132+
}
133+
134+
return nil
135+
}

0 commit comments

Comments
 (0)