diff --git a/firestartr-bootstrap/README.md b/firestartr-bootstrap/README.md index 1d6fd77c..d006100e 100644 --- a/firestartr-bootstrap/README.md +++ b/firestartr-bootstrap/README.md @@ -47,6 +47,42 @@ The following AWS Parameter Store parameters are required: - `/firestartr//fs--argocd/app-id` - `/firestartr//fs--argocd//installation-id` +#### 1.3 Azure requirements + +An Azure Key Vault named according to `key_vault_name` in `Credentialsfile.yaml` (e.g. `firestartr-kv`) must exist and be accessible by the service principal provided in the credentials file. + +The following secrets must exist inside the Key Vault (Azure Key Vault names use alphanumeric characters and dashes only — no forward slashes): + +| Key Vault Secret Name | Description | +| :--- | :--- | +| `fs-pem` | Operator GitHub App private key | +| `fs-app-id` | Operator GitHub App ID | +| `fs-client-id` | Operator GitHub App client ID | +| `fs--installation-id` | Operator GitHub App installation ID for `` | +| `fs-admin-pem` | Admin GitHub App private key | +| `fs-admin-app-id` | Admin GitHub App ID | +| `fs-admin-client-id` | Admin GitHub App client ID | +| `fs-admin--installation-id` | Admin GitHub App installation ID for `` | +| `fs-checks-pem` | Checks GitHub App private key | +| `fs-checks-app-id` | Checks GitHub App ID | +| `fs-checks-client-id` | Checks GitHub App client ID | +| `fs-checks--installation-id` | Checks GitHub App installation ID for `` | +| `fs-state-pem` | State GitHub App private key | +| `fs-state-app-id` | State GitHub App ID | +| `fs-state-client-id` | State GitHub App client ID | +| `fs-state--installation-id` | State GitHub App installation ID for `` | +| `fs-import-pem` | Import GitHub App private key | +| `fs-import-app-id` | Import GitHub App ID | +| `fs-import-client-id` | Import GitHub App client ID | +| `fs-import--installation-id` | Import GitHub App installation ID for `` | +| `fs-argocd-pem` | ArgoCD GitHub App private key | +| `fs-argocd-app-id` | ArgoCD GitHub App ID | +| `fs-argocd-client-id` | ArgoCD GitHub App client ID | +| `fs-argocd--installation-id` | ArgoCD GitHub App installation ID for `` | +| `prefapp-bot-pat` | Prefapp Bot Personal Access Token | + +The service principal must have the **Key Vault Secrets Officer** (or **Key Vault Administrator**) role on the vault, and **Storage Blob Data Contributor** on the Blob Storage container used for Terraform state. + ### 2. Bootstrap File ```yaml @@ -86,9 +122,6 @@ pushFiles: secrets: push: true # When the process finishes, the generated crs will be pushed to the crs repository. repo: "state-secrets" # Normally, the state-secrets repository will be called "state-secrets", but it is possible to change the name. - dotFirestartr: - push: true # When the process finishes, the generated crs will be pushed to the crs repository. - repo: ".firestartr" # Normally, the .firestartr repository will be called ".firestartr", but it is possible to change the name. components: - name: "dot-firestartr" # claim name @@ -210,28 +243,43 @@ The rest of the parameters of the `cloudProvider` section are the AWS S3 bucket - `github.prefappBotPat`: Personal Access Token for the Prefapp Bot user, used to download the features from the features repository. - `github.operatorPat`: Personal Access Token for the Operator user, used to commit the deployment and ArgoCD application PRs to the `firestartr-` organization. -#### 3.2 Azure terraform backend provider configuration (currently not supported) +#### 3.2 Azure terraform backend provider configuration ```yaml # Credentialsfile.yaml --- cloudProvider: - providerConfigName: backend-provider-config-name - name: azurerm + name: azure config: - use_azuread_auth: true - tenant_id: "00000000-0000-0000-0000-000000000000" - client_id: "00000000-0000-0000-0000-000000000000" - client_secret: "************************************" - storage_account_name: "abcd1234" + tenant_id: "" + subscription_id: "" + client_id: "" + client_secret: "" + storage_account_name: "tfstate" container_name: "tfstate" - source: hashicorp/aws - type: aws - version: ~> 4.0 + resource_group_name: "rg-firestartr-" + key_vault_name: "firestartr-kv" + source: hashicorp/azurerm + type: azurerm + version: "~> 3.0" github: - providerConfigName: github-app-provider-config-name + prefappBotPat: "" + operatorPat: "" ``` +All `` must be replaced with actual values. + +- `cloudProvider.config.tenant_id`: Azure Active Directory tenant ID. +- `cloudProvider.config.subscription_id`: Azure subscription ID. +- `cloudProvider.config.client_id`: Service principal application (client) ID. +- `cloudProvider.config.client_secret`: Service principal client secret. +- `cloudProvider.config.storage_account_name`: Azure Storage Account name used as the Terraform state backend. +- `cloudProvider.config.container_name`: Blob container within the storage account (usually `tfstate`). +- `cloudProvider.config.resource_group_name`: Resource group containing the storage account and Key Vault. +- `cloudProvider.config.key_vault_name`: Name of the Azure Key Vault that holds the GitHub App secrets (see section 1.3 for required secrets). + +The pre-flight validation step (`cmd-validate-bootstrap`) will verify that the service principal can authenticate, that the storage container is accessible, and that the Key Vault exists. + ### 4. How to launch the bootstrap ``: Replace with the port that kind is using to expose the Kubernetes API server (noted in step 1.1). diff --git a/firestartr-bootstrap/azure.go b/firestartr-bootstrap/azure.go new file mode 100644 index 00000000..5e1cff40 --- /dev/null +++ b/firestartr-bootstrap/azure.go @@ -0,0 +1,116 @@ +package main + +import ( + "context" + "fmt" + "log" + "strings" +) + +// ValidateAzureCredentials verifies that the Azure Service Principal credentials are valid +// by attempting a login with the az CLI inside a Dagger container. +func (m *FirestartrBootstrap) ValidateAzureCredentials( + ctx context.Context, +) error { + log.Println("Attempting to validate Azure credentials via service principal login...") + + cfg := m.Creds.CloudProvider.Config + + clientSecretArg := cfg.ClientSecret + + output, err := dag.Container(). + From("mcr.microsoft.com/azure-cli"). + WithExec([]string{ + "az", "login", + "--service-principal", + "-u", cfg.ClientId, + "-p", clientSecretArg, + "--tenant", cfg.TenantId, + }). + Stdout(ctx) + + if err != nil { + return fmt.Errorf("Azure credential validation failed: az login rejected the service principal credentials: %w", err) + } + + log.Printf("Azure credentials validated successfully. Output: %s", strings.TrimSpace(output)) + return nil +} + +// ValidateAzureStorageAccount verifies that the Azure Blob Storage container used for +// Terraform state exists and is accessible. +func (m *FirestartrBootstrap) ValidateAzureStorageAccount( + ctx context.Context, +) error { + cfg := m.Creds.CloudProvider.Config + + log.Printf( + "Validating Azure Storage Account '%s' (container '%s') in resource group '%s'...", + cfg.StorageAccountName, cfg.ContainerName, cfg.ResourceGroupName, + ) + + _, err := dag.Container(). + From("mcr.microsoft.com/azure-cli"). + WithExec([]string{ + "az", "login", + "--service-principal", + "-u", cfg.ClientId, + "-p", cfg.ClientSecret, + "--tenant", cfg.TenantId, + }). + WithExec([]string{ + "az", "storage", "container", "show", + "--account-name", cfg.StorageAccountName, + "--name", cfg.ContainerName, + "--auth-mode", "login", + }). + Stdout(ctx) + + if err != nil { + return fmt.Errorf( + "Azure Storage Account validation failed: container '%s' in account '%s' is not accessible: %w", + cfg.ContainerName, cfg.StorageAccountName, err, + ) + } + + log.Printf( + "Azure Storage Account '%s' (container '%s') validated successfully.", + cfg.StorageAccountName, cfg.ContainerName, + ) + return nil +} + +// ValidateAzureKeyVault verifies that the Azure Key Vault exists and is accessible +// with the provided service principal credentials. +func (m *FirestartrBootstrap) ValidateAzureKeyVault( + ctx context.Context, +) error { + cfg := m.Creds.CloudProvider.Config + + log.Printf("Validating Azure Key Vault '%s'...", cfg.KeyVaultName) + + _, err := dag.Container(). + From("mcr.microsoft.com/azure-cli"). + WithExec([]string{ + "az", "login", + "--service-principal", + "-u", cfg.ClientId, + "-p", cfg.ClientSecret, + "--tenant", cfg.TenantId, + }). + WithExec([]string{ + "az", "keyvault", "show", + "--name", cfg.KeyVaultName, + }). + Stdout(ctx) + + if err != nil { + return fmt.Errorf( + "Azure Key Vault validation failed: vault '%s' is not accessible: %w", + cfg.KeyVaultName, err, + ) + } + + log.Printf("Azure Key Vault '%s' validated successfully.", cfg.KeyVaultName) + return nil +} diff --git a/firestartr-bootstrap/external_secrets/azure_bootstrap_secrets.tmpl b/firestartr-bootstrap/external_secrets/azure_bootstrap_secrets.tmpl new file mode 100644 index 00000000..7e009b00 --- /dev/null +++ b/firestartr-bootstrap/external_secrets/azure_bootstrap_secrets.tmpl @@ -0,0 +1,38 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: bootstrap-secrets +spec: + data: + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: "fs-admin-pem" + metadataPolicy: None + secretKey: fs-admin-pem + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: "fs-admin-app-id" + metadataPolicy: None + secretKey: fs-admin-appid + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: "fs-admin-{{ $.GhOrgLowerCase }}-installation-id" + metadataPolicy: None + secretKey: fs-admin-installationid + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: "prefapp-bot-pat" + metadataPolicy: None + secretKey: prefapp-bot-pat + refreshInterval: 24h0m0s + secretStoreRef: + kind: SecretStore + name: azure + target: + creationPolicy: Owner + deletionPolicy: Delete + name: bootstrap-secrets diff --git a/firestartr-bootstrap/external_secrets/azure_operator_secrets.tmpl b/firestartr-bootstrap/external_secrets/azure_operator_secrets.tmpl new file mode 100644 index 00000000..5135aef4 --- /dev/null +++ b/firestartr-bootstrap/external_secrets/azure_operator_secrets.tmpl @@ -0,0 +1,38 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: operator-secrets +spec: + data: + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: "fs-pem" + metadataPolicy: None + secretKey: fs-pem + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: "fs-app-id" + metadataPolicy: None + secretKey: fs-appid + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: "fs-{{ $.GhOrgLowerCase }}-installation-id" + metadataPolicy: None + secretKey: fs-installationid + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: "prefapp-bot-pat" + metadataPolicy: None + secretKey: prefapp-bot-pat + refreshInterval: 24h0m0s + secretStoreRef: + kind: SecretStore + name: azure + target: + creationPolicy: Owner + deletionPolicy: Delete + name: operator-secrets diff --git a/firestartr-bootstrap/external_secrets/azure_secretstore.tmpl b/firestartr-bootstrap/external_secrets/azure_secretstore.tmpl new file mode 100644 index 00000000..9b165ad9 --- /dev/null +++ b/firestartr-bootstrap/external_secrets/azure_secretstore.tmpl @@ -0,0 +1,16 @@ +apiVersion: external-secrets.io/v1 +kind: SecretStore +metadata: + name: azure +spec: + provider: + azurekv: + tenantId: "{{ .CloudProvider.Config.TenantId }}" + vaultUrl: "https://{{ .CloudProvider.Config.KeyVaultName }}.vault.azure.net" + authSecretRef: + clientId: + name: azure-creds + key: clientId + clientSecret: + name: azure-creds + key: clientSecret diff --git a/firestartr-bootstrap/kubernetes.go b/firestartr-bootstrap/kubernetes.go index a72b2ae0..02e3052d 100644 --- a/firestartr-bootstrap/kubernetes.go +++ b/firestartr-bootstrap/kubernetes.go @@ -27,23 +27,45 @@ var OPERATOR_CREDS_SECRET_LIST = map[string]string{ "Pem": "ref:secretsclaim:operator-secrets:fs-pem", } +// isAzureProvider returns true when the cloud provider is Azure (azure or azurerm). +func isAzureProvider(providerName string) bool { + return providerName == "azure" || providerName == "azurerm" +} + func (m *FirestartrBootstrap) CreateKubernetesSecrets( ctx context.Context, kindContainer *dagger.Container, ) (*dagger.Container, error) { + // Select the credentials secret template based on the cloud provider. + secretTemplatePath := "templates/secret.tmpl" + if isAzureProvider(m.Creds.CloudProvider.Name) { + secretTemplatePath = "templates/azure_secret.tmpl" + } + secretsTmpl, err := dag.CurrentModule(). Source(). - File("templates/secret.tmpl"). + File(secretTemplatePath). Contents(ctx) + if err != nil { + return nil, err + } secretsCr, err := renderTmpl(secretsTmpl, m.Creds) if err != nil { return nil, err } + // Select ExternalSecret templates based on the cloud provider. + bootstrapSecretsTmplPath := "external_secrets/bootstrap_secrets.tmpl" + operatorSecretsTmplPath := "external_secrets/operator_secrets.tmpl" + if isAzureProvider(m.Creds.CloudProvider.Name) { + bootstrapSecretsTmplPath = "external_secrets/azure_bootstrap_secrets.tmpl" + operatorSecretsTmplPath = "external_secrets/azure_operator_secrets.tmpl" + } + bootstrapSecretsTmpl, err := dag.CurrentModule(). Source(). - File("external_secrets/bootstrap_secrets.tmpl"). + File(bootstrapSecretsTmplPath). Contents(ctx) if err != nil { return nil, err @@ -56,7 +78,7 @@ func (m *FirestartrBootstrap) CreateKubernetesSecrets( operatorSecretsTmpl, err := dag.CurrentModule(). Source(). - File("external_secrets/operator_secrets.tmpl"). + File(operatorSecretsTmplPath). Contents(ctx) if err != nil { return nil, err @@ -67,9 +89,31 @@ func (m *FirestartrBootstrap) CreateKubernetesSecrets( return nil, err } - awsSecretStoreFile := dag.CurrentModule(). - Source(). - File("external_secrets/aws_secretstore.yaml") + // Render and mount the SecretStore manifest based on the cloud provider. + const secretStorePath = "/secret_store/secretstore.yaml" + var secretStoreCr string + if isAzureProvider(m.Creds.CloudProvider.Name) { + azureSecretStoreTmpl, err := dag.CurrentModule(). + Source(). + File("external_secrets/azure_secretstore.tmpl"). + Contents(ctx) + if err != nil { + return nil, err + } + secretStoreCr, err = renderTmpl(azureSecretStoreTmpl, m.Creds) + if err != nil { + return nil, err + } + } else { + awsSecretStoreContent, err := dag.CurrentModule(). + Source(). + File("external_secrets/aws_secretstore.yaml"). + Contents(ctx) + if err != nil { + return nil, err + } + secretStoreCr = awsSecretStoreContent + } firestartrPodName, err := kindContainer. WithExec([]string{ @@ -105,9 +149,9 @@ func (m *FirestartrBootstrap) CreateKubernetesSecrets( "--timeout=10h", "-n", "external-secrets", }). - WithFile("/secret_store/aws_secretstore.yaml", awsSecretStoreFile). + WithNewFile(secretStorePath, secretStoreCr). WithExec([]string{ - "kubectl", "apply", "-f", "/secret_store/aws_secretstore.yaml", + "kubectl", "apply", "-f", secretStorePath, }). WithExec([]string{ "kubectl", "apply", "-f", BOOTSTRAP_SECRETS_FILE_PATH, diff --git a/firestartr-bootstrap/main.go b/firestartr-bootstrap/main.go index 08c26011..3923c69f 100644 --- a/firestartr-bootstrap/main.go +++ b/firestartr-bootstrap/main.go @@ -99,17 +99,26 @@ func New( } else { bootstrap.WebhookUrl = fmt.Sprintf("https://%s.events.%s.firestartr.dev", bootstrap.Customer, bootstrap.Env) } - bootstrap.WebhookSecretRef = fmt.Sprintf("/firestartr/%s/github-webhook/secret", bootstrap.Customer) - // We need to calculate the bucket (if necessary) - if creds.CloudProvider.Config.Bucket == nil { - calculatedBucket := fmt.Sprintf("tfstate-%s", bootstrap.Customer) - creds.CloudProvider.Config.Bucket = &calculatedBucket + // Secret references differ between providers: Azure Key Vault names must be + // alphanumeric + dashes only (no forward slashes), while AWS uses hierarchical + // Parameter Store paths. + if isAzureProvider(creds.CloudProvider.Name) { + bootstrap.WebhookSecretRef = "github-webhook-secret" + bootstrap.PrefappBotPatSecretRef = "prefapp-bot-pat" + bootstrap.FirestartrCliVersionSecretRef = "firestartr-cli-version" + } else { + bootstrap.WebhookSecretRef = fmt.Sprintf("/firestartr/%s/github-webhook/secret", bootstrap.Customer) + bootstrap.PrefappBotPatSecretRef = fmt.Sprintf("/firestartr/%s/prefapp-bot-pat", bootstrap.Customer) + bootstrap.FirestartrCliVersionSecretRef = fmt.Sprintf("/firestartr/%s/firestartr-cli-version", bootstrap.Customer) + + // We need to calculate the bucket (if necessary) + if creds.CloudProvider.Config.Bucket == nil { + calculatedBucket := fmt.Sprintf("tfstate-%s", bootstrap.Customer) + creds.CloudProvider.Config.Bucket = &calculatedBucket + } } - bootstrap.PrefappBotPatSecretRef = fmt.Sprintf("/firestartr/%s/prefapp-bot-pat", bootstrap.Customer) - bootstrap.FirestartrCliVersionSecretRef = fmt.Sprintf("/firestartr/%s/firestartr-cli-version", bootstrap.Customer) - claimsDotConfigDir, err := getClaimsDotConfigDir(ctx, bootstrap) if err != nil { return nil, err @@ -221,19 +230,36 @@ func (m *FirestartrBootstrap) ValidateBootstrap( errorMsgs = append(errorMsgs, err.Error()) } - _, err = m.ValidateSTSCredentials(ctx) - if err != nil { - errorMsgs = append(errorMsgs, err.Error()) - } + if isAzureProvider(m.Creds.CloudProvider.Name) { + err = m.ValidateAzureCredentials(ctx) + if err != nil { + errorMsgs = append(errorMsgs, err.Error()) + } - err = m.ValidateBucket(ctx) - if err != nil { - errorMsgs = append(errorMsgs, err.Error()) - } + err = m.ValidateAzureStorageAccount(ctx) + if err != nil { + errorMsgs = append(errorMsgs, err.Error()) + } - err = m.ValidateParameters(ctx, fmt.Sprintf("/firestartr/%s", m.Bootstrap.Customer)) - if err != nil { - errorMsgs = append(errorMsgs, err.Error()) + err = m.ValidateAzureKeyVault(ctx) + if err != nil { + errorMsgs = append(errorMsgs, err.Error()) + } + } else { + _, err = m.ValidateSTSCredentials(ctx) + if err != nil { + errorMsgs = append(errorMsgs, err.Error()) + } + + err = m.ValidateBucket(ctx) + if err != nil { + errorMsgs = append(errorMsgs, err.Error()) + } + + err = m.ValidateParameters(ctx, fmt.Sprintf("/firestartr/%s", m.Bootstrap.Customer)) + if err != nil { + errorMsgs = append(errorMsgs, err.Error()) + } } err = m.ValidatePrefappBotPat(ctx) diff --git a/firestartr-bootstrap/push_secrets.go b/firestartr-bootstrap/push_secrets.go index 45680c0e..bde23d13 100644 --- a/firestartr-bootstrap/push_secrets.go +++ b/firestartr-bootstrap/push_secrets.go @@ -9,13 +9,18 @@ func (m *FirestartrBootstrap) GeneratePushSecrets( ctx context.Context, ) (*dagger.Directory, error) { + secretStore := "aws" + if isAzureProvider(m.Creds.CloudProvider.Name) { + secretStore = "azure" + } + webHookPushSecret := PushSecretElement{ Name: "webhook-pushsecret", KubernetesSecret: "webhook-secret", KubernetesSecretKey: "webhook-secret-key", ParameterName: m.Bootstrap.WebhookSecretRef, Value: "my-secret-secret", - SecretStore: "aws", + SecretStore: secretStore, } prefappBotPatSecret := PushSecretElement{ @@ -24,7 +29,7 @@ func (m *FirestartrBootstrap) GeneratePushSecrets( KubernetesSecretKey: "botpat-secret-key", ParameterName: m.Bootstrap.PrefappBotPatSecretRef, Value: m.Creds.GithubApp.PrefappBotPat, - SecretStore: "aws", + SecretStore: secretStore, } prefappCliVersion := PushSecretElement{ @@ -33,7 +38,7 @@ func (m *FirestartrBootstrap) GeneratePushSecrets( KubernetesSecretKey: "cli-version-key", ParameterName: m.Bootstrap.FirestartrCliVersionSecretRef, Value: m.Bootstrap.Firestartr.CliVersion, - SecretStore: "aws", + SecretStore: secretStore, } rendered, err := renderPushSecret(ctx, &webHookPushSecret, "external_secrets/push_secret.tmpl") diff --git a/firestartr-bootstrap/schemas/credentials-file.json b/firestartr-bootstrap/schemas/credentials-file.json index 8eabe4e9..36bd7e35 100644 --- a/firestartr-bootstrap/schemas/credentials-file.json +++ b/firestartr-bootstrap/schemas/credentials-file.json @@ -6,6 +6,69 @@ "type": "string", "pattern": "^\\d+$", "description": "A string containing only one or more digits." + }, + "awsConfig": { + "type": "object", + "properties": { + "bucket": { + "type": "string" + }, + "region": { + "type": "string" + }, + "access_key": { + "type": "string" + }, + "secret_key": { + "type": "string" + }, + "token": { + "type": "string" + } + }, + "required": [ + "region", + "access_key", + "secret_key" + ] + }, + "azureConfig": { + "type": "object", + "properties": { + "tenant_id": { + "type": "string" + }, + "subscription_id": { + "type": "string" + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "storage_account_name": { + "type": "string" + }, + "container_name": { + "type": "string" + }, + "resource_group_name": { + "type": "string" + }, + "key_vault_name": { + "type": "string" + } + }, + "required": [ + "tenant_id", + "client_id", + "client_secret", + "storage_account_name", + "container_name", + "resource_group_name", + "key_vault_name" + ] } }, "type": "object", @@ -14,32 +77,14 @@ "type": "object", "properties": { "name": { - "type": "string" + "type": "string", + "enum": ["aws", "azure", "azurerm"] }, "providerConfigName": { "type": "string" }, "config": { - "type": "object", - "properties": { - "bucket": { - "type": "string" - }, - "region": { - "type": "string" - }, - "access_key": { - "type": "string" - }, - "secret_key": { - "type": "string" - } - }, - "required": [ - "region", - "access_key", - "secret_key" - ] + "type": "object" }, "source": { "type": "string" @@ -51,6 +96,21 @@ "type": "string" } }, + "if": { + "properties": { + "name": { "enum": ["azure", "azurerm"] } + } + }, + "then": { + "properties": { + "config": { "$ref": "#/$defs/azureConfig" } + } + }, + "else": { + "properties": { + "config": { "$ref": "#/$defs/awsConfig" } + } + }, "required": [ "name", "config", diff --git a/firestartr-bootstrap/templates/azure_secret.tmpl b/firestartr-bootstrap/templates/azure_secret.tmpl new file mode 100644 index 00000000..cb0cfca8 --- /dev/null +++ b/firestartr-bootstrap/templates/azure_secret.tmpl @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: azure-creds +stringData: + clientId: {{ .CloudProvider.Config.ClientId }} + clientSecret: {{ .CloudProvider.Config.ClientSecret }} + tenantId: {{ .CloudProvider.Config.TenantId }} diff --git a/firestartr-bootstrap/types.go b/firestartr-bootstrap/types.go index 3f15e0b7..75d30d79 100644 --- a/firestartr-bootstrap/types.go +++ b/firestartr-bootstrap/types.go @@ -87,11 +87,22 @@ type CloudProvider struct { } type ConfigProvider struct { + // AWS fields Bucket *string `json:"bucket" yaml:"bucket"` Region string `json:"region" yaml:"region"` AccessKey string `json:"access_key" yaml:"access_key"` SecretKey string `json:"secret_key" yaml:"secret_key"` Token string `json:"token" yaml:"token"` + + // Azure fields + TenantId string `json:"tenant_id" yaml:"tenant_id"` + SubscriptionId string `json:"subscription_id" yaml:"subscription_id"` + ClientId string `json:"client_id" yaml:"client_id"` + ClientSecret string `json:"client_secret" yaml:"client_secret"` + StorageAccountName string `json:"storage_account_name" yaml:"storage_account_name"` + ContainerName string `json:"container_name" yaml:"container_name"` + ResourceGroupName string `json:"resource_group_name" yaml:"resource_group_name"` + KeyVaultName string `json:"key_vault_name" yaml:"key_vault_name"` } type GithubApp struct {