diff --git a/.github/infrastructure/conformance/azure/setup-azure-conf-test.sh b/.github/infrastructure/conformance/azure/setup-azure-conf-test.sh index c33d0fd2f7..0b3a9bbb89 100755 --- a/.github/infrastructure/conformance/azure/setup-azure-conf-test.sh +++ b/.github/infrastructure/conformance/azure/setup-azure-conf-test.sh @@ -181,6 +181,8 @@ IOT_HUB_PUBSUB_CONSUMER_GROUP_VAR_NAME="AzureIotHubPubsubConsumerGroup" KEYVAULT_CERT_NAME="AzureKeyVaultSecretStoreCert" KEYVAULT_CLIENT_ID_VAR_NAME="AzureKeyVaultSecretStoreClientId" +KEYVAULT_SERVICE_PRINCIPAL_CLIENT_SECRET_VAR_NAME="AzureKeyVaultSecretStoreServicePrincipalClientSecret" +KEYVAULT_SERVICE_PRINCIPAL_CLIENT_ID_VAR_NAME="AzureKeyVaultSecretStoreServicePrincipalClientId" KEYVAULT_TENANT_ID_VAR_NAME="AzureKeyVaultSecretStoreTenantId" KEYVAULT_NAME_VAR_NAME="AzureKeyVaultName" @@ -297,11 +299,17 @@ echo "INFO: SQL_SERVER_ADMIN_NAME=${SQL_SERVER_ADMIN_NAME}" # Give the service principal used by the SDK write access to the entire resource group MSYS_NO_PATHCONV=1 az role assignment create --assignee "${SDK_AUTH_SP_ID}" --role "Contributor" --scope "/subscriptions/${SUB_ID}/resourceGroups/${RESOURCE_GROUP_NAME}" -# Create Identity +# Create Identity if it doesn't exist # We use the standard name "azure-managed-identity" for the identity so we can easily query for it later using the CLI -echo "Creating Identity azure-managed-identity" -MANAGED_IDENTITY_SP="$(az identity create -g ${RESOURCE_GROUP_NAME} -n azure-managed-identity --location ${DEPLOY_LOCATION} --query principalId -otsv)" -# This identity can later be injected into services for managed identity authentication +if az identity show -g ${RESOURCE_GROUP_NAME} -n azure-managed-identity --query id -otsv; then + echo "Reusing Identity azure-managed-identity" + MANAGED_IDENTITY_SP="$(az identity show -g ${RESOURCE_GROUP_NAME} -n azure-managed-identity --query principalId -otsv)" +else + echo "Creating Identity azure-managed-identity" + MANAGED_IDENTITY_SP="$(az identity create -g ${RESOURCE_GROUP_NAME} -n azure-managed-identity --location ${DEPLOY_LOCATION} --query principalId -otsv)" + # This identity can later be injected into services for managed identity authentication +fi + MANAGED_IDENTITY_ID="$(az identity show -g ${RESOURCE_GROUP_NAME} -n azure-managed-identity --query id -otsv)" echo "Created Identity ${MANAGED_IDENTITY_ID}" @@ -313,6 +321,15 @@ az keyvault set-policy --name "${KEYVAULT_NAME}" -g "${RESOURCE_GROUP_NAME}" --s # Other tests verifying managed identity will want to grant permission like so: # MSYS_NO_PATHCONV=1 az role assignment create --assignee-object-id "${MANAGED_IDENTITY_SP}" --assignee-principal-type ServicePrincipal --role "Azure Service Bus Data Owner" --scope "/subscriptions/${SUB_ID}/resourceGroups/${RESOURCE_GROUP_NAME}/providers/Microsoft.ServiceBus/namespaces/${SERVICE_BUS_NAME}" +# Creating service principal for service principal authentication with KeyVault +AKV_SPAUTH_SP_NAME="${PREFIX}-akv-spauth-conf-test-sp" +echo "Creating service principal ${AKV_SPAUTH_SP_NAME} for use with KeyVault ${KEYVAULT_NAME}" +{ read AKV_SPAUTH_SP_CLIENT_ID ; read AKV_SPAUTH_SP_CLIENT_SECRET ; } < <(az ad sp create-for-rbac --name ${AKV_SPAUTH_SP_NAME} --skip-assignment --years 1 --query "[appId,password]" -otsv) + +# Give the service principal read access to the KeyVault Secrets +AKV_SPAUTH_SP_OBJECTID="$(az ad sp show --id ${AKV_SPAUTH_SP_CLIENT_ID} --query objectId -otsv)" +az keyvault set-policy --name "${KEYVAULT_NAME}" -g "${RESOURCE_GROUP_NAME}" --secret-permissions get list --object-id "${AKV_SPAUTH_SP_OBJECTID}" + # Update service principal credentials and roles for created resources echo "Creating ${CERT_AUTH_SP_NAME} certificate ..." az ad sp credential reset --name "${CERT_AUTH_SP_NAME}" --create-cert --cert "${KEYVAULT_CERT_NAME}" --keyvault "${KEYVAULT_NAME}" @@ -418,6 +435,13 @@ KEYVAULT_CLIENT_ID="$(az ad sp list --display-name "${CERT_AUTH_SP_NAME}" --quer echo export ${KEYVAULT_CLIENT_ID_VAR_NAME}=\"${KEYVAULT_CLIENT_ID}\" >> "${ENV_CONFIG_FILENAME}" az keyvault secret set --name "${KEYVAULT_CLIENT_ID_VAR_NAME}" --vault-name "${KEYVAULT_NAME}" --value "${KEYVAULT_CLIENT_ID}" +KEYVAULT_SERVICE_PRINCIPAL_CLIENT_ID=${AKV_SPAUTH_SP_CLIENT_ID} +echo export ${KEYVAULT_SERVICE_PRINCIPAL_CLIENT_ID_VAR_NAME}=\"${KEYVAULT_SERVICE_PRINCIPAL_CLIENT_ID}\" >> "${ENV_CONFIG_FILENAME}" +az keyvault secret set --name "${KEYVAULT_SERVICE_PRINCIPAL_CLIENT_ID_VAR_NAME}" --vault-name "${KEYVAULT_NAME}" --value "${KEYVAULT_SERVICE_PRINCIPAL_CLIENT_ID}" + +KEYVAULT_SERVICE_PRINCIPAL_CLIENT_SECRET=${AKV_SPAUTH_SP_CLIENT_SECRET} +echo export ${KEYVAULT_SERVICE_PRINCIPAL_CLIENT_SECRET_VAR_NAME}=\"${KEYVAULT_SERVICE_PRINCIPAL_CLIENT_SECRET}\" >> "${ENV_CONFIG_FILENAME}" +az keyvault secret set --name "${KEYVAULT_SERVICE_PRINCIPAL_CLIENT_SECRET_VAR_NAME}" --vault-name "${KEYVAULT_NAME}" --value "${KEYVAULT_SERVICE_PRINCIPAL_CLIENT_SECRET}" # ------------------------------------ # Populate Blob Storage test settings # ------------------------------------ diff --git a/.github/workflows/conformance.yml b/.github/workflows/conformance.yml index 96a8ea2dbf..9f2ba5245c 100644 --- a/.github/workflows/conformance.yml +++ b/.github/workflows/conformance.yml @@ -113,9 +113,11 @@ jobs: required-secrets: AzureServiceBusConnectionString - component: bindings.azure.storagequeues required-secrets: AzureBlobStorageAccessKey,AzureBlobStorageAccount,AzureBlobStorageQueue - - component: secretstores.azure.keyvault + - component: secretstores.azure.keyvault.certificate required-secrets: AzureKeyVaultName,AzureKeyVaultSecretStoreTenantId,AzureKeyVaultSecretStoreClientId required-certs: AzureKeyVaultSecretStoreCert + - component: secretstores.azure.keyvault.serviceprincipal + required-secrets: AzureKeyVaultName,AzureKeyVaultSecretStoreTenantId,AzureKeyVaultSecretStoreServicePrincipalClientId,AzureKeyVaultSecretStoreServicePrincipalClientSecret EOF ) echo "::set-output name=cron-components::$CRON_COMPONENTS" diff --git a/tests/config/secretstores/azure/keyvault/azure-keyvault.yaml b/tests/config/secretstores/azure/keyvault/certificate/azure-keyvault.yaml similarity index 100% rename from tests/config/secretstores/azure/keyvault/azure-keyvault.yaml rename to tests/config/secretstores/azure/keyvault/certificate/azure-keyvault.yaml diff --git a/tests/config/secretstores/azure/keyvault/serviceprincipal/azure-keyvault-service-principal.yaml b/tests/config/secretstores/azure/keyvault/serviceprincipal/azure-keyvault-service-principal.yaml new file mode 100644 index 0000000000..74147834f4 --- /dev/null +++ b/tests/config/secretstores/azure/keyvault/serviceprincipal/azure-keyvault-service-principal.yaml @@ -0,0 +1,15 @@ +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: azurekeyvault-service-principal +spec: + type: secretstores.azure.keyvault + metadata: + - name: vaultName + value: ${{AzureKeyVaultName}} + - name: azureTenantId + value: ${{AzureKeyVaultSecretStoreTenantId}} + - name: azureClientId + value: ${{AzureKeyVaultSecretStoreServicePrincipalClientId}} + - name: azureClientSecret + value: ${{AzureKeyVaultSecretStoreServicePrincipalClientSecret}} diff --git a/tests/config/secretstores/tests.yml b/tests/config/secretstores/tests.yml index 73d1b15f83..a879eecfca 100644 --- a/tests/config/secretstores/tests.yml +++ b/tests/config/secretstores/tests.yml @@ -5,7 +5,9 @@ components: operations: ["get"] - component: localfile allOperations: true - - component: azure.keyvault + - component: azure.keyvault.certificate + allOperations: true + - component: azure.keyvault.serviceprincipal allOperations: true - component: kubernetes allOperations: true diff --git a/tests/conformance/common.go b/tests/conformance/common.go index e8aa5e7c4e..9ebdf83b12 100644 --- a/tests/conformance/common.go +++ b/tests/conformance/common.go @@ -372,7 +372,9 @@ func loadPubSub(tc TestComponent) pubsub.PubSub { func loadSecretStore(tc TestComponent) secretstores.SecretStore { var store secretstores.SecretStore switch tc.Component { - case "azure.keyvault": + case "azure.keyvault.certificate": + store = ss_azure.NewAzureKeyvaultSecretStore(testLogger) + case "azure.keyvault.serviceprincipal": store = ss_azure.NewAzureKeyvaultSecretStore(testLogger) case "kubernetes": store = ss_kubernetes.NewKubernetesSecretStore(testLogger)