-
Notifications
You must be signed in to change notification settings - Fork 280
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
adding validation feature to azuredevops_serviceendpoint_azurerm reso… #865
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rdalbuquerque thanks for submit PR. A few changes requested and you need document the new feature in serviceendpoint_azurerm.html.markdown
var reqResult *serviceendpoint.ServiceEndpointRequestResult | ||
var err error | ||
log.Printf(fmt.Sprintf(":: serviceendpoint/commons.go :: %s :: Initiating validation", *endpoint.Name)) | ||
for i := 0; i < maxRetries; i++ { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we replace the retry code with resource.RetryContext()
, a simple retry util tool
@@ -23,7 +23,7 @@ func dataSourceServiceEndpointAzureRMRead(d *schema.ResourceData, m interface{}) | |||
if serviceEndpoint != nil { | |||
(*serviceEndpoint.Data)["creationMode"] = "" | |||
d.Set("service_endpoint_id", serviceEndpoint.Id.String()) | |||
flattenServiceEndpointAzureRM(d, serviceEndpoint, projectID) | |||
flattenServiceEndpointAzureRM(d, serviceEndpoint, projectID, false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The validation
flag is a feature of the resource, data source can ignore it and the data source schema not defined this property. There is also no validation
in the API response, true
or false
does no matter here.
@@ -161,6 +170,22 @@ func resourceServiceEndpointAzureRMCreate(d *schema.ResourceData, m interface{}) | |||
return err | |||
} | |||
|
|||
if validate { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we directly get the validate
with d.Get("validate")
instead of expandServiceEndpointAzureRM
.
flatten/expand
focuses on the core properties of flattening/expanding resources
@@ -181,30 +206,41 @@ func resourceServiceEndpointAzureRMRead(d *schema.ResourceData, m interface{}) e | |||
return fmt.Errorf(" looking up service endpoint given ID (%v) and project ID (%v): %v", getArgs.EndpointId, getArgs.Project, err) | |||
} | |||
|
|||
flattenServiceEndpointAzureRM(d, serviceEndpoint, (*serviceEndpoint.ServiceEndpointProjectReferences)[0].ProjectReference.Id) | |||
validate, ok := d.Get("validate").(bool) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can set validation
directly in read instead of flattenServiceEndpointAzureRM
validate, ok := d.Get("validate").(bool) | |
d.Set("validate", d.Get("validate").(bool)) |
@@ -146,12 +149,18 @@ func ResourceServiceEndpointAzureRM() *schema.Resource { | |||
Version: 1, | |||
}, | |||
} | |||
|
|||
r.Schema["validate"] = &schema.Schema{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we wrapper validate
into a features
block like build definition features ? This property is a feature not part of the API.
Thanks for the review @xuzhang3 , will start working on it now |
@xuzhang3 Only issue I caught is that even though the validation passes the variable group expansion might still fail. Upon further investigation I found that even though the validation passes once it might fail again right after (this issue is also reproducible through the UI). Looks like some kind of load balancing/replication issue after Although variable group extension might still fail after validation passes it drastically decreases the probability of said issue. this is the script I used to test this scenarios: $secretvars = @{
secretvars = @{}
}
$errCount = 0
for ($i = 0; $i -lt 5; $i++) {
$secretvars.secretvars["secret$i"] = "secretvalue"
$secretvars | ConvertTo-Json | Set-Content -Path secretvars.auto.tfvars.json
terraform apply -replace azuread_application_password.this -auto-approve | Tee-Object -Variable result
if (-not ($result -like '*Apply complete*')) {
$errCount++
Write-Warning "error occurred on run $i"
}
Start-Sleep -Seconds 10
}
Write-Host
Write-Warning "Total errors: $errCount" And the terraform resources: resource "azuread_application" "this" {
display_name = "test-serviceendpoint"
}
resource "azuread_service_principal" "this" {
application_id = azuread_application.this.application_id
}
resource "azuread_application_password" "this" {
depends_on = [ azurerm_key_vault_secret.this ]
application_object_id = azuread_application.this.object_id
}
resource "azuredevops_serviceendpoint_azurerm" "this" {
project_id = data.azuredevops_project.this.id
service_endpoint_name = "Example AzureRM"
description = "Managed by Terraform"
service_endpoint_authentication_scheme = "ServicePrincipal"
credentials {
serviceprincipalid = azuread_service_principal.this.application_id
serviceprincipalkey = azuread_application_password.this.value
}
azurerm_spn_tenantid = data.azurerm_client_config.current.tenant_id
azurerm_subscription_id = data.azurerm_client_config.current.subscription_id
azurerm_subscription_name = "prd"
features {
validate = true
}
}
resource "azurerm_resource_group" "this" {
name = "test-azuredevops-conn"
location = "eastus"
}
resource "azurerm_key_vault" "this" {
name = "test-azdo-conn"
resource_group_name = azurerm_resource_group.this.name
location = "eastus"
sku_name = "standard"
tenant_id = data.azurerm_client_config.current.tenant_id
enable_rbac_authorization = true
}
resource "azurerm_role_assignment" "data_admin_2_current_client" {
scope = azurerm_key_vault.this.id
role_definition_name = "Key Vault Administrator"
principal_id = data.azurerm_client_config.current.object_id
}
resource "azurerm_role_assignment" "secret_reader_2_conn" {
scope = azurerm_key_vault.this.id
role_definition_name = "Key Vault Secrets User"
principal_id = azuread_service_principal.this.object_id
}
## variable group linked to vault using the connection
variable "secretvars" {
type = map(string)
}
resource "azurerm_key_vault_secret" "this" {
for_each = var.secretvars
key_vault_id = azurerm_key_vault.this.id
name = each.key
value = each.value
}
resource "azuredevops_variable_group" "this" {
project_id = data.azuredevops_project.this.id
name = "Example Variable Group"
key_vault {
name = azurerm_key_vault.this.name
service_endpoint_id = azuredevops_serviceendpoint_azurerm.this.id
}
dynamic "variable" {
for_each = azurerm_key_vault_secret.this
content {
name = variable.value.name
}
}
} |
@rdalbuquerque can you help resolve the conflict? |
done :) |
|
@rdalbuquerque LGTM |
All Submissions:
What about the current behavior has changed?
Adding validation argument to verify if connection with azure is valid.
currently if you rotate the service principal credential backing a azurerm service endpoint it takes a little bit of time before the connection is valid again. That makes other dependent resources, like variable groups linked with Azure, return an error if they are also doing an operation that depends on said connection.
With
validate
argument set to true, the provider will verify the connection with a retry logic before completing the modification.Issue Number: #825
Also fixing error messages typos
Issue Number: #303
Does this introduce a change to
go.mod
,go.sum
orvendor/
?Does this introduce a breaking change?
Any relevant logs, error output, etc?
(If it’s long, please paste to https://ghostbin.com/ and insert the link here.)
Other information
The tradeoff is that if the secret is in fact wrong it will take 30 seconds to return an error