Skip to content

Commit

Permalink
Configure EC2 instance metadata options (#4037)
Browse files Browse the repository at this point in the history
* Configure ec2 instance metadata options

Allows configuration of EC2 instance metadata options to add IMDSv2 support.

* add e2e test

* refactor to reduce complexity

* test machine deployment
  • Loading branch information
muraee authored Mar 7, 2023
1 parent 36ddbf4 commit aa7d627
Show file tree
Hide file tree
Showing 22 changed files with 636 additions and 40 deletions.
3 changes: 3 additions & 0 deletions api/v1beta1/awscluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error {
restoreControlPlaneLoadBalancerStatus(&restored.Status.Network.APIServerELB, &dst.Status.Network.APIServerELB)

dst.Spec.S3Bucket = restored.Spec.S3Bucket
if restored.Status.Bastion != nil {
dst.Status.Bastion.InstanceMetadataOptions = restored.Status.Bastion.InstanceMetadataOptions
}

return nil
}
Expand Down
2 changes: 2 additions & 0 deletions api/v1beta1/awsmachine_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func (src *AWSMachine) ConvertTo(dstRaw conversion.Hub) error {
}

dst.Spec.Ignition = restored.Spec.Ignition
dst.Spec.InstanceMetadataOptions = restored.Spec.InstanceMetadataOptions

return nil
}
Expand Down Expand Up @@ -81,6 +82,7 @@ func (r *AWSMachineTemplate) ConvertTo(dstRaw conversion.Hub) error {

dst.Spec.Template.ObjectMeta = restored.Spec.Template.ObjectMeta
dst.Spec.Template.Spec.Ignition = restored.Spec.Template.Spec.Ignition
dst.Spec.Template.Spec.InstanceMetadataOptions = restored.Spec.Template.Spec.InstanceMetadataOptions

return nil
}
Expand Down
8 changes: 8 additions & 0 deletions api/v1beta1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ func Convert_v1beta2_NetworkStatus_To_v1beta1_NetworkStatus(in *v1beta2.NetworkS
return autoConvert_v1beta2_NetworkStatus_To_v1beta1_NetworkStatus(in, out, s)
}

func Convert_v1beta2_AWSMachineSpec_To_v1beta1_AWSMachineSpec(in *v1beta2.AWSMachineSpec, out *AWSMachineSpec, s conversion.Scope) error {
return autoConvert_v1beta2_AWSMachineSpec_To_v1beta1_AWSMachineSpec(in, out, s)
}

func Convert_v1beta2_Instance_To_v1beta1_Instance(in *v1beta2.Instance, out *Instance, s conversion.Scope) error {
return autoConvert_v1beta2_Instance_To_v1beta1_Instance(in, out, s)
}

func Convert_v1beta1_ClassicELB_To_v1beta2_LoadBalancer(in *ClassicELB, out *v1beta2.LoadBalancer, s conversion.Scope) error {
out.Name = in.Name
out.DNSName = in.DNSName
Expand Down
52 changes: 30 additions & 22 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/awsmachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ type AWSMachineSpec struct {
// InstanceID is the EC2 instance ID for this machine.
InstanceID *string `json:"instanceID,omitempty"`

// InstanceMetadataOptions is the metadata options for the EC2 instance.
// +optional
InstanceMetadataOptions *InstanceMetadataOptions `json:"instanceMetadataOptions,omitempty"`

// AMI is the reference to the AMI from which to create the machine instance.
AMI AMIReference `json:"ami,omitempty"`

Expand Down
12 changes: 12 additions & 0 deletions api/v1beta2/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,15 @@ func SetDefaults_Labels(obj *metav1.ObjectMeta) { //nolint:golint,stylecheck
clusterv1.ClusterctlMoveHierarchyLabelName: ""}
}
}

