Skip to content

Commit d3c59d9

Browse files
authored
Merge pull request #4892 from r4f4/shared-vpc-associate-public-ip
🐛 ec2: instances: fix assigning public IP
2 parents 6afad25 + 46abb5b commit d3c59d9

File tree

8 files changed

+555
-5
lines changed

8 files changed

+555
-5
lines changed

api/v1beta1/awscluster_conversion.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error {
5757
dst.Status.Bastion.InstanceMetadataOptions = restored.Status.Bastion.InstanceMetadataOptions
5858
dst.Status.Bastion.PlacementGroupName = restored.Status.Bastion.PlacementGroupName
5959
dst.Status.Bastion.PrivateDNSName = restored.Status.Bastion.PrivateDNSName
60+
dst.Status.Bastion.PublicIPOnLaunch = restored.Status.Bastion.PublicIPOnLaunch
6061
}
6162
dst.Spec.Partition = restored.Spec.Partition
6263

api/v1beta1/zz_generated.conversion.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1beta2/types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,10 @@ type Instance struct {
237237
// PrivateDNSName is the options for the instance hostname.
238238
// +optional
239239
PrivateDNSName *PrivateDNSName `json:"privateDnsName,omitempty"`
240+
241+
// PublicIPOnLaunch is the option to associate a public IP on instance launch
242+
// +optional
243+
PublicIPOnLaunch *bool `json:"publicIPOnLaunch,omitempty"`
240244
}
241245

242246
// InstanceMetadataState describes the state of InstanceMetadataOptions.HttpEndpoint and InstanceMetadataOptions.InstanceMetadataTags

api/v1beta2/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,10 @@ spec:
11321132
privateIp:
11331133
description: The private IPv4 address assigned to the instance.
11341134
type: string
1135+
publicIPOnLaunch:
1136+
description: PublicIPOnLaunch is the option to associate a public
1137+
IP on instance launch
1138+
type: boolean
11351139
publicIp:
11361140
description: The public IPv4 address assigned to the instance,
11371141
if applicable.
@@ -2984,6 +2988,10 @@ spec:
29842988
privateIp:
29852989
description: The private IPv4 address assigned to the instance.
29862990
type: string
2991+
publicIPOnLaunch:
2992+
description: PublicIPOnLaunch is the option to associate a public
2993+
IP on instance launch
2994+
type: boolean
29872995
publicIp:
29882996
description: The public IPv4 address assigned to the instance,
29892997
if applicable.

config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1907,6 +1907,10 @@ spec:
19071907
privateIp:
19081908
description: The private IPv4 address assigned to the instance.
19091909
type: string
1910+
publicIPOnLaunch:
1911+
description: PublicIPOnLaunch is the option to associate a public
1912+
IP on instance launch
1913+
type: boolean
19101914
publicIp:
19111915
description: The public IPv4 address assigned to the instance,
19121916
if applicable.

pkg/cloud/services/ec2/instances.go

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,21 @@ func (s *Service) CreateInstance(scope *scope.MachineScope, userData []byte, use
182182
}
183183
input.SubnetID = subnetID
184184

185+
if ptr.Deref(scope.AWSMachine.Spec.PublicIP, false) {
186+
subnets, err := s.getFilteredSubnets(&ec2.Filter{
187+
Name: aws.String("subnet-id"),
188+
Values: aws.StringSlice([]string{subnetID}),
189+
})
190+
if err != nil {
191+
return nil, fmt.Errorf("could not query if subnet has MapPublicIpOnLaunch set: %w", err)
192+
}
193+
if len(subnets) == 0 {
194+
return nil, fmt.Errorf("expected to find subnet %q", subnetID)
195+
}
196+
// If the subnet does not assign public IPs, set that option in the instance's network interface
197+
input.PublicIPOnLaunch = ptr.To(!aws.BoolValue(subnets[0].MapPublicIpOnLaunch))
198+
}
199+
185200
if !scope.IsControlPlaneExternallyManaged() && !scope.IsExternallyManaged() && !scope.IsEKSManaged() && s.scope.Network().APIServerELB.DNSName == "" {
186201
record.Eventf(s.scope.InfraCluster(), "FailedCreateInstance", "Failed to run controlplane, APIServer ELB not available")
187202
return nil, awserrors.NewFailedDependency("failed to run controlplane, APIServer ELB not available")
@@ -335,7 +350,7 @@ func (s *Service) findSubnet(scope *scope.MachineScope) (string, error) {
335350
*subnet.SubnetId, *subnet.AvailabilityZone, *failureDomain)
336351
continue
337352
}
338-
if scope.AWSMachine.Spec.PublicIP != nil && *scope.AWSMachine.Spec.PublicIP && !*subnet.MapPublicIpOnLaunch {
353+
if scope.AWSMachine.Spec.PublicIP != nil && *scope.AWSMachine.Spec.PublicIP && !s.scope.Subnets().FindByID(*subnet.SubnetId).IsPublic {
339354
errMessage += fmt.Sprintf(" subnet %q is a private subnet.", *subnet.SubnetId)
340355
continue
341356
}
@@ -539,13 +554,25 @@ func (s *Service) runInstance(role string, i *infrav1.Instance) (*infrav1.Instan
539554
DeviceIndex: aws.Int64(int64(index)),
540555
})
541556
}
557+
netInterfaces[0].AssociatePublicIpAddress = i.PublicIPOnLaunch
542558

543559
input.NetworkInterfaces = netInterfaces
544560
} else {
545-
input.SubnetId = aws.String(i.SubnetID)
561+
if ptr.Deref(i.PublicIPOnLaunch, false) {
562+
input.NetworkInterfaces = []*ec2.InstanceNetworkInterfaceSpecification{
563+
{
564+
DeviceIndex: aws.Int64(0),
565+
SubnetId: aws.String(i.SubnetID),
566+
Groups: aws.StringSlice(i.SecurityGroupIDs),
567+
AssociatePublicIpAddress: i.PublicIPOnLaunch,
568+
},
569+
}
570+
} else {
571+
input.SubnetId = aws.String(i.SubnetID)
546572

547-
if len(i.SecurityGroupIDs) > 0 {
548-
input.SecurityGroupIds = aws.StringSlice(i.SecurityGroupIDs)
573+
if len(i.SecurityGroupIDs) > 0 {
574+
input.SecurityGroupIds = aws.StringSlice(i.SecurityGroupIDs)
575+
}
549576
}
550577
}
551578

0 commit comments

Comments
 (0)