config: drop support for deprecated Azure's service principal authentication (#1906)

* invalidate app client id field for azure and provide info

* remove TestNewWithDefaultOptions case

* fix test

* remove appClientID field

* remove client secret + rename err

* remove from docs

* otto feedback

* update docs

* delete env test in cfg since no envs set anymore

* Update dev-docs/workflows/github-actions.md

Co-authored-by: Otto Bittner <cobittner@posteo.net>

* WARNING to stderr

* fix check

---------

Co-authored-by: Otto Bittner <cobittner@posteo.net>
This commit is contained in:
Adrian Stobbe 2023-06-14 17:50:57 +02:00 committed by GitHub
parent d964c74cbb
commit 07de6482b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 152 additions and 222 deletions

View file

@ -95,8 +95,6 @@ runs:
(.provider | select(. | has(\"azure\")).azure.location) = \"West US\" | (.provider | select(. | has(\"azure\")).azure.location) = \"West US\" |
(.provider | select(. | has(\"azure\")).azure.userAssignedIdentity) = \"${{ inputs.azureUserAssignedIdentity }}\" | (.provider | select(. | has(\"azure\")).azure.userAssignedIdentity) = \"${{ inputs.azureUserAssignedIdentity }}\" |
(.provider | select(. | has(\"azure\")).azure.resourceGroup) = \"${{ inputs.azureResourceGroup }}\" | (.provider | select(. | has(\"azure\")).azure.resourceGroup) = \"${{ inputs.azureResourceGroup }}\" |
(.provider | select(. | has(\"azure\")).azure.appClientID) = \"${{ inputs.azureClientID }}\" |
(.provider | select(. | has(\"azure\")).azure.clientSecretValue) = \"${{ inputs.azureClientSecret }}\"" \
constellation-conf.yaml constellation-conf.yaml
yq eval -i \ yq eval -i \

View file

@ -501,16 +501,10 @@ func (i *initCmd) getMarshaledServiceAccountURI(provider cloudprovider.Provider,
case cloudprovider.Azure: case cloudprovider.Azure:
i.log.Debugf("Handling case for Azure") i.log.Debugf("Handling case for Azure")
// TODO(3u13r): Remove this fallback and enforce assigned managed identity after the v2.8.0 but before the v2.9.0 release.
authMethod := azureshared.AuthMethodUserAssignedIdentity authMethod := azureshared.AuthMethodUserAssignedIdentity
if config.Provider.Azure.AppClientID != "" {
authMethod = azureshared.AuthMethodServicePrincipal
}
creds := azureshared.ApplicationCredentials{ creds := azureshared.ApplicationCredentials{
TenantID: config.Provider.Azure.TenantID, TenantID: config.Provider.Azure.TenantID,
AppClientID: config.Provider.Azure.AppClientID,
ClientSecretValue: config.Provider.Azure.ClientSecretValue,
Location: config.Provider.Azure.Location, Location: config.Provider.Azure.Location,
PreferredAuthMethod: authMethod, PreferredAuthMethod: authMethod,
UamiResourceID: config.Provider.Azure.UserAssignedIdentity, UamiResourceID: config.Provider.Azure.UserAssignedIdentity,

View file

@ -602,8 +602,6 @@ func defaultConfigWithExpectedMeasurements(t *testing.T, conf *config.Config, cs
conf.Provider.Azure.Location = "test-location" conf.Provider.Azure.Location = "test-location"
conf.Provider.Azure.UserAssignedIdentity = "test-identity" conf.Provider.Azure.UserAssignedIdentity = "test-identity"
conf.Provider.Azure.ResourceGroup = "test-resource-group" conf.Provider.Azure.ResourceGroup = "test-resource-group"
conf.Provider.Azure.AppClientID = "01234567-0123-0123-0123-0123456789ab"
conf.Provider.Azure.ClientSecretValue = "test-client-secret"
conf.Attestation.AzureSEVSNP.Measurements[4] = measurements.WithAllBytes(0x44, measurements.Enforce, measurements.PCRMeasurementLength) conf.Attestation.AzureSEVSNP.Measurements[4] = measurements.WithAllBytes(0x44, measurements.Enforce, measurements.PCRMeasurementLength)
conf.Attestation.AzureSEVSNP.Measurements[9] = measurements.WithAllBytes(0x11, measurements.Enforce, measurements.PCRMeasurementLength) conf.Attestation.AzureSEVSNP.Measurements[9] = measurements.WithAllBytes(0x11, measurements.Enforce, measurements.PCRMeasurementLength)
conf.Attestation.AzureSEVSNP.Measurements[12] = measurements.WithAllBytes(0xcc, measurements.Enforce, measurements.PCRMeasurementLength) conf.Attestation.AzureSEVSNP.Measurements[12] = measurements.WithAllBytes(0xcc, measurements.Enforce, measurements.PCRMeasurementLength)

View file

@ -47,7 +47,6 @@ func TestVerify(t *testing.T) {
formatter *stubAttDocFormatter formatter *stubAttDocFormatter
nodeEndpointFlag string nodeEndpointFlag string
configFlag string configFlag string
ownerIDFlag string
clusterIDFlag string clusterIDFlag string
idFile *clusterid.File idFile *clusterid.File
wantEndpoint string wantEndpoint string
@ -172,9 +171,6 @@ func TestVerify(t *testing.T) {
if tc.configFlag != "" { if tc.configFlag != "" {
require.NoError(cmd.Flags().Set("config", tc.configFlag)) require.NoError(cmd.Flags().Set("config", tc.configFlag))
} }
if tc.ownerIDFlag != "" {
require.NoError(cmd.Flags().Set("owner-id", tc.ownerIDFlag))
}
if tc.clusterIDFlag != "" { if tc.clusterIDFlag != "" {
require.NoError(cmd.Flags().Set("cluster-id", tc.clusterIDFlag)) require.NoError(cmd.Flags().Set("cluster-id", tc.clusterIDFlag))
} }
@ -183,15 +179,14 @@ func TestVerify(t *testing.T) {
} }
fileHandler := file.NewHandler(afero.NewMemMapFs()) fileHandler := file.NewHandler(afero.NewMemMapFs())
config := defaultConfigWithExpectedMeasurements(t, config.Default(), tc.provider) cfg := defaultConfigWithExpectedMeasurements(t, config.Default(), tc.provider)
require.NoError(fileHandler.WriteYAML(constants.ConfigFilename, config)) require.NoError(fileHandler.WriteYAML(constants.ConfigFilename, cfg))
if tc.idFile != nil { if tc.idFile != nil {
require.NoError(fileHandler.WriteJSON(constants.ClusterIDsFileName, tc.idFile, file.OptNone)) require.NoError(fileHandler.WriteJSON(constants.ClusterIDsFileName, tc.idFile, file.OptNone))
} }
v := &verifyCmd{log: logger.NewTest(t)} v := &verifyCmd{log: logger.NewTest(t)}
err := v.verify(cmd, fileHandler, tc.protoClient, tc.formatter, stubAttestationFetcher{}) err := v.verify(cmd, fileHandler, tc.protoClient, tc.formatter, stubAttestationFetcher{})
if tc.wantErr { if tc.wantErr {
assert.Error(err) assert.Error(err)
} else { } else {

View file

@ -366,8 +366,6 @@ func prepareAzureValues(values map[string]any) error {
return errors.New("missing 'autoscaler' key") return errors.New("missing 'autoscaler' key")
} }
autoscalerVals["Azure"] = map[string]any{ autoscalerVals["Azure"] = map[string]any{
"clientID": "AppClientID",
"clientSecret": "ClientSecretValue",
"resourceGroup": "resourceGroup", "resourceGroup": "resourceGroup",
"subscriptionID": "subscriptionID", "subscriptionID": "subscriptionID",
"tenantID": "TenantID", "tenantID": "TenantID",

View file

@ -3,6 +3,7 @@
This terraform configuration creates the necessary Azure resources that need to be available to host a Constellation cluster. This terraform configuration creates the necessary Azure resources that need to be available to host a Constellation cluster.
You can create the resources with the following commands: You can create the resources with the following commands:
```sh ```sh
mkdir constellation_azure_iam mkdir constellation_azure_iam
cd constellation_azure_iam cd constellation_azure_iam
@ -12,25 +13,19 @@ terraform apply
``` ```
The following terraform output values are available (with their corresponding keys in the Constellation configuration file): The following terraform output values are available (with their corresponding keys in the Constellation configuration file):
- `subscription_id` (subscription) - `subscription_id` (subscription)
- `tenant_id` (tenant) - `tenant_id` (tenant)
- `region` (location)
- `base_resource_group_name` (resourceGroup)
- `application_id` (appClientID)
- `uami_id` (userAssignedIdentity) - `uami_id` (userAssignedIdentity)
- `application_client_secret_value` (clientSecretValue) - **Sensitive Value**
You can either get the profile names from the Terraform output and manually add them to your Constellation configuration file according to our [Documentation](https://docs.edgeless.systems/constellation/getting-started/first-steps). You can either get the profile names from the Terraform output and manually add them to your Constellation configuration file according to our [Documentation](https://docs.edgeless.systems/constellation/getting-started/first-steps).
Or you can do this with a `yq` command: Or you can do this with a `yq` command:
```sh ```sh
yq -i " yq -i "
.provider.azure.subscription = $(terraform output subscription_id) | .provider.azure.subscription = $(terraform output subscription_id) |
.provider.azure.tenant = $(terraform output tenant_id) | .provider.azure.tenant = $(terraform output tenant_id) |
.provider.azure.location = $(terraform output region) |
.provider.azure.resourceGroup = $(terraform output base_resource_group_name) |
.provider.azure.appClientID = $(terraform output application_id) |
.provider.azure.userAssignedIdentity = $(terraform output uami_id) | .provider.azure.userAssignedIdentity = $(terraform output uami_id) |
.provider.azure.clientSecretValue = $(terraform output application_client_secret_value)
" path/to/constellation-conf.yaml " path/to/constellation-conf.yaml
``` ```

View file

@ -17,7 +17,7 @@ constellation create --name nfs -c 1 -w 3
We need block storage form somewhere. We will use the official Azure CSI for that. We need to create the azure config secret again with the expected fields. Replace "XXX" with the corresponding value from the secret `azureconfig`. We need block storage form somewhere. We will use the official Azure CSI for that. We need to create the azure config secret again with the expected fields. Replace "XXX" with the corresponding value from the secret `azureconfig`.
```bash ```bash
kubectl create secret generic -n kube-system --from-literal=cloud-config='{"cloud":"AzurePublicCloud","useInstanceMetadata":true,"vmType":"vmss","tenantId":"XXX","subscriptionId":"XXX","resourceGroup":"XXX","location":"XXX", "aadClientId":"XXX","aadClientSecret":"XXX"}' azure-config kubectl create secret generic -n kube-system --from-literal=cloud-config='{"cloud":"AzurePublicCloud","useInstanceMetadata":true,"vmType":"vmss","tenantId":"XXX","subscriptionId":"XXX","resourceGroup":"XXX","location":"XXX"}' azure-config
helm repo add azuredisk-csi-driver https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/charts helm repo add azuredisk-csi-driver https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/charts
helm repo update azuredisk-csi-driver helm repo update azuredisk-csi-driver

View file

@ -18,17 +18,18 @@ gh workflow run e2e-test-manual.yml \
Here are some examples for test suites you might want to run. Values for `sonobuoyTestSuiteCmd`: Here are some examples for test suites you might want to run. Values for `sonobuoyTestSuiteCmd`:
* `--mode quick` * `--mode quick`
* Runs a set of tests that are known to be quick to execute! (<1 min) * Runs a set of tests that are known to be quick to execute! (<1 min)
* `--e2e-focus "Services should be able to create a functioning NodePort service"` * `--e2e-focus "Services should be able to create a functioning NodePort service"`
* Runs a specific test * Runs a specific test
* `--mode certified-conformance` * `--mode certified-conformance`
* For K8s conformance certification test suite * For K8s conformance certification test suite
Check [Sonobuoy docs](https://sonobuoy.io/docs/latest/e2eplugin/) for more examples. Check [Sonobuoy docs](https://sonobuoy.io/docs/latest/e2eplugin/) for more examples.
When using `--mode` be aware that `--e2e-focus` and `e2e-skip` will be overwritten. [Check in the source code](https://github.com/vmware-tanzu/sonobuoy/blob/e709787426316423a4821927b1749d5bcc90cb8c/cmd/sonobuoy/app/modes.go#L130) what the different modes do. When using `--mode` be aware that `--e2e-focus` and `e2e-skip` will be overwritten. [Check in the source code](https://github.com/vmware-tanzu/sonobuoy/blob/e709787426316423a4821927b1749d5bcc90cb8c/cmd/sonobuoy/app/modes.go#L130) what the different modes do.
## Local Development ## Local Development
Using [***act***](https://github.com/nektos/act) you can run GitHub actions locally. Using [***act***](https://github.com/nektos/act) you can run GitHub actions locally.
**These instructions are for internal use.** **These instructions are for internal use.**
@ -83,25 +84,4 @@ In addition, you need to create a Service Account which Constellation itself is
### Authorizing Azure ### Authorizing Azure
Create a new service principal: See [here](https://docs.edgeless.systems/constellation/workflows/config#creating-iam-credentials).
```bash
az ad sp create-for-rbac --name "github-actions-e2e-tests" --role contributor --scopes /subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435 --sdk-auth
az role assignment create --role "User Access Administrator" --scope /subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435 --assignee <SERVICE_PRINCIPAL_CLIENT_ID>
```
Next, add API permissions to Managed Identity:
* Not possible through portal; requires PowerShell
* <https://techcommunity.microsoft.com/t5/integrations-on-azure-blog/grant-graph-api-permission-to-managed-identity-object/ba-p/2792127>
* `$GraphAppId` in this article is for Microsoft Graph. Azure AD Graph is `00000002-0000-0000-c000-000000000000`
* Note that changing permissions can take between few seconds to several hours
Afterward, you need to define a few secrets either as Github Action Secrets or in a secrets file for *act* as described before.
The following secrets need to be defined:
* `AZURE_E2E_CREDENTIALS`: The output of `az ad sp ...`
* `AZURE_E2E_CLIENT_SECRET`: The client secret value for the registered app on Azure (which is defined as `appClientID`).
For information on how to achieve this, refer to the [First steps](https://docs.edgeless.systems/constellation/getting-started/first-steps) in the documentation for Constellation.

View file

@ -5,7 +5,7 @@ Use [`constellation config migrate`](./cli.md#constellation-config-migrate) to a
## Migrating from Azure's service principal authentication to managed identity authentication ## Migrating from Azure's service principal authentication to managed identity authentication
- The `provider.azure.appClientID` and `provider.azure.appClientSecret` fields are no longer required and should be removed. - The `provider.azure.appClientID` and `provider.azure.appClientSecret` fields are no longer supported and should be removed.
- To keep using an existing UAMI add the `Owner` permission with the scope of your `resourceGroup`. - To keep using an existing UAMI add the `Owner` permission with the scope of your `resourceGroup`.
- Otherwise, simply [create new Constellation IAM credentials](../workflows/config.md#creating-iam-credentials) and use the created UAMI. - Otherwise, simply [create new Constellation IAM credentials](../workflows/config.md#creating-iam-credentials) and use the created UAMI.
- To migrate the authentication for an existing Constellation on Azure to an UAMI with the necessary permissions: - To migrate the authentication for an existing Constellation on Azure to an UAMI with the necessary permissions:
@ -13,6 +13,9 @@ Use [`constellation config migrate`](./cli.md#constellation-config-migrate) to a
2. Set `useManagedIdentityExtension` to `true` and use the `userAssignedIdentity` from the Constellation config for the value of `userAssignedIdentityID`. 2. Set `useManagedIdentityExtension` to `true` and use the `userAssignedIdentity` from the Constellation config for the value of `userAssignedIdentityID`.
3. Restart the CSI driver, cloud controller manager, cluster autoscaler, and Constellation operator pods. 3. Restart the CSI driver, cloud controller manager, cluster autoscaler, and Constellation operator pods.
## Migrating from CLI versions before 2.9
- The `provider.azure.appClientID` and `provider.azure.clientSecretValue` fields were removed to enforce migration to managed identity authentication
## Migrating from CLI versions before 2.8 ## Migrating from CLI versions before 2.8
@ -20,7 +23,6 @@ Use [`constellation config migrate`](./cli.md#constellation-config-migrate) to a
- The `confidentialVM`, `idKeyDigest`, and `enforceIdKeyDigest` fields for the Azure cloud service provider were removed in favor of using the global `attestation` field. - The `confidentialVM`, `idKeyDigest`, and `enforceIdKeyDigest` fields for the Azure cloud service provider were removed in favor of using the global `attestation` field.
- The optional global field `attestationVariant` was replaced by the now required `attestation` field. - The optional global field `attestationVariant` was replaced by the now required `attestation` field.
## Migrating from CLI versions before 2.3 ## Migrating from CLI versions before 2.3
- The `sshUsers` field was deprecated in v2.2 and has been removed from the configuration in v2.3. - The `sshUsers` field was deprecated in v2.2 and has been removed from the configuration in v2.3.

View file

@ -91,6 +91,7 @@ constellation iam create azure --region=westus --resourceGroup=constellTest --se
This command creates IAM configuration on the Azure region `westus` creating a new resource group `constellTest` and a new service principal `spTest`. This command creates IAM configuration on the Azure region `westus` creating a new resource group `constellTest` and a new service principal `spTest`.
Note that CVMs are currently only supported in a few regions, check [Azure's products available by region](https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines&regions=all). These are: Note that CVMs are currently only supported in a few regions, check [Azure's products available by region](https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines&regions=all). These are:
* `westus` * `westus`
* `eastus` * `eastus`
* `northeurope` * `northeurope`
@ -98,10 +99,6 @@ Note that CVMs are currently only supported in a few regions, check [Azure's pro
Paste the output into the corresponding fields of the `constellation-conf.yaml` file. Paste the output into the corresponding fields of the `constellation-conf.yaml` file.
:::tip
Since `clientSecretValue` is a sensitive value, you can leave it empty in the configuration file and pass it via an environment variable instead. To this end, create the environment variable `CONSTELL_AZURE_CLIENT_SECRET_VALUE` and set it to the secret value.
:::
</tabItem> </tabItem>
<tabItem value="gcp" label="GCP"> <tabItem value="gcp" label="GCP">
@ -129,6 +126,7 @@ constellation iam create aws --zone=eu-central-1a --prefix=constellTest
This command creates IAM configuration for the AWS zone `eu-central-1a` using the prefix `constellTest` for all named resources being created. This command creates IAM configuration for the AWS zone `eu-central-1a` using the prefix `constellTest` for all named resources being created.
Constellation OS images are currently replicated to the following regions: Constellation OS images are currently replicated to the following regions:
* `eu-central-1` * `eu-central-1`
* `eu-west-1` * `eu-west-1`
* `eu-west-3` * `eu-west-3`
@ -178,22 +176,6 @@ The following describes the configuration fields and how you obtain the required
The user-assigned identity is used by instances of the cluster to access other cloud resources. The user-assigned identity is used by instances of the cluster to access other cloud resources.
For more information about managed identities refer to [Azure's documentation](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-manage-user-assigned-managed-identities). For more information about managed identities refer to [Azure's documentation](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-manage-user-assigned-managed-identities).
* **appClientID**: [Create a new app registration in Azure](https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/CreateApplicationBlade/quickStartType~/null/isMSAApp~/false).
Set `Supported account types` to `Accounts in this organizational directory only` and leave the `Redirect URI` empty.
Set the configuration value to the `Application (client) ID`, e.g., `86ec31dd-532b-4a8c-a055-dd23f25fb12f`.
In the cluster resource group, go to `Access Control (IAM)` and set the created app registration as `Owner`.
* **clientSecretValue**: In the previously created app registration, go to `Certificates & secrets` and create a new `Client secret`.
Set the configuration value to the secret value.
:::tip
Since this is a sensitive value, alternatively you can leave `clientSecretValue` empty in the configuration file and pass it via an environment variable instead. To this end, create the environment variable `CONSTELL_AZURE_CLIENT_SECRET_VALUE` and set it to the secret value.
:::
</tabItem> </tabItem>
<tabItem value="gcp" label="GCP"> <tabItem value="gcp" label="GCP">
@ -212,11 +194,11 @@ The following describes the configuration fields and how you obtain the required
* **serviceAccountKeyPath**: To configure this, you need to create a GCP [service account](https://cloud.google.com/iam/docs/service-accounts) with the following permissions: * **serviceAccountKeyPath**: To configure this, you need to create a GCP [service account](https://cloud.google.com/iam/docs/service-accounts) with the following permissions:
- `Compute Instance Admin (v1) (roles/compute.instanceAdmin.v1)` * `Compute Instance Admin (v1) (roles/compute.instanceAdmin.v1)`
- `Compute Network Admin (roles/compute.networkAdmin)` * `Compute Network Admin (roles/compute.networkAdmin)`
- `Compute Security Admin (roles/compute.securityAdmin)` * `Compute Security Admin (roles/compute.securityAdmin)`
- `Compute Storage Admin (roles/compute.storageAdmin)` * `Compute Storage Admin (roles/compute.storageAdmin)`
- `Service Account User (roles/iam.serviceAccountUser)` * `Service Account User (roles/iam.serviceAccountUser)`
Afterward, create and download a new JSON key for this service account. Place the downloaded file in your Constellation workspace, and set the config parameter to the filename, e.g., `constellation-129857-15343dba46cb.json`. Afterward, create and download a new JSON key for this service account. Place the downloaded file in your Constellation workspace, and set the config parameter to the filename, e.g., `constellation-129857-15343dba46cb.json`.
@ -265,6 +247,7 @@ Now that you've configured your CSP, you can [create your cluster](./create.md).
You can keep a created IAM configuration and reuse it for new clusters. Alternatively, you can also delete it if you don't want to use it anymore. You can keep a created IAM configuration and reuse it for new clusters. Alternatively, you can also delete it if you don't want to use it anymore.
Delete the IAM configuration by executing the following command in the same directory where you executed `constellation iam create` (the directory that contains [`constellation-iam-terraform`](../reference/terraform.md) as a subdirectory): Delete the IAM configuration by executing the following command in the same directory where you executed `constellation iam create` (the directory that contains [`constellation-iam-terraform`](../reference/terraform.md) as a subdirectory):
```bash ```bash
constellation iam destroy constellation iam destroy
``` ```

View file

@ -147,8 +147,6 @@ func (c *Cloud) GetCCMConfig(ctx context.Context, providerID string, cloudServic
Location: creds.Location, Location: creds.Location,
UseManagedIdentityExtension: useManagedIdentityExtension, UseManagedIdentityExtension: useManagedIdentityExtension,
UserAssignedIdentityID: uamiClientID, UserAssignedIdentityID: uamiClientID,
AADClientID: creds.AppClientID,
AADClientSecret: creds.ClientSecretValue,
} }
return json.Marshal(config) return json.Marshal(config)
@ -429,8 +427,6 @@ type cloudConfig struct {
VMType string `json:"vmType,omitempty"` VMType string `json:"vmType,omitempty"`
UseManagedIdentityExtension bool `json:"useManagedIdentityExtension,omitempty"` UseManagedIdentityExtension bool `json:"useManagedIdentityExtension,omitempty"`
UserAssignedIdentityID string `json:"userAssignedIdentityID,omitempty"` UserAssignedIdentityID string `json:"userAssignedIdentityID,omitempty"`
AADClientID string `json:"aadClientId,omitempty"`
AADClientSecret string `json:"aadClientSecret,omitempty"`
} }
// convertToInstanceMetadata converts a armcomputev2.VirtualMachineScaleSetVM to a metadata.InstanceMetadata. // convertToInstanceMetadata converts a armcomputev2.VirtualMachineScaleSetVM to a metadata.InstanceMetadata.

View file

@ -102,8 +102,6 @@ func TestGetCCMConfig(t *testing.T) {
UserAssignedIdentityID: uamiClientID, UserAssignedIdentityID: uamiClientID,
VMType: "vmss", VMType: "vmss",
Location: "westeurope", Location: "westeurope",
AADClientID: "client-id",
AADClientSecret: "client-secret",
}, },
}, },
"no app registration": { "no app registration": {
@ -210,8 +208,6 @@ func TestGetCCMConfig(t *testing.T) {
UseInstanceMetadata: true, UseInstanceMetadata: true,
VMType: "vmss", VMType: "vmss",
Location: "westeurope", Location: "westeurope",
AADClientID: "client-id",
AADClientSecret: "client-secret",
}, },
}, },
"load balancer list error": { "load balancer list error": {

View file

@ -35,6 +35,7 @@ go_library(
"@com_github_go_playground_validator_v10//:validator", "@com_github_go_playground_validator_v10//:validator",
"@com_github_go_playground_validator_v10//translations/en", "@com_github_go_playground_validator_v10//translations/en",
"@com_github_siderolabs_talos_pkg_machinery//config/encoder", "@com_github_siderolabs_talos_pkg_machinery//config/encoder",
"@in_gopkg_yaml_v3//:yaml_v3",
"@org_golang_x_mod//semver", "@org_golang_x_mod//semver",
], ],
) )

View file

@ -33,6 +33,7 @@ import (
ut "github.com/go-playground/universal-translator" ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
en_translations "github.com/go-playground/validator/v10/translations/en" en_translations "github.com/go-playground/validator/v10/translations/en"
"gopkg.in/yaml.v3"
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi" "github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest" "github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
@ -145,12 +146,6 @@ type AzureConfig struct {
// Authorize spawned VMs to access Azure API. // Authorize spawned VMs to access Azure API.
UserAssignedIdentity string `yaml:"userAssignedIdentity" validate:"required"` UserAssignedIdentity string `yaml:"userAssignedIdentity" validate:"required"`
// description: | // description: |
// Application client ID of the Active Directory app registration.
AppClientID string `yaml:"appClientID,omitempty" validate:"omitempty,uuid"`
// description: |
// Client secret value of the Active Directory app registration credentials. Alternatively leave empty and pass value via CONSTELL_AZURE_CLIENT_SECRET_VALUE environment variable.
ClientSecretValue string `yaml:"clientSecretValue,omitempty" validate:"omitempty"`
// description: |
// VM instance type to use for Constellation nodes. // VM instance type to use for Constellation nodes.
InstanceType string `yaml:"instanceType" validate:"azure_instance_type"` InstanceType string `yaml:"instanceType" validate:"azure_instance_type"`
// description: | // description: |
@ -381,11 +376,33 @@ func fromFile(fileHandler file.Handler, name string) (*Config, error) {
if errors.Is(err, fs.ErrNotExist) { if errors.Is(err, fs.ErrNotExist) {
return nil, fmt.Errorf("unable to find %s - use `constellation config generate` to generate it first", name) return nil, fmt.Errorf("unable to find %s - use `constellation config generate` to generate it first", name)
} }
if isAppClientIDError(err) {
return nil, UnsupportedAppRegistrationError{}
}
return nil, fmt.Errorf("could not load config from file %s: %w", name, err) return nil, fmt.Errorf("could not load config from file %s: %w", name, err)
} }
return &conf, nil return &conf, nil
} }
func isAppClientIDError(err error) bool {
var yamlErr *yaml.TypeError
if errors.As(err, &yamlErr) {
for _, e := range yamlErr.Errors {
if strings.Contains(e, "appClientID") {
return true
}
}
}
return false
}
// UnsupportedAppRegistrationError is returned when the config contains configuration related to now unsupported app registrations.
type UnsupportedAppRegistrationError struct{}
func (e UnsupportedAppRegistrationError) Error() string {
return "Azure app registrations are not supported since v2.9. migrate to using a user assigned managed identity by following the migration guide: https://docs.edgeless.systems/constellation/reference/migration.\nplease remove it from your config and from the Kubernetes secret in your running cluster. ensure that the UAMI has all required permissions."
}
// New creates a new config by: // New creates a new config by:
// 1. Reading config file via provided fileHandler from file with name. // 1. Reading config file via provided fileHandler from file with name.
// 2. For "latest" version values of the attestation variants fetch the version numbers. // 2. For "latest" version values of the attestation variants fetch the version numbers.
@ -407,7 +424,7 @@ func New(fileHandler file.Handler, name string, fetcher attestationconfigapi.Fet
// Read secrets from env-vars. // Read secrets from env-vars.
clientSecretValue := os.Getenv(constants.EnvVarAzureClientSecretValue) clientSecretValue := os.Getenv(constants.EnvVarAzureClientSecretValue)
if clientSecretValue != "" && c.Provider.Azure != nil { if clientSecretValue != "" && c.Provider.Azure != nil {
c.Provider.Azure.ClientSecretValue = clientSecretValue fmt.Fprintf(os.Stderr, "WARNING: the environment variable %s is no longer used %s", constants.EnvVarAzureClientSecretValue, UnsupportedAppRegistrationError{}.Error())
} }
openstackPassword := os.Getenv(constants.EnvVarOpenStackPassword) openstackPassword := os.Getenv(constants.EnvVarOpenStackPassword)
@ -421,14 +438,6 @@ func New(fileHandler file.Handler, name string, fetcher attestationconfigapi.Fet
c.MicroserviceVersion = Default().MicroserviceVersion c.MicroserviceVersion = Default().MicroserviceVersion
} }
// TODO(3u13r): Remove this deprecation warning and enforce assigned managed identity after the v2.8.0 but before the v2.9.0 release.
if c.Provider.Azure != nil &&
(c.Provider.Azure.AppClientID != "" || c.Provider.Azure.ClientSecretValue != "") {
// Deprecation warning for old auth method
fmt.Fprintf(os.Stderr, "WARNING: Using a service principal for authentication is deprecated and will be removed in an upcoming version.\n")
fmt.Fprintf(os.Stderr, " Migrate to using a user assigned managed identity by following the migration guide: https://docs.edgeless.systems/constellation/reference/migration.\n")
}
return c, c.Validate(force) return c, c.Validate(force)
} }

View file

@ -11,22 +11,23 @@ import (
) )
var ( var (
ConfigDoc encoder.Doc ConfigDoc encoder.Doc
ProviderConfigDoc encoder.Doc ProviderConfigDoc encoder.Doc
AWSConfigDoc encoder.Doc AWSConfigDoc encoder.Doc
AzureConfigDoc encoder.Doc AzureConfigDoc encoder.Doc
GCPConfigDoc encoder.Doc GCPConfigDoc encoder.Doc
OpenStackConfigDoc encoder.Doc OpenStackConfigDoc encoder.Doc
QEMUConfigDoc encoder.Doc QEMUConfigDoc encoder.Doc
AttestationConfigDoc encoder.Doc AttestationConfigDoc encoder.Doc
AWSSEVSNPDoc encoder.Doc UnsupportedAppRegistrationErrorDoc encoder.Doc
AWSNitroTPMDoc encoder.Doc AWSSEVSNPDoc encoder.Doc
SNPFirmwareSignerConfigDoc encoder.Doc AWSNitroTPMDoc encoder.Doc
GCPSEVESDoc encoder.Doc SNPFirmwareSignerConfigDoc encoder.Doc
QEMUVTPMDoc encoder.Doc GCPSEVESDoc encoder.Doc
QEMUTDXDoc encoder.Doc QEMUVTPMDoc encoder.Doc
AzureSEVSNPDoc encoder.Doc QEMUTDXDoc encoder.Doc
AzureTrustedLaunchDoc encoder.Doc AzureSEVSNPDoc encoder.Doc
AzureTrustedLaunchDoc encoder.Doc
) )
func init() { func init() {
@ -166,7 +167,7 @@ func init() {
FieldName: "azure", FieldName: "azure",
}, },
} }
AzureConfigDoc.Fields = make([]encoder.Doc, 11) AzureConfigDoc.Fields = make([]encoder.Doc, 9)
AzureConfigDoc.Fields[0].Name = "subscription" AzureConfigDoc.Fields[0].Name = "subscription"
AzureConfigDoc.Fields[0].Type = "string" AzureConfigDoc.Fields[0].Type = "string"
AzureConfigDoc.Fields[0].Note = "" AzureConfigDoc.Fields[0].Note = ""
@ -192,36 +193,26 @@ func init() {
AzureConfigDoc.Fields[4].Note = "" AzureConfigDoc.Fields[4].Note = ""
AzureConfigDoc.Fields[4].Description = "Authorize spawned VMs to access Azure API." AzureConfigDoc.Fields[4].Description = "Authorize spawned VMs to access Azure API."
AzureConfigDoc.Fields[4].Comments[encoder.LineComment] = "Authorize spawned VMs to access Azure API." AzureConfigDoc.Fields[4].Comments[encoder.LineComment] = "Authorize spawned VMs to access Azure API."
AzureConfigDoc.Fields[5].Name = "appClientID" AzureConfigDoc.Fields[5].Name = "instanceType"
AzureConfigDoc.Fields[5].Type = "string" AzureConfigDoc.Fields[5].Type = "string"
AzureConfigDoc.Fields[5].Note = "" AzureConfigDoc.Fields[5].Note = ""
AzureConfigDoc.Fields[5].Description = "Application client ID of the Active Directory app registration." AzureConfigDoc.Fields[5].Description = "VM instance type to use for Constellation nodes."
AzureConfigDoc.Fields[5].Comments[encoder.LineComment] = "Application client ID of the Active Directory app registration." AzureConfigDoc.Fields[5].Comments[encoder.LineComment] = "VM instance type to use for Constellation nodes."
AzureConfigDoc.Fields[6].Name = "clientSecretValue" AzureConfigDoc.Fields[6].Name = "stateDiskType"
AzureConfigDoc.Fields[6].Type = "string" AzureConfigDoc.Fields[6].Type = "string"
AzureConfigDoc.Fields[6].Note = "" AzureConfigDoc.Fields[6].Note = ""
AzureConfigDoc.Fields[6].Description = "Client secret value of the Active Directory app registration credentials. Alternatively leave empty and pass value via CONSTELL_AZURE_CLIENT_SECRET_VALUE environment variable." AzureConfigDoc.Fields[6].Description = "Type of a node's state disk. The type influences boot time and I/O performance. See: https://docs.microsoft.com/en-us/azure/virtual-machines/disks-types#disk-type-comparison"
AzureConfigDoc.Fields[6].Comments[encoder.LineComment] = "Client secret value of the Active Directory app registration credentials. Alternatively leave empty and pass value via CONSTELL_AZURE_CLIENT_SECRET_VALUE environment variable." AzureConfigDoc.Fields[6].Comments[encoder.LineComment] = "Type of a node's state disk. The type influences boot time and I/O performance. See: https://docs.microsoft.com/en-us/azure/virtual-machines/disks-types#disk-type-comparison"
AzureConfigDoc.Fields[7].Name = "instanceType" AzureConfigDoc.Fields[7].Name = "deployCSIDriver"
AzureConfigDoc.Fields[7].Type = "string" AzureConfigDoc.Fields[7].Type = "bool"
AzureConfigDoc.Fields[7].Note = "" AzureConfigDoc.Fields[7].Note = ""
AzureConfigDoc.Fields[7].Description = "VM instance type to use for Constellation nodes." AzureConfigDoc.Fields[7].Description = "Deploy Azure Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage"
AzureConfigDoc.Fields[7].Comments[encoder.LineComment] = "VM instance type to use for Constellation nodes." AzureConfigDoc.Fields[7].Comments[encoder.LineComment] = "Deploy Azure Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage"
AzureConfigDoc.Fields[8].Name = "stateDiskType" AzureConfigDoc.Fields[8].Name = "secureBoot"
AzureConfigDoc.Fields[8].Type = "string" AzureConfigDoc.Fields[8].Type = "bool"
AzureConfigDoc.Fields[8].Note = "" AzureConfigDoc.Fields[8].Note = ""
AzureConfigDoc.Fields[8].Description = "Type of a node's state disk. The type influences boot time and I/O performance. See: https://docs.microsoft.com/en-us/azure/virtual-machines/disks-types#disk-type-comparison" AzureConfigDoc.Fields[8].Description = "Enable secure boot for VMs. If enabled, the OS image has to include a virtual machine guest state (VMGS) blob."
AzureConfigDoc.Fields[8].Comments[encoder.LineComment] = "Type of a node's state disk. The type influences boot time and I/O performance. See: https://docs.microsoft.com/en-us/azure/virtual-machines/disks-types#disk-type-comparison" AzureConfigDoc.Fields[8].Comments[encoder.LineComment] = "Enable secure boot for VMs. If enabled, the OS image has to include a virtual machine guest state (VMGS) blob."
AzureConfigDoc.Fields[9].Name = "deployCSIDriver"
AzureConfigDoc.Fields[9].Type = "bool"
AzureConfigDoc.Fields[9].Note = ""
AzureConfigDoc.Fields[9].Description = "Deploy Azure Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage"
AzureConfigDoc.Fields[9].Comments[encoder.LineComment] = "Deploy Azure Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage"
AzureConfigDoc.Fields[10].Name = "secureBoot"
AzureConfigDoc.Fields[10].Type = "bool"
AzureConfigDoc.Fields[10].Note = ""
AzureConfigDoc.Fields[10].Description = "Enable secure boot for VMs. If enabled, the OS image has to include a virtual machine guest state (VMGS) blob."
AzureConfigDoc.Fields[10].Comments[encoder.LineComment] = "Enable secure boot for VMs. If enabled, the OS image has to include a virtual machine guest state (VMGS) blob."
GCPConfigDoc.Type = "GCPConfig" GCPConfigDoc.Type = "GCPConfig"
GCPConfigDoc.Comments[encoder.LineComment] = "GCPConfig are GCP specific configuration values used by the CLI." GCPConfigDoc.Comments[encoder.LineComment] = "GCPConfig are GCP specific configuration values used by the CLI."
@ -467,6 +458,11 @@ func init() {
AttestationConfigDoc.Fields[6].Description = "QEMU vTPM attestation." AttestationConfigDoc.Fields[6].Description = "QEMU vTPM attestation."
AttestationConfigDoc.Fields[6].Comments[encoder.LineComment] = "QEMU vTPM attestation." AttestationConfigDoc.Fields[6].Comments[encoder.LineComment] = "QEMU vTPM attestation."
UnsupportedAppRegistrationErrorDoc.Type = "UnsupportedAppRegistrationError"
UnsupportedAppRegistrationErrorDoc.Comments[encoder.LineComment] = "UnsupportedAppRegistrationError is returned when the config contains configuration related to now unsupported app registrations."
UnsupportedAppRegistrationErrorDoc.Description = "UnsupportedAppRegistrationError is returned when the config contains configuration related to now unsupported app registrations."
UnsupportedAppRegistrationErrorDoc.Fields = make([]encoder.Doc, 0)
AWSSEVSNPDoc.Type = "AWSSEVSNP" AWSSEVSNPDoc.Type = "AWSSEVSNP"
AWSSEVSNPDoc.Comments[encoder.LineComment] = "AWSSEVSNP is the configuration for AWS SEV-SNP attestation." AWSSEVSNPDoc.Comments[encoder.LineComment] = "AWSSEVSNP is the configuration for AWS SEV-SNP attestation."
AWSSEVSNPDoc.Description = "AWSSEVSNP is the configuration for AWS SEV-SNP attestation." AWSSEVSNPDoc.Description = "AWSSEVSNP is the configuration for AWS SEV-SNP attestation."
@ -673,6 +669,10 @@ func (_ AttestationConfig) Doc() *encoder.Doc {
return &AttestationConfigDoc return &AttestationConfigDoc
} }
func (_ UnsupportedAppRegistrationError) Doc() *encoder.Doc {
return &UnsupportedAppRegistrationErrorDoc
}
func (_ AWSSEVSNP) Doc() *encoder.Doc { func (_ AWSSEVSNP) Doc() *encoder.Doc {
return &AWSSEVSNPDoc return &AWSSEVSNPDoc
} }
@ -719,6 +719,7 @@ func GetConfigurationDoc() *encoder.FileDoc {
&OpenStackConfigDoc, &OpenStackConfigDoc,
&QEMUConfigDoc, &QEMUConfigDoc,
&AttestationConfigDoc, &AttestationConfigDoc,
&UnsupportedAppRegistrationErrorDoc,
&AWSSEVSNPDoc, &AWSSEVSNPDoc,
&AWSNitroTPMDoc, &AWSNitroTPMDoc,
&SNPFirmwareSignerConfigDoc, &SNPFirmwareSignerConfigDoc,

View file

@ -59,10 +59,11 @@ func TestDefaultConfigWritesLatestVersion(t *testing.T) {
func TestNew(t *testing.T) { func TestNew(t *testing.T) {
testCases := map[string]struct { testCases := map[string]struct {
config configMap config configMap
configName string configName string
wantResult *Config wantResult *Config
wantErr bool wantErr bool
wantedErrType error
}{ }{
"Azure SEV-SNP: mix of Latest and uint as version value in file correctly sets latest versions values": { "Azure SEV-SNP: mix of Latest and uint as version value in file correctly sets latest versions values": {
config: func() configMap { config: func() configMap {
@ -150,6 +151,16 @@ func TestReadConfigFile(t *testing.T) {
configName: constants.ConfigFilename, configName: constants.ConfigFilename,
wantErr: true, wantErr: true,
}, },
"error on entering app client id": {
config: func() configMap {
conf := Default()
m := getConfigAsMap(conf, t)
m.setAzureProvider("appClientID", "3ea4bdc1-1cc1-4237-ae78-0831eff3491e")
return m
}(),
configName: constants.ConfigFilename,
wantedErrType: UnsupportedAppRegistrationError{},
},
} }
for name, tc := range testCases { for name, tc := range testCases {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
@ -161,12 +172,16 @@ func TestReadConfigFile(t *testing.T) {
require.NoError(fileHandler.WriteYAML(tc.configName, tc.config, file.OptNone)) require.NoError(fileHandler.WriteYAML(tc.configName, tc.config, file.OptNone))
} }
result, err := fromFile(fileHandler, tc.configName) result, err := fromFile(fileHandler, tc.configName)
if tc.wantedErrType != nil {
assert.ErrorIs(err, tc.wantedErrType)
return
}
if tc.wantErr { if tc.wantErr {
assert.Error(err) assert.Error(err)
} else { return
assert.NoError(err)
assert.Equal(tc.wantResult, result)
} }
assert.NoError(err)
assert.Equal(tc.wantResult, result)
}) })
} }
} }
@ -246,67 +261,6 @@ func TestFromFile(t *testing.T) {
} }
} }
func TestNewWithDefaultOptions(t *testing.T) {
testCases := map[string]struct {
confToWrite *Config
envToSet map[string]string
wantErr bool
wantClientSecretValue string
}{
"set env works": {
confToWrite: func() *Config { // valid config with all, but clientSecretValue
c := Default()
c.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
modifyConfigForAzureToPassValidate(c)
return c
}(),
envToSet: map[string]string{
constants.EnvVarAzureClientSecretValue: "some-secret",
},
wantClientSecretValue: "some-secret",
},
"set env overwrites": {
confToWrite: func() *Config {
c := Default()
modifyConfigForAzureToPassValidate(c)
return c
}(),
envToSet: map[string]string{
constants.EnvVarAzureClientSecretValue: "some-secret",
},
wantClientSecretValue: "some-secret",
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
// Setup
fileHandler := file.NewHandler(afero.NewMemMapFs())
err := fileHandler.WriteYAML(constants.ConfigFilename, tc.confToWrite)
require.NoError(err)
for envKey, envValue := range tc.envToSet {
t.Setenv(envKey, envValue)
}
// Test
c, err := New(fileHandler, constants.ConfigFilename, stubAttestationFetcher{}, false)
if tc.wantErr {
assert.Error(err)
return
}
assert.NoError(err)
var validationErr *ValidationError
if errors.As(err, &validationErr) {
t.Log(validationErr.LongMessage())
}
assert.Equal(c.Provider.Azure.ClientSecretValue, tc.wantClientSecretValue)
})
}
}
func TestValidate(t *testing.T) { func TestValidate(t *testing.T) {
const defaultErrCount = 33 // expect this number of error messages by default because user-specific values are not set and multiple providers are defined by default const defaultErrCount = 33 // expect this number of error messages by default because user-specific values are not set and multiple providers are defined by default
const azErrCount = 7 const azErrCount = 7
@ -384,8 +338,6 @@ func TestValidate(t *testing.T) {
az.Location = "test-location" az.Location = "test-location"
az.UserAssignedIdentity = "test-identity" az.UserAssignedIdentity = "test-identity"
az.ResourceGroup = "test-resource-group" az.ResourceGroup = "test-resource-group"
az.AppClientID = "01234567-0123-0123-0123-0123456789ab"
az.ClientSecretValue = "test-client-secret"
cnf.Provider = ProviderConfig{} cnf.Provider = ProviderConfig{}
cnf.Provider.Azure = az cnf.Provider.Azure = az
cnf.Attestation.AzureSEVSNP.Measurements = measurements.M{ cnf.Attestation.AzureSEVSNP.Measurements = measurements.M{
@ -902,6 +854,42 @@ func TestConfigVersionCompatibility(t *testing.T) {
} }
} }
func TestIsAppClientIDError(t *testing.T) {
testCases := map[string]struct {
err error
expected bool
}{
"yaml.Error with appClientID error": {
err: &yaml.TypeError{
Errors: []string{
"invalid value for appClientID",
"another error",
},
},
expected: true,
},
"yaml.Error without appClientID error": {
err: &yaml.TypeError{
Errors: []string{
"invalid value for something else",
"another error",
},
},
expected: false,
},
"other error": {
err: errors.New("appClientID but other error type"),
expected: false,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
assert.Equal(tc.expected, isAppClientIDError(tc.err))
})
}
}
// configMap is used to un-/marshal the config as an unstructured map. // configMap is used to un-/marshal the config as an unstructured map.
type configMap map[string]interface{} type configMap map[string]interface{}
@ -909,6 +897,10 @@ func (c configMap) setAzureSEVSNPVersion(versionType string, value interface{})
c["attestation"].(configMap)["azureSEVSNP"].(configMap)[versionType] = value c["attestation"].(configMap)["azureSEVSNP"].(configMap)[versionType] = value
} }
func (c configMap) setAzureProvider(azureProviderField string, value interface{}) {
c["provider"].(configMap)["azure"].(configMap)[azureProviderField] = value
}
func (c configMap) getAzureSEVSNPVersion(versionType string) interface{} { func (c configMap) getAzureSEVSNPVersion(versionType string) interface{} {
return c["attestation"].(configMap)["azureSEVSNP"].(configMap)[versionType] return c["attestation"].(configMap)["azureSEVSNP"].(configMap)[versionType]
} }

View file

@ -67,8 +67,6 @@ type AzureConfig struct {
Location string `yaml:"location" validate:"required"` Location string `yaml:"location" validate:"required"`
ResourceGroup string `yaml:"resourceGroup" validate:"required"` ResourceGroup string `yaml:"resourceGroup" validate:"required"`
UserAssignedIdentity string `yaml:"userAssignedIdentity" validate:"required"` UserAssignedIdentity string `yaml:"userAssignedIdentity" validate:"required"`
AppClientID string `yaml:"appClientID" validate:"uuid"`
ClientSecretValue string `yaml:"clientSecretValue" validate:"required"`
InstanceType string `yaml:"instanceType" validate:"azure_instance_type"` InstanceType string `yaml:"instanceType" validate:"azure_instance_type"`
StateDiskType string `yaml:"stateDiskType" validate:"oneof=Premium_LRS Premium_ZRS Standard_LRS StandardSSD_LRS StandardSSD_ZRS"` StateDiskType string `yaml:"stateDiskType" validate:"oneof=Premium_LRS Premium_ZRS Standard_LRS StandardSSD_LRS StandardSSD_ZRS"`
DeployCSIDriver *bool `yaml:"deployCSIDriver" validate:"required"` DeployCSIDriver *bool `yaml:"deployCSIDriver" validate:"required"`
@ -227,8 +225,6 @@ func V2ToV3(path string, fileHandler file.Handler) error {
Location: cfgV2.Provider.Azure.Location, Location: cfgV2.Provider.Azure.Location,
ResourceGroup: cfgV2.Provider.Azure.ResourceGroup, ResourceGroup: cfgV2.Provider.Azure.ResourceGroup,
UserAssignedIdentity: cfgV2.Provider.Azure.UserAssignedIdentity, UserAssignedIdentity: cfgV2.Provider.Azure.UserAssignedIdentity,
AppClientID: cfgV2.Provider.Azure.AppClientID,
ClientSecretValue: cfgV2.Provider.Azure.ClientSecretValue,
InstanceType: cfgV2.Provider.Azure.InstanceType, InstanceType: cfgV2.Provider.Azure.InstanceType,
StateDiskType: cfgV2.Provider.Azure.StateDiskType, StateDiskType: cfgV2.Provider.Azure.StateDiskType,
DeployCSIDriver: cfgV2.Provider.Azure.DeployCSIDriver, DeployCSIDriver: cfgV2.Provider.Azure.DeployCSIDriver,

View file

@ -10,8 +10,6 @@ provider:
location: "West Europe" location: "West Europe"
resourceGroup: "resourceGroup" resourceGroup: "resourceGroup"
userAssignedIdentity: /subscriptions/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/resourceGroups/resourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ConstellationUAMI userAssignedIdentity: /subscriptions/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/resourceGroups/resourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ConstellationUAMI
appClientID: "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
clientSecretValue: "aaaaaaaaaaaaaaaaaaaa"
stateDiskType: Premium_LRS stateDiskType: Premium_LRS
confidentialVM: true confidentialVM: true
instanceType: Standard_DC4as_v5 instanceType: Standard_DC4as_v5

View file

@ -10,8 +10,6 @@ provider:
location: "West Europe" location: "West Europe"
resourceGroup: "resourceGroup" resourceGroup: "resourceGroup"
userAssignedIdentity: /subscriptions/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/resourceGroups/resourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ConstellationUAMI userAssignedIdentity: /subscriptions/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/resourceGroups/resourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ConstellationUAMI
appClientID: "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
clientSecretValue: "aaaaaaaaaaaaaaaaaaaa"
stateDiskType: Premium_LRS stateDiskType: Premium_LRS
confidentialVM: true confidentialVM: true
instanceType: Standard_DC4as_v5 instanceType: Standard_DC4as_v5