// SetDefaults_AWSMachineSpec is used by defaulter-gen.
func SetDefaults_AWSMachineSpec(obj *AWSMachineSpec) { //nolint:golint,stylecheck
if obj.InstanceMetadataOptions == nil {
obj.InstanceMetadataOptions = &InstanceMetadataOptions{
HTTPEndpoint: InstanceMetadataEndpointStateEnabled,
HTTPPutResponseHopLimit: 1,
HTTPTokens: HTTPTokensStateRequired, // Defaults to IMDSv2
InstanceMetadataTags: InstanceMetadataEndpointStateDisabled,
}
}
}
77 changes: 77 additions & 0 deletions api/v1beta2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,83 @@ type Instance struct {
// IDs of the instance's volumes
// +optional
VolumeIDs []string `json:"volumeIDs,omitempty"`

// InstanceMetadataOptions is the metadata options for the EC2 instance.
// +optional
InstanceMetadataOptions *InstanceMetadataOptions `json:"instanceMetadataOptions,omitempty"`
}

// InstanceMetadataState describes the state of InstanceMetadataOptions.HttpEndpoint and InstanceMetadataOptions.InstanceMetadataTags
type InstanceMetadataState string

const (
// InstanceMetadataEndpointStateDisabled represents the disabled state
InstanceMetadataEndpointStateDisabled = InstanceMetadataState("disabled")

// InstanceMetadataEndpointStateEnabled represents the enabled state
InstanceMetadataEndpointStateEnabled = InstanceMetadataState("enabled")
)

// HTTPTokensState describes the state of InstanceMetadataOptions.HTTPTokensState
type HTTPTokensState string

const (
// HTTPTokensStateOptional represents the optional state
HTTPTokensStateOptional = HTTPTokensState("optional")

// HTTPTokensStateRequired represents the required state (IMDSv2)
HTTPTokensStateRequired = HTTPTokensState("required")
)

// InstanceMetadataOptions describes metadata options for the EC2 instance.
type InstanceMetadataOptions struct {
// Enables or disables the HTTP metadata endpoint on your instances.
//
// If you specify a value of disabled, you cannot access your instance metadata.
//
// Default: enabled
//
// +kubebuilder:validation:Enum:=enabled;disabled
// +kubebuilder:default=enabled
HTTPEndpoint InstanceMetadataState `json:"httpEndpoint,omitempty"`

// The desired HTTP PUT response hop limit for instance metadata requests. The
// larger the number, the further instance metadata requests can travel.
//
// Default: 1
//
// +kubebuilder:validation:Minimum:=1
// +kubebuilder:validation:Maximum:=64
// +kubebuilder:default=1
HTTPPutResponseHopLimit int64 `json:"httpPutResponseHopLimit,omitempty"`

// The state of token usage for your instance metadata requests.
//
// If the state is optional, you can choose to retrieve instance metadata with
// or without a session token on your request. If you retrieve the IAM role
// credentials without a token, the version 1.0 role credentials are returned.
// If you retrieve the IAM role credentials using a valid session token, the
// version 2.0 role credentials are returned.
//
// If the state is required, you must send a session token with any instance
// metadata retrieval requests. In this state, retrieving the IAM role credentials
// always returns the version 2.0 credentials; the version 1.0 credentials are
// not available.
//
// Default: required
// +kubebuilder:validation:Enum:=optional;required
// +kubebuilder:default=required
HTTPTokens HTTPTokensState `json:"httpTokens,omitempty"`

// Set to enabled to allow access to instance tags from the instance metadata.
// Set to disabled to turn off access to instance tags from the instance metadata.
// For more information, see Work with instance tags using the instance metadata
// (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html#work-with-tags-in-IMDS).
//
// Default: disabled
// +kubebuilder:validation:Enum:=enabled;disabled
// +kubebuilder:default=disabled
InstanceMetadataTags InstanceMetadataState `json:"instanceMetadataTags,omitempty"`
}

// Volume encapsulates the configuration options for the storage device.
Expand Down
25 changes: 25 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.

10 changes: 10 additions & 0 deletions api/v1beta2/zz_generated.defaults.go

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

Loading

0 comments on commit aa7d627

Please sign in to comment.