Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 ec2: instances: fix assigning public IP #4892

Merged
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
1 change: 1 addition & 0 deletions api/v1beta1/awscluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error {
dst.Status.Bastion.InstanceMetadataOptions = restored.Status.Bastion.InstanceMetadataOptions
dst.Status.Bastion.PlacementGroupName = restored.Status.Bastion.PlacementGroupName
dst.Status.Bastion.PrivateDNSName = restored.Status.Bastion.PrivateDNSName
dst.Status.Bastion.PublicIPOnLaunch = restored.Status.Bastion.PublicIPOnLaunch
}
dst.Spec.Partition = restored.Spec.Partition

Expand Down
1 change: 1 addition & 0 deletions api/v1beta1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions api/v1beta2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ type Instance struct {
// PrivateDNSName is the options for the instance hostname.
// +optional
PrivateDNSName *PrivateDNSName `json:"privateDnsName,omitempty"`

// PublicIPOnLaunch is the option to associate a public IP on instance launch
// +optional
PublicIPOnLaunch *bool `json:"publicIPOnLaunch,omitempty"`
vincepri marked this conversation as resolved.
Show resolved Hide resolved
}

// InstanceMetadataState describes the state of InstanceMetadataOptions.HttpEndpoint and InstanceMetadataOptions.InstanceMetadataTags
Expand Down
5 changes: 5 additions & 0 deletions api/v1beta2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,10 @@ spec:
privateIp:
description: The private IPv4 address assigned to the instance.
type: string
publicIPOnLaunch:
description: PublicIPOnLaunch is the option to associate a public
IP on instance launch
type: boolean
publicIp:
description: The public IPv4 address assigned to the instance,
if applicable.
Expand Down Expand Up @@ -2984,6 +2988,10 @@ spec:
privateIp:
description: The private IPv4 address assigned to the instance.
type: string
publicIPOnLaunch:
description: PublicIPOnLaunch is the option to associate a public
IP on instance launch
type: boolean
publicIp:
description: The public IPv4 address assigned to the instance,
if applicable.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1907,6 +1907,10 @@ spec:
privateIp:
description: The private IPv4 address assigned to the instance.
type: string
publicIPOnLaunch:
description: PublicIPOnLaunch is the option to associate a public
IP on instance launch
type: boolean
publicIp:
description: The public IPv4 address assigned to the instance,
if applicable.
Expand Down
35 changes: 31 additions & 4 deletions pkg/cloud/services/ec2/instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,21 @@ func (s *Service) CreateInstance(scope *scope.MachineScope, userData []byte, use
}
input.SubnetID = subnetID

if ptr.Deref(scope.AWSMachine.Spec.PublicIP, false) {
subnets, err := s.getFilteredSubnets(&ec2.Filter{
Name: aws.String("subnet-id"),
Values: aws.StringSlice([]string{subnetID}),
})
if err != nil {
return nil, fmt.Errorf("could not query if subnet has MapPublicIpOnLaunch set: %w", err)
}
if len(subnets) == 0 {
return nil, fmt.Errorf("expected to find subnet %q", subnetID)
}
// If the subnet does not assign public IPs, set that option in the instance's network interface
input.PublicIPOnLaunch = ptr.To(!aws.BoolValue(subnets[0].MapPublicIpOnLaunch))
}

if !scope.IsControlPlaneExternallyManaged() && !scope.IsExternallyManaged() && !scope.IsEKSManaged() && s.scope.Network().APIServerELB.DNSName == "" {
record.Eventf(s.scope.InfraCluster(), "FailedCreateInstance", "Failed to run controlplane, APIServer ELB not available")
return nil, awserrors.NewFailedDependency("failed to run controlplane, APIServer ELB not available")
Expand Down Expand Up @@ -334,7 +349,7 @@ func (s *Service) findSubnet(scope *scope.MachineScope) (string, error) {
*subnet.SubnetId, *subnet.AvailabilityZone, *failureDomain)
continue
}
if scope.AWSMachine.Spec.PublicIP != nil && *scope.AWSMachine.Spec.PublicIP && !*subnet.MapPublicIpOnLaunch {
if scope.AWSMachine.Spec.PublicIP != nil && *scope.AWSMachine.Spec.PublicIP && !s.scope.Subnets().FindByID(*subnet.SubnetId).IsPublic {
errMessage += fmt.Sprintf(" subnet %q is a private subnet.", *subnet.SubnetId)
continue
}
Expand Down Expand Up @@ -538,13 +553,25 @@ func (s *Service) runInstance(role string, i *infrav1.Instance) (*infrav1.Instan
DeviceIndex: aws.Int64(int64(index)),
})
}
netInterfaces[0].AssociatePublicIpAddress = i.PublicIPOnLaunch

input.NetworkInterfaces = netInterfaces
} else {
input.SubnetId = aws.String(i.SubnetID)
if ptr.Deref(i.PublicIPOnLaunch, false) {
input.NetworkInterfaces = []*ec2.InstanceNetworkInterfaceSpecification{
{
DeviceIndex: aws.Int64(0),
SubnetId: aws.String(i.SubnetID),
Groups: aws.StringSlice(i.SecurityGroupIDs),
AssociatePublicIpAddress: i.PublicIPOnLaunch,
},
}
} else {
input.SubnetId = aws.String(i.SubnetID)

if len(i.SecurityGroupIDs) > 0 {
input.SecurityGroupIds = aws.StringSlice(i.SecurityGroupIDs)
if len(i.SecurityGroupIDs) > 0 {
input.SecurityGroupIds = aws.StringSlice(i.SecurityGroupIDs)
}
}
}

Expand Down
Loading
Loading