From cee67102e8c0aecf4546c737419ecfe931b01efb Mon Sep 17 00:00:00 2001 From: "justin.miron" Date: Fri, 29 Mar 2024 10:30:49 -0500 Subject: [PATCH] Remove `TagSpecification` from the EC2 instance spec Instance parameters allows specifying tags in two methods: `TagSpecification` and `Tags`. These methods have different semantics - `TagSpecification` tags will be applied when the instance is created, `Tags` will be created in a separate `CreateTags` API call afterwards. All tags required to meet IAM policy must be specified in `TagSpecification`. Signed-off-by: justin.miron --- apis/ec2/manualv1alpha1/instances_types.go | 8 --- .../manualv1alpha1/zz_generated.deepcopy.go | 7 -- .../crds/ec2.aws.crossplane.io_instances.yaml | 69 ------------------- pkg/clients/ec2/instance.go | 33 +++++---- pkg/controller/ec2/instance/controller.go | 6 +- 5 files changed, 19 insertions(+), 104 deletions(-) diff --git a/apis/ec2/manualv1alpha1/instances_types.go b/apis/ec2/manualv1alpha1/instances_types.go index 3e7e578032..f0d86290f8 100644 --- a/apis/ec2/manualv1alpha1/instances_types.go +++ b/apis/ec2/manualv1alpha1/instances_types.go @@ -264,14 +264,6 @@ type InstanceParameters struct { // +optional Tags []Tag `json:"tags,omitempty"` - // The tags to apply to the resources during launch. You can only tag instances - // and volumes on launch. The specified tags are applied to all instances or - // volumes that are created during launch. To tag a resource after it has been - // created, see CreateTags (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateTags.html). - // +immutable - // +optional - TagSpecifications []TagSpecification `json:"tagSpecifications,omitempty"` - // The user data to make available to the instance. For more information, see // Running Commands on Your Linux Instance at Launch (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html) // (Linux) and Adding User Data (https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-instance-metadata.html#instancedata-add-user-data) diff --git a/apis/ec2/manualv1alpha1/zz_generated.deepcopy.go b/apis/ec2/manualv1alpha1/zz_generated.deepcopy.go index 8be2b64193..c13820ea6e 100644 --- a/apis/ec2/manualv1alpha1/zz_generated.deepcopy.go +++ b/apis/ec2/manualv1alpha1/zz_generated.deepcopy.go @@ -1247,13 +1247,6 @@ func (in *InstanceParameters) DeepCopyInto(out *InstanceParameters) { *out = make([]Tag, len(*in)) copy(*out, *in) } - if in.TagSpecifications != nil { - in, out := &in.TagSpecifications, &out.TagSpecifications - *out = make([]TagSpecification, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } if in.UserData != nil { in, out := &in.UserData, &out.UserData *out = new(string) diff --git a/package/crds/ec2.aws.crossplane.io_instances.yaml b/package/crds/ec2.aws.crossplane.io_instances.yaml index e07e94b293..a4fd000734 100644 --- a/package/crds/ec2.aws.crossplane.io_instances.yaml +++ b/package/crds/ec2.aws.crossplane.io_instances.yaml @@ -1035,75 +1035,6 @@ spec: type: string type: object type: object - tagSpecifications: - description: The tags to apply to the resources during launch. - You can only tag instances and volumes on launch. The specified - tags are applied to all instances or volumes that are created - during launch. To tag a resource after it has been created, - see CreateTags (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateTags.html). - items: - description: TagSpecification defines the tags to apply to a - resource when the resource is being created. - properties: - resourceType: - description: "The type of resource to tag. Currently, the - resource types that support tagging on creation are: capacity-reservation - | client-vpn-endpoint | dedicated-host | fleet | fpga-image - | instance | ipv4pool-ec2 | ipv6pool-ec2 | key-pair | - launch-template | natgateway | spot-fleet-request | placement-group - | snapshot | traffic-mirror-filter | traffic-mirror-session - | traffic-mirror-target | transit-gateway | transit-gateway-attachment - | transit-gateway-route-table | vpc-endpoint (for interface - VPC endpoints)| vpc-endpoint-service (for gateway VPC - endpoints) | volume | vpc-flow-log. \n To tag a resource - after it has been created, see CreateTags (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateTags.html)." - enum: - - capacity-reservation - - client-vpn-endpoint - - dedicated-host - - fleet - - fpga-image - - instance - - ipv4pool-ec2 - - ipv6pool-ec2 - - key-pair - - launch-template - - natgateway - - spot-fleet-request - - placement-group - - snapshot - - traffic-mirror-filter - - traffic-mirror-session - - traffic-mirror-target - - transit-gateway - - transit-gateway-attachment - - transit-gateway-route-table - - vpc-endpoint - - vpc-endpoint-service - - volume - - vpc-flow-log - type: string - tags: - description: The tags to apply to the resource - items: - description: Tag defines a tag - properties: - key: - description: Key is the name of the tag. - type: string - value: - description: Value is the value of the tag. - type: string - required: - - key - - value - type: object - type: array - required: - - resourceType - - tags - type: object - type: array tags: description: Tags are used as identification helpers between AWS resources. diff --git a/pkg/clients/ec2/instance.go b/pkg/clients/ec2/instance.go index ac6eff7103..ac4123f416 100644 --- a/pkg/clients/ec2/instance.go +++ b/pkg/clients/ec2/instance.go @@ -33,6 +33,9 @@ import ( const ( // InstanceNotFound is the code that is returned by ec2 when the given InstanceID is not valid InstanceNotFound = "InvalidInstanceID.NotFound" + + // Instance type associated with EC2 instance tags + instanceResourceType = "instance" ) // InstanceClient is the external client used for Instance Custom Resource @@ -819,7 +822,7 @@ func GenerateEC2RunInstancesInput(name string, p *manualv1alpha1.InstanceParamet RamdiskId: p.RAMDiskID, SecurityGroupIds: p.SecurityGroupIDs, SubnetId: p.SubnetID, - TagSpecifications: GenerateEC2TagSpecifications(p.TagSpecifications), + TagSpecifications: GenerateEC2TagSpecifications(p.Tags), UserData: p.UserData, } } @@ -852,25 +855,21 @@ func GenerateTags(tags []types.Tag) []manualv1alpha1.Tag { // GenerateEC2TagSpecifications takes a slice of TagSpecifications and converts it to a // slice of ec2.TagSpecification -func GenerateEC2TagSpecifications(tagSpecs []manualv1alpha1.TagSpecification) []types.TagSpecification { - if tagSpecs != nil { - res := make([]types.TagSpecification, len(tagSpecs)) - for i, ts := range tagSpecs { - res[i] = types.TagSpecification{ - ResourceType: types.ResourceType(*ts.ResourceType), - } +func GenerateEC2TagSpecifications(tags []manualv1alpha1.Tag) []types.TagSpecification { + if len(tags) > 0 { + tagSpec := types.TagSpecification{ + ResourceType: types.ResourceType(instanceResourceType), + Tags: make([]types.Tag, len(tags)), + } - tags := make([]types.Tag, len(ts.Tags)) - for i, t := range ts.Tags { - tags[i] = types.Tag{ - Key: aws.String(t.Key), - Value: aws.String(t.Value), - } + for i, t := range tags { + tagSpec.Tags[i] = types.Tag{ + Key: aws.String(t.Key), + Value: aws.String(t.Value), } - - res[i].Tags = tags } - return res + + return []types.TagSpecification{tagSpec} } return nil } diff --git a/pkg/controller/ec2/instance/controller.go b/pkg/controller/ec2/instance/controller.go index 45ceeaf9f9..c32b33621e 100644 --- a/pkg/controller/ec2/instance/controller.go +++ b/pkg/controller/ec2/instance/controller.go @@ -246,9 +246,9 @@ func (e *external) Create(ctx context.Context, mgd resource.Managed) (managed.Ex return managed.ExternalCreation{}, errors.New(errUnexpectedObject) } - result, err := e.client.RunInstances(ctx, - ec2.GenerateEC2RunInstancesInput(mgd.GetName(), &cr.Spec.ForProvider), - ) + input := ec2.GenerateEC2RunInstancesInput(mgd.GetName(), &cr.Spec.ForProvider) + + result, err := e.client.RunInstances(ctx, input) if err != nil { return managed.ExternalCreation{}, errorutils.Wrap(err, errCreate) }