Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions api/v1alpha1/terraform/terraform_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type BackendConfig struct {
S3 *S3Backend `yaml:"s3,omitempty"`
Kubernetes *KubernetesBackend `yaml:"kubernetes,omitempty"`
Local *LocalBackend `yaml:"local,omitempty"`
AzureRM *AzureRMBackend `yaml:"azurerm,omitempty"`
Prefix *string `yaml:"prefix,omitempty"`
}

Expand Down Expand Up @@ -90,6 +91,40 @@ type ExecConfig struct {
Env *map[string]string `yaml:"env,omitempty"`
}

// AzureRMBackend represents the configuration for the AzureRM backend
type AzureRMBackend struct {
StorageAccountName *string `yaml:"storage_account_name,omitempty"`
ContainerName *string `yaml:"container_name,omitempty"`
Key *string `yaml:"key,omitempty"`
Environment *string `yaml:"environment,omitempty"`
MetadataHost *string `yaml:"metadata_host,omitempty"`
UseAzureAD *bool `yaml:"use_azuread,omitempty"`
UseOIDC *bool `yaml:"use_oidc,omitempty"`
UseCLI *bool `yaml:"use_cli,omitempty"`
UseMSI *bool `yaml:"use_msi,omitempty"`
UseAksWorkloadIdentity *bool `yaml:"use_aks_workload_identity,omitempty"`
TenantID *string `yaml:"tenant_id,omitempty"`
SubscriptionID *string `yaml:"subscription_id,omitempty"`
ClientID *string `yaml:"client_id,omitempty"`
ClientSecret *string `yaml:"client_secret,omitempty"`
ClientCertificate *string `yaml:"client_certificate,omitempty"`
ClientCertPassword *string `yaml:"client_certificate_password,omitempty"`
ClientCertPath *string `yaml:"client_certificate_path,omitempty"`
ClientIdFilePath *string `yaml:"client_id_file_path,omitempty"`
ClientSecretFilePath *string `yaml:"client_secret_file_path,omitempty"`
MSIEndpoint *string `yaml:"msi_endpoint,omitempty"`
ResourceGroupName *string `yaml:"resource_group_name,omitempty"`
UseDNSZoneEndpoint *bool `yaml:"use_dns_zone_endpoint,omitempty"`
Snapshot *bool `yaml:"snapshot,omitempty"`
AccessKey *string `yaml:"access_key,omitempty"`
SasToken *string `yaml:"sas_token,omitempty"`
AdoPipelineServiceConnectionId *string `yaml:"ado_pipeline_service_connection_id,omitempty"`
OidcRequestUrl *string `yaml:"oidc_request_url,omitempty"`
OidcRequestToken *string `yaml:"oidc_request_token,omitempty"`
OidcToken *string `yaml:"oidc_token,omitempty"`
OidcTokenFilePath *string `yaml:"oidc_token_file_path,omitempty"`
}

// Merge performs a simple merge of the current TerraformConfig with another TerraformConfig.
func (base *TerraformConfig) Merge(overlay *TerraformConfig) {
if overlay.Enabled != nil {
Expand Down
12 changes: 12 additions & 0 deletions pkg/env/terraform_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ func (e *TerraformEnvPrinter) generateBackendOverrideTf() error {
case "kubernetes":
backendConfig = fmt.Sprintf(`terraform {
backend "kubernetes" {}
}`)
case "azurerm":
backendConfig = fmt.Sprintf(`terraform {
backend "azurerm" {}
}`)
default:
return fmt.Errorf("unsupported backend: %s", backend)
Expand Down Expand Up @@ -255,6 +259,14 @@ func (e *TerraformEnvPrinter) generateBackendConfigArgs(projectPath, configRoot
return nil, fmt.Errorf("error processing Kubernetes backend config: %w", err)
}
}
case "azurerm":
keyPath := fmt.Sprintf("%s%s", prefix, filepath.ToSlash(filepath.Join(projectPath, "terraform.tfstate")))
addBackendConfigArg("key", keyPath)
if backend := e.configHandler.GetConfig().Terraform.Backend.AzureRM; backend != nil {
if err := e.processBackendConfig(backend, addBackendConfigArg); err != nil {
return nil, fmt.Errorf("error processing AzureRM backend config: %w", err)
}
}
default:
return nil, fmt.Errorf("unsupported backend: %s", backend)
}
Expand Down
58 changes: 58 additions & 0 deletions pkg/env/terraform_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,33 @@ func TestTerraformEnv_generateBackendOverrideTf(t *testing.T) {
}
})

t.Run("AzureRMBackend", func(t *testing.T) {
// Given a TerraformEnvPrinter with AzureRM backend configuration
printer, mocks := setup(t)
mocks.ConfigHandler.SetContextValue("terraform.backend.type", "azurerm")

var writtenData []byte
mocks.Shims.WriteFile = func(filename string, data []byte, perm os.FileMode) error {
writtenData = data
return nil
}

// When generateBackendOverrideTf is called
err := printer.generateBackendOverrideTf()

// Then no error should occur and the expected backend config should be written
if err != nil {
t.Errorf("Expected no error, got %v", err)
}

expectedContent := `terraform {
backend "azurerm" {}
}`
if string(writtenData) != expectedContent {
t.Errorf("Expected backend config %q, got %q", expectedContent, string(writtenData))
}
})

t.Run("UnsupportedBackend", func(t *testing.T) {
// Given a TerraformEnvPrinter with unsupported backend configuration
printer, mocks := setup(t)
Expand Down Expand Up @@ -1122,6 +1149,37 @@ func TestTerraformEnv_generateBackendConfigArgs(t *testing.T) {
}
})

t.Run("AzureRMBackendWithPrefix", func(t *testing.T) {
// Given a TerraformEnvPrinter with AzureRM backend and prefix configuration
printer, mocks := setup(t)
mocks.ConfigHandler.SetContextValue("terraform.backend.type", "azurerm")
mocks.ConfigHandler.SetContextValue("terraform.backend.prefix", "mock-prefix/")
mocks.ConfigHandler.SetContextValue("terraform.backend.azurerm.storage_account_name", "mock-storage")
mocks.ConfigHandler.SetContextValue("terraform.backend.azurerm.container_name", "mock-container")
mocks.ConfigHandler.SetContextValue("terraform.backend.azurerm.use_azuread", true)
projectPath := "project/path"
configRoot := "/mock/config/root"

// When generateBackendConfigArgs is called
backendConfigArgs, err := printer.generateBackendConfigArgs(projectPath, configRoot)

// Then no error should occur and the expected arguments should be returned
if err != nil {
t.Errorf("unexpected error: %v", err)
}

expectedArgs := []string{
`-backend-config="key=mock-prefix/project/path/terraform.tfstate"`,
`-backend-config="container_name=mock-container"`,
`-backend-config="storage_account_name=mock-storage"`,
`-backend-config="use_azuread=true"`,
}

if !reflect.DeepEqual(backendConfigArgs, expectedArgs) {
t.Errorf("expected %v, got %v", expectedArgs, backendConfigArgs)
}
})

t.Run("UnsupportedBackendType", func(t *testing.T) {
// Given a TerraformEnvPrinter with unsupported backend configuration
printer, mocks := setup(t)
Expand Down
Loading