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 }