Migrate instance types to aws-sdk-go-v2

This commit is contained in:
Peter Rifel 2024-04-09 21:24:58 -05:00
parent f05284a2f9
commit 2bf59688c2
No known key found for this signature in database
9 changed files with 117 additions and 104 deletions

View File

@ -29,6 +29,7 @@ import (
awsconfig "github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/klog/v2"
@ -647,18 +648,18 @@ func (b *KubeletBuilder) buildKubeletConfigSpec(ctx context.Context) (*kops.Kube
}
metadata := imds.NewFromConfig(config)
var instanceTypeName string
var instanceTypeName ec2types.InstanceType
// Get the actual instance type by querying the EC2 instance metadata service.
resp, err := metadata.GetMetadata(ctx, &imds.GetMetadataInput{Path: "instance-type"})
if err == nil {
defer resp.Content.Close()
itName, err := io.ReadAll(resp.Content)
if err == nil {
instanceTypeName = string(itName)
instanceTypeName = ec2types.InstanceType(string(itName))
}
}
if instanceTypeName == "" {
instanceTypeName = *b.NodeupConfig.DefaultMachineType
instanceTypeName = ec2types.InstanceType(*b.NodeupConfig.DefaultMachineType)
}
awsCloud := b.Cloud.(awsup.AWSCloud)
@ -669,7 +670,7 @@ func (b *KubeletBuilder) buildKubeletConfigSpec(ctx context.Context) (*kops.Kube
}
// Default maximum pods per node defined by KubeletConfiguration
maxPods := 110
maxPods := int32(110)
// AWS VPC CNI plugin-specific maximum pod calculation based on:
// https://github.com/aws/amazon-vpc-cni-k8s/blob/v1.9.3/README.md#setup

View File

@ -179,13 +179,13 @@ func (h *IntegrationTestHarness) SetupMockAWS() *awsup.MockAWSCloud {
VPCId: aws.String("vpc-12345678"),
}})
mockEC2.Images = append(mockEC2.Images, &ec2.Image{
mockEC2.Images = append(mockEC2.Images, &ec2types.Image{
CreationDate: aws.String("2022-04-04T00:00:00.000Z"),
ImageId: aws.String("ami-12345678"),
Name: aws.String("images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20220404"),
OwnerId: aws.String(awsup.WellKnownAccountUbuntu),
RootDeviceName: aws.String("/dev/xvda"),
Architecture: aws.String("x86_64"),
Architecture: ec2types.ArchitectureValuesX8664,
})
mockEC2.CreateVpcWithId(&ec2.CreateVpcInput{

View File

@ -189,7 +189,7 @@ type AWSCloud interface {
DefaultInstanceType(cluster *kops.Cluster, ig *kops.InstanceGroup) (string, error)
// DescribeInstanceType calls ec2.DescribeInstanceType to get information for a particular instance type
DescribeInstanceType(instanceType string) (*ec2.InstanceTypeInfo, error)
DescribeInstanceType(instanceType string) (*ec2types.InstanceTypeInfo, error)
// AccountInfo returns the AWS account ID and AWS partition that we are deploying into
AccountInfo(ctx context.Context) (string, string, error)
@ -2274,24 +2274,33 @@ func findDNSName(cloud AWSCloud, cluster *kops.Cluster) (string, error) {
// DefaultInstanceType determines an instance type for the specified cluster & instance group
func (c *awsCloudImplementation) DefaultInstanceType(cluster *kops.Cluster, ig *kops.InstanceGroup) (string, error) {
var candidates []string
var candidates []ec2types.InstanceType
switch ig.Spec.Role {
case kops.InstanceGroupRoleControlPlane, kops.InstanceGroupRoleNode, kops.InstanceGroupRoleAPIServer:
// t3.medium is the cheapest instance with 4GB of mem, unlimited by default, fast and has decent network
// c5.large and c4.large are a good second option in case t3.medium is not available in the AZ
candidates = []string{"t3.medium", "c5.large", "c4.large", "t4g.medium"}
candidates = []ec2types.InstanceType{
ec2types.InstanceTypeT3Medium,
ec2types.InstanceTypeC5Large,
ec2types.InstanceTypeC4Large,
ec2types.InstanceTypeT4gMedium,
}
case kops.InstanceGroupRoleBastion:
candidates = []string{"t3.micro", "t2.micro", "t4g.micro"}
candidates = []ec2types.InstanceType{
ec2types.InstanceTypeT3Micro,
ec2types.InstanceTypeT2Micro,
ec2types.InstanceTypeT4gMicro,
}
default:
return "", fmt.Errorf("unhandled role %q", ig.Spec.Role)
}
imageArch := "x86_64"
imageArch := ec2types.ArchitectureTypeX8664
if imageInfo, err := c.ResolveImage(ig.Spec.Image); err == nil {
imageArch = fi.ValueOf(imageInfo.Architecture)
imageArch = ec2types.ArchitectureType(imageInfo.Architecture)
}
// Find the AZs the InstanceGroup targets
@ -2304,13 +2313,13 @@ func (c *awsCloudImplementation) DefaultInstanceType(cluster *kops.Cluster, ig *
// TODO: Validate that instance type exists in all AZs, but skip AZs that don't support any VPC stuff
var reasons []string
for _, instanceType := range candidates {
if strings.HasPrefix(instanceType, "t4g") {
if imageArch != "arm64" {
if strings.HasPrefix(string(instanceType), "t4g") {
if imageArch != ec2types.ArchitectureTypeArm64 {
reasons = append(reasons, fmt.Sprintf("instance type %q does not match image architecture %q", instanceType, imageArch))
continue
}
} else {
if imageArch == "arm64" {
if imageArch == ec2types.ArchitectureTypeArm64 {
reasons = append(reasons, fmt.Sprintf("instance type %q does not match image architecture %q", instanceType, imageArch))
continue
}
@ -2321,7 +2330,7 @@ func (c *awsCloudImplementation) DefaultInstanceType(cluster *kops.Cluster, ig *
return "", err
}
if zones.IsSuperset(igZonesSet) {
return instanceType, nil
return string(instanceType), nil
} else {
reasons = append(reasons, fmt.Sprintf("instance type %q is not available in all zones (available in zones %v, need %v)", instanceType, zones, igZones))
klog.V(2).Infof("can't use instance type %q, available in zones %v but need %v", instanceType, zones, igZones)
@ -2337,26 +2346,27 @@ func (c *awsCloudImplementation) DefaultInstanceType(cluster *kops.Cluster, ig *
}
// supportsInstanceType uses the DescribeReservedInstancesOfferings API call to determine if an instance type is supported in a region
func (c *awsCloudImplementation) zonesWithInstanceType(instanceType string) (sets.String, error) {
func (c *awsCloudImplementation) zonesWithInstanceType(instanceType ec2types.InstanceType) (sets.String, error) {
klog.V(4).Infof("checking if instance type %q is supported in region %q", instanceType, c.region)
ctx := context.TODO()
request := &ec2.DescribeReservedInstancesOfferingsInput{}
request.InstanceTenancy = aws.String("default")
request.InstanceTenancy = ec2types.TenancyDefault
request.IncludeMarketplace = aws.Bool(false)
request.OfferingClass = aws.String(ec2.OfferingClassTypeStandard)
request.OfferingType = aws.String(ec2.OfferingTypeValuesNoUpfront)
request.ProductDescription = aws.String(ec2.RIProductDescriptionLinuxUnixamazonVpc)
request.InstanceType = aws.String(instanceType)
request.OfferingClass = ec2types.OfferingClassTypeStandard
request.OfferingType = ec2types.OfferingTypeValuesNoUpfront
request.ProductDescription = ec2types.RIProductDescriptionLinuxUnixAmazonVpc
request.InstanceType = instanceType
zones := sets.NewString()
response, err := c.ec2.DescribeReservedInstancesOfferings(request)
response, err := c.ec2.DescribeReservedInstancesOfferings(ctx, request)
if err != nil {
return zones, fmt.Errorf("error checking if instance type %q is supported in region %q: %v", instanceType, c.region, err)
}
for _, item := range response.ReservedInstancesOfferings {
if aws.StringValue(item.InstanceType) == instanceType {
zones.Insert(aws.StringValue(item.AvailabilityZone))
if item.InstanceType == instanceType {
zones.Insert(aws.ToString(item.AvailabilityZone))
} else {
klog.Warningf("skipping non-matching instance type offering: %v", item)
}
@ -2366,7 +2376,7 @@ func (c *awsCloudImplementation) zonesWithInstanceType(instanceType string) (set
}
// DescribeInstanceType calls ec2.DescribeInstanceType to get information for a particular instance type
func (c *awsCloudImplementation) DescribeInstanceType(instanceType string) (*ec2.InstanceTypeInfo, error) {
func (c *awsCloudImplementation) DescribeInstanceType(instanceType string) (*ec2types.InstanceTypeInfo, error) {
if info, ok := c.instanceTypes.typeMap[instanceType]; ok {
return info, nil
}
@ -2381,18 +2391,19 @@ func (c *awsCloudImplementation) DescribeInstanceType(instanceType string) (*ec2
return info, nil
}
func describeInstanceType(c AWSCloud, instanceType string) (*ec2.InstanceTypeInfo, error) {
func describeInstanceType(c AWSCloud, instanceType string) (*ec2types.InstanceTypeInfo, error) {
ctx := context.TODO()
req := &ec2.DescribeInstanceTypesInput{
InstanceTypes: aws.StringSlice([]string{instanceType}),
InstanceTypes: []ec2types.InstanceType{ec2types.InstanceType(instanceType)},
}
resp, err := c.EC2().DescribeInstanceTypes(req)
resp, err := c.EC2().DescribeInstanceTypes(ctx, req)
if err != nil {
return nil, fmt.Errorf("describing instance type %q in region %q: %w", instanceType, c.Region(), err)
}
if len(resp.InstanceTypes) != 1 {
return nil, fmt.Errorf("instance type %q not found in region %q", instanceType, c.Region())
}
return resp.InstanceTypes[0], nil
return &resp.InstanceTypes[0], nil
}
// AccountInfo returns the AWS account ID and AWS partition that we are deploying into

View File

@ -22,28 +22,29 @@ import (
"sync"
"github.com/aws/aws-sdk-go-v2/aws"
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
"k8s.io/klog/v2"
)
type AWSMachineTypeInfo struct {
Name string
Name ec2types.InstanceType
MemoryGB float32
Cores int
EphemeralDisks []int
Cores int32
EphemeralDisks []int64
GPU bool
MaxPods int
InstanceENIs int
InstanceIPsPerENI int
MaxPods int32
InstanceENIs int32
InstanceIPsPerENI int32
}
type EphemeralDevice struct {
DeviceName string
VirtualName string
SizeGB int
SizeGB int64
}
var (
machineTypeInfo map[string]*AWSMachineTypeInfo
machineTypeInfo map[ec2types.InstanceType]*AWSMachineTypeInfo
machineTypeMutex sync.Mutex
)
@ -66,36 +67,36 @@ func (m *AWSMachineTypeInfo) EphemeralDevices() []*EphemeralDevice {
return disks
}
func GetMachineTypeInfo(c AWSCloud, machineType string) (*AWSMachineTypeInfo, error) {
func GetMachineTypeInfo(c AWSCloud, machineType ec2types.InstanceType) (*AWSMachineTypeInfo, error) {
machineTypeMutex.Lock()
defer machineTypeMutex.Unlock()
if machineTypeInfo == nil {
machineTypeInfo = make(map[string]*AWSMachineTypeInfo)
machineTypeInfo = make(map[ec2types.InstanceType]*AWSMachineTypeInfo)
} else if i, ok := machineTypeInfo[machineType]; ok {
return i, nil
}
info, err := c.DescribeInstanceType(machineType)
info, err := c.DescribeInstanceType(string(machineType))
if err != nil {
return nil, err
}
machine := AWSMachineTypeInfo{
Name: machineType,
GPU: info.GpuInfo != nil,
InstanceENIs: intValue(info.NetworkInfo.MaximumNetworkInterfaces),
InstanceIPsPerENI: intValue(info.NetworkInfo.Ipv4AddressesPerInterface),
InstanceENIs: aws.ToInt32(info.NetworkInfo.MaximumNetworkInterfaces),
InstanceIPsPerENI: aws.ToInt32(info.NetworkInfo.Ipv4AddressesPerInterface),
}
memoryGB := float64(intValue(info.MemoryInfo.SizeInMiB)) / 1024
memoryGB := float64(aws.ToInt64(info.MemoryInfo.SizeInMiB)) / 1024
machine.MemoryGB = float32(math.Round(memoryGB*100) / 100)
if info.VCpuInfo != nil && info.VCpuInfo.DefaultVCpus != nil {
machine.Cores = intValue(info.VCpuInfo.DefaultVCpus)
machine.Cores = aws.ToInt32(info.VCpuInfo.DefaultVCpus)
}
if info.InstanceStorageInfo != nil && len(info.InstanceStorageInfo.Disks) > 0 {
disks := make([]int, 0)
disks := make([]int64, 0)
for _, disk := range info.InstanceStorageInfo.Disks {
for i := 0; i < intValue(disk.Count); i++ {
disks = append(disks, intValue(disk.SizeInGB))
for i := int32(0); i < aws.ToInt32(disk.Count); i++ {
disks = append(disks, aws.ToInt64(disk.SizeInGB))
}
}
machine.EphemeralDisks = disks
@ -104,7 +105,3 @@ func GetMachineTypeInfo(c AWSCloud, machineType string) (*AWSMachineTypeInfo, er
return &machine, nil
}
func intValue(v *int64) int {
return int(aws.ToInt64(v))
}

View File

@ -325,27 +325,27 @@ func (c *MockAWSCloud) DefaultInstanceType(cluster *kops.Cluster, ig *kops.Insta
}
// DescribeInstanceType calls ec2.DescribeInstanceType to get information for a particular instance type
func (c *MockAWSCloud) DescribeInstanceType(instanceType string) (*ec2.InstanceTypeInfo, error) {
func (c *MockAWSCloud) DescribeInstanceType(instanceType string) (*ec2types.InstanceTypeInfo, error) {
if instanceType == "t2.invalidType" {
return nil, fmt.Errorf("invalid instance type %q specified", "t2.invalidType")
}
info := &ec2.InstanceTypeInfo{
NetworkInfo: &ec2.NetworkInfo{
MaximumNetworkInterfaces: aws.Int64(1),
Ipv4AddressesPerInterface: aws.Int64(1),
info := &ec2types.InstanceTypeInfo{
NetworkInfo: &ec2types.NetworkInfo{
MaximumNetworkInterfaces: aws.Int32(1),
Ipv4AddressesPerInterface: aws.Int32(1),
},
MemoryInfo: &ec2.MemoryInfo{
MemoryInfo: &ec2types.MemoryInfo{
SizeInMiB: aws.Int64(1024),
},
VCpuInfo: &ec2.VCpuInfo{
DefaultVCpus: aws.Int64(2),
VCpuInfo: &ec2types.VCpuInfo{
DefaultVCpus: aws.Int32(2),
},
}
if instanceType == "m3.medium" {
info.InstanceStorageInfo = &ec2.InstanceStorageInfo{
Disks: []*ec2.DiskInfo{
info.InstanceStorageInfo = &ec2types.InstanceStorageInfo{
Disks: []ec2types.DiskInfo{
{
Count: aws.Int64(1),
Count: aws.Int32(1),
SizeInGB: aws.Int64(1024),
},
},
@ -354,31 +354,31 @@ func (c *MockAWSCloud) DescribeInstanceType(instanceType string) (*ec2.InstanceT
switch instanceType {
case "c5.large", "m3.medium", "m4.large", "m5.large", "m5.xlarge", "t3.micro", "t3.medium", "t3.large", "c4.large":
info.ProcessorInfo = &ec2.ProcessorInfo{
SupportedArchitectures: []*string{
aws.String(ec2.ArchitectureTypeX8664),
info.ProcessorInfo = &ec2types.ProcessorInfo{
SupportedArchitectures: []ec2types.ArchitectureType{
ec2types.ArchitectureTypeX8664,
},
}
case "a1.large", "m6g.xlarge":
info.ProcessorInfo = &ec2.ProcessorInfo{
SupportedArchitectures: []*string{
aws.String(ec2.ArchitectureTypeArm64),
info.ProcessorInfo = &ec2types.ProcessorInfo{
SupportedArchitectures: []ec2types.ArchitectureType{
ec2types.ArchitectureTypeArm64,
},
}
case "t2.micro", "t2.medium":
info.ProcessorInfo = &ec2.ProcessorInfo{
SupportedArchitectures: []*string{
aws.String(ec2.ArchitectureTypeI386),
aws.String(ec2.ArchitectureTypeX8664),
info.ProcessorInfo = &ec2types.ProcessorInfo{
SupportedArchitectures: []ec2types.ArchitectureType{
ec2types.ArchitectureTypeI386,
ec2types.ArchitectureTypeX8664,
},
}
case "g4dn.xlarge", "g4ad.16xlarge":
info.ProcessorInfo = &ec2.ProcessorInfo{
SupportedArchitectures: []*string{
aws.String(ec2.ArchitectureTypeX8664),
info.ProcessorInfo = &ec2types.ProcessorInfo{
SupportedArchitectures: []ec2types.ArchitectureType{
ec2types.ArchitectureTypeX8664,
},
}
info.GpuInfo = &ec2.GpuInfo{}
info.GpuInfo = &ec2types.GpuInfo{}
}
return info, nil

View File

@ -17,12 +17,13 @@ limitations under the License.
package cloudup
import (
"context"
"fmt"
"strconv"
"strings"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go-v2/service/ec2"
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
"github.com/blang/semver/v4"
"k8s.io/apimachinery/pkg/api/resource"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -1669,16 +1670,16 @@ func MachineArchitecture(cloud fi.Cloud, machineType string) (architectures.Arch
if info.ProcessorInfo == nil || len(info.ProcessorInfo.SupportedArchitectures) == 0 {
return "", fmt.Errorf("unable to determine architecture info for instance type %q", machineType)
}
var unsupported []string
var unsupported []ec2types.ArchitectureType
for _, arch := range info.ProcessorInfo.SupportedArchitectures {
// Return the first found supported architecture, in order of popularity
switch fi.ValueOf(arch) {
case ec2.ArchitectureTypeX8664:
switch arch {
case ec2types.ArchitectureTypeX8664:
return architectures.ArchitectureAmd64, nil
case ec2.ArchitectureTypeArm64:
case ec2types.ArchitectureTypeArm64:
return architectures.ArchitectureArm64, nil
default:
unsupported = append(unsupported, fi.ValueOf(arch))
unsupported = append(unsupported, arch)
}
}
return "", fmt.Errorf("unsupported architecture for instance type %q: %v", machineType, unsupported)

View File

@ -20,6 +20,7 @@ import (
"fmt"
"strings"
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/klog/v2"
@ -200,7 +201,7 @@ func PopulateInstanceGroupSpec(cluster *kops.Cluster, input *kops.InstanceGroup,
switch cluster.Spec.GetCloudProvider() {
case kops.CloudProviderAWS:
if clusterNvidia || igNvidia {
mt, err := awsup.GetMachineTypeInfo(cloud.(awsup.AWSCloud), ig.Spec.MachineType)
mt, err := awsup.GetMachineTypeInfo(cloud.(awsup.AWSCloud), ec2types.InstanceType(ig.Spec.MachineType))
if err != nil {
return ig, fmt.Errorf("error looking up machine type info: %v", err)
}

View File

@ -995,6 +995,7 @@ func (tf *TemplateFunctions) podIdentityWebhookConfigMapData() (string, error) {
}
func karpenterInstanceTypes(cloud awsup.AWSCloud, ig kops.InstanceGroupSpec) ([]string, error) {
ctx := context.TODO()
var mixedInstancesPolicy *kops.MixedInstancesPolicySpec
if ig.MachineType == "" && ig.MixedInstancesPolicy == nil {
@ -1033,55 +1034,55 @@ func karpenterInstanceTypes(cloud awsup.AWSCloud, ig kops.InstanceGroupSpec) ([]
arch := ami.Architecture
hv := ami.VirtualizationType
ir := &ec2.InstanceRequirementsRequest{
VCpuCount: &ec2.VCpuCountRangeRequest{},
MemoryMiB: &ec2.MemoryMiBRequest{},
BurstablePerformance: fi.PtrTo("included"),
InstanceGenerations: []*string{fi.PtrTo("current")},
ir := &ec2types.InstanceRequirementsRequest{
VCpuCount: &ec2types.VCpuCountRangeRequest{},
MemoryMiB: &ec2types.MemoryMiBRequest{},
BurstablePerformance: ec2types.BurstablePerformanceIncluded,
InstanceGenerations: []ec2types.InstanceGeneration{ec2types.InstanceGenerationCurrent},
}
cpu := instanceRequirements.CPU
if cpu != nil {
if cpu.Max != nil {
cpuMax, _ := instanceRequirements.CPU.Max.AsInt64()
ir.VCpuCount.Max = &cpuMax
ir.VCpuCount.Max = fi.PtrTo(int32(cpuMax))
}
cpu := instanceRequirements.CPU
if cpu != nil {
if cpu.Max != nil {
cpuMax, _ := instanceRequirements.CPU.Max.AsInt64()
ir.VCpuCount.Max = &cpuMax
ir.VCpuCount.Max = fi.PtrTo(int32(cpuMax))
}
if cpu.Min != nil {
cpuMin, _ := instanceRequirements.CPU.Min.AsInt64()
ir.VCpuCount.Min = &cpuMin
ir.VCpuCount.Min = fi.PtrTo(int32(cpuMin))
}
} else {
ir.VCpuCount.Min = fi.PtrTo(int64(0))
ir.VCpuCount.Min = fi.PtrTo(int32(0))
}
memory := instanceRequirements.Memory
if memory != nil {
if memory.Max != nil {
memoryMax := instanceRequirements.Memory.Max.ScaledValue(resource.Mega)
ir.MemoryMiB.Max = &memoryMax
ir.MemoryMiB.Max = fi.PtrTo(int32(memoryMax))
}
if memory.Min != nil {
memoryMin := instanceRequirements.Memory.Min.ScaledValue(resource.Mega)
ir.MemoryMiB.Min = &memoryMin
ir.MemoryMiB.Min = fi.PtrTo(int32(memoryMin))
}
} else {
ir.MemoryMiB.Min = fi.PtrTo(int64(0))
ir.MemoryMiB.Min = fi.PtrTo(int32(0))
}
ir.AcceleratorCount = &ec2.AcceleratorCountRequest{
Min: fi.PtrTo(int64(0)),
Max: fi.PtrTo(int64(0)),
ir.AcceleratorCount = &ec2types.AcceleratorCountRequest{
Min: fi.PtrTo(int32(0)),
Max: fi.PtrTo(int32(0)),
}
response, err := cloud.EC2().GetInstanceTypesFromInstanceRequirements(
response, err := cloud.EC2().GetInstanceTypesFromInstanceRequirements(ctx,
&ec2.GetInstanceTypesFromInstanceRequirementsInput{
ArchitectureTypes: []*string{arch},
VirtualizationTypes: []*string{hv},
ArchitectureTypes: []ec2types.ArchitectureType{ec2types.ArchitectureType(arch)},
VirtualizationTypes: []ec2types.VirtualizationType{hv},
InstanceRequirements: ir,
},
)

View File

@ -35,6 +35,7 @@ import (
awsconfig "github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/aws/aws-sdk-go-v2/service/autoscaling"
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
"github.com/aws/aws-sdk-go-v2/service/kms"
"github.com/aws/aws-sdk-go/aws/awserr"
"go.uber.org/multierr"
@ -264,7 +265,7 @@ func (c *NodeUpCommand) Run(out io.Writer) error {
if nvidia != nil && fi.ValueOf(nvidia.Enabled) {
awsCloud := cloud.(awsup.AWSCloud)
// Get the instance type's detailed information.
instanceType, err := awsup.GetMachineTypeInfo(awsCloud, modelContext.MachineType)
instanceType, err := awsup.GetMachineTypeInfo(awsCloud, ec2types.InstanceType(modelContext.MachineType))
if err != nil {
return err
}