github.com/openshift/installer@v1.4.17/pkg/tfvars/azure/azure.go (about)

     1  package azure
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"math/rand"
     7  	"time"
     8  
     9  	"github.com/pkg/errors"
    10  
    11  	machineapi "github.com/openshift/api/machine/v1beta1"
    12  	"github.com/openshift/installer/pkg/types"
    13  	"github.com/openshift/installer/pkg/types/azure"
    14  )
    15  
    16  // Auth is the collection of credentials that will be used by terrform.
    17  type Auth struct {
    18  	SubscriptionID            string `json:"azure_subscription_id,omitempty"`
    19  	ClientID                  string `json:"azure_client_id,omitempty"`
    20  	ClientSecret              string `json:"azure_client_secret,omitempty"`
    21  	TenantID                  string `json:"azure_tenant_id,omitempty"`
    22  	ClientCertificatePath     string `json:"azure_certificate_path,omitempty"`
    23  	ClientCertificatePassword string `json:"azure_certificate_password,omitempty"`
    24  	UseMSI                    bool   `json:"azure_use_msi,omitempty"`
    25  }
    26  
    27  // OSImage is the marketplace image to be used for RHCOS.
    28  type OSImage struct {
    29  	Publisher string `json:"azure_marketplace_image_publisher,omitempty"`
    30  	Offer     string `json:"azure_marketplace_image_offer,omitempty"`
    31  	SKU       string `json:"azure_marketplace_image_sku,omitempty"`
    32  	Version   string `json:"azure_marketplace_image_version,omitempty"`
    33  }
    34  
    35  type config struct {
    36  	Auth                                    `json:",inline"`
    37  	Environment                             string            `json:"azure_environment"`
    38  	ARMEndpoint                             string            `json:"azure_arm_endpoint"`
    39  	ExtraTags                               map[string]string `json:"azure_extra_tags,omitempty"`
    40  	MasterInstanceType                      string            `json:"azure_master_vm_type,omitempty"`
    41  	MasterAvailabilityZones                 []string          `json:"azure_master_availability_zones"`
    42  	MasterEncryptionAtHostEnabled           bool              `json:"azure_master_encryption_at_host_enabled"`
    43  	MasterDiskEncryptionSetID               string            `json:"azure_master_disk_encryption_set_id,omitempty"`
    44  	ControlPlaneUltraSSDEnabled             bool              `json:"azure_control_plane_ultra_ssd_enabled"`
    45  	VolumeType                              string            `json:"azure_master_root_volume_type"`
    46  	VolumeSize                              int32             `json:"azure_master_root_volume_size"`
    47  	ImageURL                                string            `json:"azure_image_url,omitempty"`
    48  	ImageRelease                            string            `json:"azure_image_release,omitempty"`
    49  	Region                                  string            `json:"azure_region,omitempty"`
    50  	BaseDomainResourceGroupName             string            `json:"azure_base_domain_resource_group_name,omitempty"`
    51  	ResourceGroupName                       string            `json:"azure_resource_group_name"`
    52  	NetworkResourceGroupName                string            `json:"azure_network_resource_group_name"`
    53  	VirtualNetwork                          string            `json:"azure_virtual_network"`
    54  	ControlPlaneSubnet                      string            `json:"azure_control_plane_subnet"`
    55  	ComputeSubnet                           string            `json:"azure_compute_subnet"`
    56  	PreexistingNetwork                      bool              `json:"azure_preexisting_network"`
    57  	Private                                 bool              `json:"azure_private"`
    58  	OutboundType                            string            `json:"azure_outbound_routing_type"`
    59  	BootstrapIgnitionStub                   string            `json:"azure_bootstrap_ignition_stub"`
    60  	BootstrapIgnitionURLPlaceholder         string            `json:"azure_bootstrap_ignition_url_placeholder"`
    61  	HyperVGeneration                        string            `json:"azure_hypervgeneration_version"`
    62  	VMNetworkingType                        bool              `json:"azure_control_plane_vm_networking_type"`
    63  	RandomStringPrefix                      string            `json:"random_storage_account_suffix"`
    64  	VMArchitecture                          string            `json:"azure_vm_architecture"`
    65  	UseMarketplaceImage                     bool              `json:"azure_use_marketplace_image"`
    66  	MarketplaceImageHasPlan                 bool              `json:"azure_marketplace_image_has_plan"`
    67  	OSImage                                 `json:",inline"`
    68  	SecurityEncryptionType                  string            `json:"azure_master_security_encryption_type,omitempty"`
    69  	SecureVirtualMachineDiskEncryptionSetID string            `json:"azure_master_secure_vm_disk_encryption_set_id,omitempty"`
    70  	SecureBoot                              string            `json:"azure_master_secure_boot,omitempty"`
    71  	VirtualizedTrustedPlatformModule        string            `json:"azure_master_virtualized_trusted_platform_module,omitempty"`
    72  	KeyVaultResourceGroup                   string            `json:"azure_keyvault_resource_group,omitempty"`
    73  	KeyVaultName                            string            `json:"azure_keyvault_name,omitempty"`
    74  	KeyVaultKeyName                         string            `json:"azure_keyvault_key_name,omitempty"`
    75  	UserAssignedIdentity                    string            `json:"azure_user_assigned_identity_key,omitempty"`
    76  	ResourceGroupMetadataTags               map[string]string `json:"azure_resource_group_metadata_tags"`
    77  }
    78  
    79  // TFVarsSources contains the parameters to be converted into Terraform variables
    80  type TFVarsSources struct {
    81  	Auth                            Auth
    82  	CloudName                       azure.CloudEnvironment
    83  	ARMEndpoint                     string
    84  	ResourceGroupName               string
    85  	BaseDomainResourceGroupName     string
    86  	MasterConfigs                   []*machineapi.AzureMachineProviderSpec
    87  	WorkerConfigs                   []*machineapi.AzureMachineProviderSpec
    88  	ImageURL                        string
    89  	ImageRelease                    string
    90  	PreexistingNetwork              bool
    91  	Publish                         types.PublishingStrategy
    92  	OutboundType                    azure.OutboundType
    93  	BootstrapIgnStub                string
    94  	BootstrapIgnitionURLPlaceholder string
    95  	HyperVGeneration                string
    96  	VMArchitecture                  types.Architecture
    97  	InfrastructureName              string
    98  	KeyVault                        azure.KeyVault
    99  	UserAssignedIdentityKey         string
   100  	LBPrivate                       bool
   101  }
   102  
   103  // TFVars generates Azure-specific Terraform variables launching the cluster.
   104  func TFVars(sources TFVarsSources) ([]byte, error) {
   105  	masterConfig := sources.MasterConfigs[0]
   106  	workerConfig := sources.WorkerConfigs[0]
   107  
   108  	region := masterConfig.Location
   109  
   110  	masterAvailabilityZones := make([]string, len(sources.MasterConfigs))
   111  	for i, c := range sources.MasterConfigs {
   112  		masterAvailabilityZones[i] = c.Zone
   113  	}
   114  
   115  	environment, err := environment(sources.CloudName)
   116  	if err != nil {
   117  		return nil, errors.Wrap(err, "could not determine Azure environment to use for Terraform")
   118  	}
   119  
   120  	masterEncryptionAtHostEnabled := masterConfig.SecurityProfile != nil &&
   121  		(*masterConfig.SecurityProfile).EncryptionAtHost != nil &&
   122  		*masterConfig.SecurityProfile.EncryptionAtHost
   123  
   124  	var masterDiskEncryptionSetID string
   125  	if masterConfig.OSDisk.ManagedDisk.DiskEncryptionSet != nil {
   126  		masterDiskEncryptionSetID = masterConfig.OSDisk.ManagedDisk.DiskEncryptionSet.ID
   127  	}
   128  
   129  	var secureBoot string
   130  	var virtualizedTrustedPlatformModule string
   131  	if masterConfig.SecurityProfile != nil && masterConfig.SecurityProfile.Settings.SecurityType != "" {
   132  		switch masterConfig.SecurityProfile.Settings.SecurityType {
   133  		case machineapi.SecurityTypesConfidentialVM:
   134  			secureBoot = string(masterConfig.SecurityProfile.Settings.ConfidentialVM.UEFISettings.SecureBoot)
   135  			virtualizedTrustedPlatformModule = string(masterConfig.SecurityProfile.Settings.ConfidentialVM.UEFISettings.VirtualizedTrustedPlatformModule)
   136  		case machineapi.SecurityTypesTrustedLaunch:
   137  			secureBoot = string(masterConfig.SecurityProfile.Settings.TrustedLaunch.UEFISettings.SecureBoot)
   138  			virtualizedTrustedPlatformModule = string(masterConfig.SecurityProfile.Settings.TrustedLaunch.UEFISettings.VirtualizedTrustedPlatformModule)
   139  		}
   140  	}
   141  
   142  	vmarch := "x64"
   143  	if sources.VMArchitecture == types.ArchitectureARM64 {
   144  		vmarch = "Arm64"
   145  	}
   146  
   147  	tags := make(map[string]string, len(masterConfig.Tags)+1)
   148  	// add OCP default tag
   149  	tags[fmt.Sprintf("kubernetes.io_cluster.%s", sources.InfrastructureName)] = "owned"
   150  	for k, v := range masterConfig.Tags {
   151  		tags[k] = v
   152  	}
   153  
   154  	osImage := OSImage{
   155  		Publisher: masterConfig.Image.Publisher,
   156  		Offer:     masterConfig.Image.Offer,
   157  		SKU:       masterConfig.Image.SKU,
   158  		Version:   masterConfig.Image.Version,
   159  	}
   160  
   161  	// Metadata tags to be added to the resource group for the cluster destroy
   162  	metadataTags := map[string]string{}
   163  	metadataTags[azure.TagMetadataRegion] = region
   164  	if len(sources.BaseDomainResourceGroupName) > 0 {
   165  		metadataTags[azure.TagMetadataBaseDomainRG] = sources.BaseDomainResourceGroupName
   166  	}
   167  	if len(masterConfig.NetworkResourceGroup) > 0 {
   168  		metadataTags[azure.TagMetadataNetworkRG] = masterConfig.NetworkResourceGroup
   169  	}
   170  
   171  	cfg := &config{
   172  		Auth:                                    sources.Auth,
   173  		Environment:                             environment,
   174  		ARMEndpoint:                             sources.ARMEndpoint,
   175  		Region:                                  region,
   176  		MasterInstanceType:                      masterConfig.VMSize,
   177  		MasterAvailabilityZones:                 masterAvailabilityZones,
   178  		MasterEncryptionAtHostEnabled:           masterEncryptionAtHostEnabled,
   179  		MasterDiskEncryptionSetID:               masterDiskEncryptionSetID,
   180  		ControlPlaneUltraSSDEnabled:             masterConfig.UltraSSDCapability == machineapi.AzureUltraSSDCapabilityEnabled,
   181  		VolumeType:                              masterConfig.OSDisk.ManagedDisk.StorageAccountType,
   182  		VolumeSize:                              masterConfig.OSDisk.DiskSizeGB,
   183  		ImageURL:                                sources.ImageURL,
   184  		ImageRelease:                            sources.ImageRelease,
   185  		Private:                                 sources.Publish == types.InternalPublishingStrategy || sources.LBPrivate,
   186  		OutboundType:                            string(sources.OutboundType),
   187  		ResourceGroupName:                       sources.ResourceGroupName,
   188  		BaseDomainResourceGroupName:             sources.BaseDomainResourceGroupName,
   189  		NetworkResourceGroupName:                masterConfig.NetworkResourceGroup,
   190  		VirtualNetwork:                          masterConfig.Vnet,
   191  		ControlPlaneSubnet:                      masterConfig.Subnet,
   192  		ComputeSubnet:                           workerConfig.Subnet,
   193  		PreexistingNetwork:                      sources.PreexistingNetwork,
   194  		BootstrapIgnitionStub:                   sources.BootstrapIgnStub,
   195  		BootstrapIgnitionURLPlaceholder:         sources.BootstrapIgnitionURLPlaceholder,
   196  		HyperVGeneration:                        sources.HyperVGeneration,
   197  		VMNetworkingType:                        masterConfig.AcceleratedNetworking,
   198  		RandomStringPrefix:                      randomStringPrefixFunction(),
   199  		VMArchitecture:                          vmarch,
   200  		ExtraTags:                               tags,
   201  		UseMarketplaceImage:                     osImage.Publisher != "",
   202  		MarketplaceImageHasPlan:                 masterConfig.Image.Type != machineapi.AzureImageTypeMarketplaceNoPlan,
   203  		OSImage:                                 osImage,
   204  		SecurityEncryptionType:                  string(masterConfig.OSDisk.ManagedDisk.SecurityProfile.SecurityEncryptionType),
   205  		SecureVirtualMachineDiskEncryptionSetID: masterConfig.OSDisk.ManagedDisk.SecurityProfile.DiskEncryptionSet.ID,
   206  		SecureBoot:                              secureBoot,
   207  		VirtualizedTrustedPlatformModule:        virtualizedTrustedPlatformModule,
   208  		KeyVaultResourceGroup:                   sources.KeyVault.ResourceGroup,
   209  		KeyVaultName:                            sources.KeyVault.Name,
   210  		KeyVaultKeyName:                         sources.KeyVault.KeyName,
   211  		UserAssignedIdentity:                    sources.UserAssignedIdentityKey,
   212  		ResourceGroupMetadataTags:               metadataTags,
   213  	}
   214  
   215  	return json.MarshalIndent(cfg, "", "  ")
   216  }
   217  
   218  // environment returns the Azure environment to pass to Terraform
   219  func environment(cloudName azure.CloudEnvironment) (string, error) {
   220  	switch cloudName {
   221  	case azure.PublicCloud:
   222  		return "public", nil
   223  	case azure.USGovernmentCloud:
   224  		return "usgovernment", nil
   225  	case azure.ChinaCloud:
   226  		return "china", nil
   227  	case azure.GermanCloud:
   228  		return "german", nil
   229  	case azure.StackCloud:
   230  		// unused since stack uses its own provider
   231  		return "", nil
   232  	default:
   233  		return "", errors.Errorf("unsupported cloud name %q", cloudName)
   234  	}
   235  }
   236  
   237  func randomStringPrefixFunction() string {
   238  	length := 5
   239  	rand.Seed(time.Now().UnixNano())
   240  	suffix := make([]rune, length)
   241  	for i := 0; i < length; i++ {
   242  		suffix[i] = 97 + rand.Int31n(26)
   243  	}
   244  	return string(suffix)
   245  }