Repository: kubernetes-sigs/cluster-api-provider-aws
Pull request #3790 (2022-10-20 17:10:12)

Change naming format of AMIs while searching for AMIs
**What type of PR is this?**
/kind bug

**What this PR does / why we need it**:
The old AMIs were generated with following pattern: `capa-ami-amazon-2-1.25.2-00-1664536077`. From the recent releases, the new AMIs are getting generated as `capa-ami-amazon-2-v1.25.3-1665727783`(observe prefix v to the k8s version)). Because of this mismatch, the newly generated AMIs are not getting published in S3, as the AMIs are filtered based on the convention `capa-ami-{{.BaseOS}}-{{.K8sVersion}}`.
This PR fixes the AMI naming format from `capa-ami-{{.BaseOS}}-{{.K8sVersion}}` to `capa-ami-{{.BaseOS}}-{{.K8sVersion}}-*`, such that all the new AMIs are also published to the S3 amis.json.
[Ref](https://kubernetes.slack.com/archives/C01E0Q35A8J/p1666969997721009) slack thread.

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #

**Special notes for your reviewer**:

**Checklist**:

- [x] squashed commits
- [ ] includes documentation
- [x] adds unit tests
- [ ] adds or updates e2e tests


k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by:
**Once this PR has been reviewed and has the lgtm label**, please ask for approval from ankitasw by writing `/assign @ankitasw` in a comment. For more information see [the Kubernetes Code Review Process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process).

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fcluster-api-provider-aws).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubernetes-sigs/cluster-api-provider-aws/blob/main/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["ankitasw"]} -->
Ankitasw: /priority critical-urgent
cc @richardcase 
dlipovetsky: Does this need a backport to one or more of: release-1.5, release-1.6, release-2.0?
Ankitasw: > Does this need a backport to one or more of: release-1.5, release-1.6, release-2.0?

This doesn't need backport as this change has been introduced from [latest release](https://github.com/kubernetes-sigs/image-builder/releases/tag/v0.1.13) of image-builder. With older versions, we don't have any issue.
k8s-ci-robot: @Ankitasw: The following test **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-cluster-api-provider-aws-test | 70a95a6851ffdb26c6d6fb2512fb4333b989ca6e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-aws/3790/pull-cluster-api-provider-aws-test/1586053037997166592) | true | `/test pull-cluster-api-provider-aws-test`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-aws&pr=3790). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3AAnkitasw). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-aws/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->

Patch:
diff --git a/cmd/clusterawsadm/ami/helper.go b/cmd/clusterawsadm/ami/helper.go
index 0ca0e4c70..11271f0d0 100644
--- a/cmd/clusterawsadm/ami/helper.go
+++ b/cmd/clusterawsadm/ami/helper.go
@@ -229,7 +229,7 @@ func getAllImages(ec2Client ec2iface.EC2API, ownerID string) (map[string][]*ec2.
 }
 
 func findAMI(imagesMap map[string][]*ec2.Image, baseOS, kubernetesVersion string) (*ec2.Image, error) {
-	amiNameFormat := "capa-ami-{{.BaseOS}}-{{.K8sVersion}}"
+	amiNameFormat := "capa-ami-{{.BaseOS}}-{{.K8sVersion}}-*"
 	amiName, err := ec2service.GenerateAmiName(amiNameFormat, baseOS, kubernetesVersion)
 	if err != nil {
 		return nil, errors.Wrapf(err, "failed to process ami format: %q", amiNameFormat)
diff --git a/pkg/cloud/services/ec2/ami.go b/pkg/cloud/services/ec2/ami.go
index 8f46c97dd..75e6d0835 100644
--- a/pkg/cloud/services/ec2/ami.go
+++ b/pkg/cloud/services/ec2/ami.go
@@ -20,7 +20,6 @@ import (
 	"bytes"
 	"fmt"
 	"sort"
-	"strings"
 	"text/template"
 	"time"
 
@@ -77,7 +76,7 @@ type AMILookup struct {
 
 // GenerateAmiName will generate an AMI name.
 func GenerateAmiName(amiNameFormat, baseOS, kubernetesVersion string) (string, error) {
-	amiNameParameters := AMILookup{baseOS, strings.TrimPrefix(kubernetesVersion, "v")}
+	amiNameParameters := AMILookup{baseOS, kubernetesVersion}
 	// revert to default if not specified
 	if amiNameFormat == "" {
 		amiNameFormat = DefaultAmiNameFormat


Test patch:
diff --git a/cmd/clusterawsadm/ami/helper_test.go b/cmd/clusterawsadm/ami/helper_test.go
index ac47834d0..680ace868 100644
--- a/cmd/clusterawsadm/ami/helper_test.go
+++ b/cmd/clusterawsadm/ami/helper_test.go
@@ -19,7 +19,10 @@ package ami
 import (
 	"testing"
 
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/service/ec2"
 	"github.com/google/go-cmp/cmp"
+	. "github.com/onsi/gomega"
 )
 
 func TestAllPatchVersions(t *testing.T) {
@@ -51,3 +54,50 @@ func TestAllPatchVersions(t *testing.T) {
 		})
 	}
 }
+
+func TestFindAMI(t *testing.T) {
+	tests := []struct {
+		name      string
+		imagesMap map[string][]*ec2.Image
+		want      *ec2.Image
+	}{
+		{
+			name: "find AMI based on the latest ami format",
+			imagesMap: map[string][]*ec2.Image{
+				"capa-ami-amazon-2-v1.23.5-*": {
+					{
+						ImageId:      aws.String("capa-ami-amazon-2-v1.25.3-1664536077"),
+						CreationDate: aws.String("2011-02-08T17:02:31.000Z"),
+					},
+				},
+			},
+			want: &ec2.Image{
+				ImageId:      aws.String("capa-ami-amazon-2-v1.25.3-1664536077"),
+				CreationDate: aws.String("2011-02-08T17:02:31.000Z"),
+			},
+		},
+		{
+			name: "find AMI based on the old ami format",
+			imagesMap: map[string][]*ec2.Image{
+				"capa-ami-amazon-2-1.23.5": {
+					{
+						ImageId:      aws.String("capa-ami-amazon-2-1.25.3-00-1664536077"),
+						CreationDate: aws.String("2011-02-08T17:02:31.000Z"),
+					},
+				},
+			},
+			want: nil,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			g := NewWithT(t)
+			got, err := findAMI(tt.imagesMap, "amazon-2", "v1.23.5")
+			if err != nil {
+				t.Fatalf("error while finding AMI %+v", err)
+			}
+			g.Expect(got).Should(Equal(tt.want))
+		})
+	}
+}
diff --git a/pkg/cloud/services/ec2/ami_test.go b/pkg/cloud/services/ec2/ami_test.go
index eec279a88..bc0ae2d59 100644
--- a/pkg/cloud/services/ec2/ami_test.go
+++ b/pkg/cloud/services/ec2/ami_test.go
@@ -265,7 +265,7 @@ func TestGenerateAmiName(t *testing.T) {
 			args: args{
 				kubernetesVersion: "v1.23.3",
 			},
-			want: "capa-ami--?1.23.3-*",
+			want: "capa-ami--?v1.23.3-*",
 		},
 		{
 			name: "Should return valid amiName if default AMI name format passed",