Repository: awslabs/amazon-eks-ami
Pull request #2227: feat(nodeadm): configure container runtime based on binaries
Author: login: ndbaker1
Created: 2025-04-23T06:33:49Z | Merged: 2025-04-30T22:20:29Z

**Issue #, if available:**

**Description of changes:**

This PR removes validation of instance type for loading the nvidia container runtime by relying on the presence of the `nvidia-container-runtime` binaries being present in the AMI. This is normally a safe assumption, since you should only be using NVIDIA-enabled EKS AMIs with NVIDIA-based EC2 instances.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

<!-- If this is a security issue, please do not discuss on GitHub. Please report any suspected or confirmed security issues to AWS Security https://aws.amazon.com/security/vulnerability-reporting/ -->

**Testing Done**

the only edge cases we really need to test is when the GPU AMI is used on a non-GPU instance type, because the assumptions is baked in that the `nvidia-container-runtime` exists, but we need to know if this introduces any conflicts.

<!-- Include information regarding the testing that was completed with this changes. Where applicable, include details steps to replicate. -->

*[See this guide for recommended testing for PRs.](../doc/CONTRIBUTING.md#testing-changes) Some tests may not apply. Completing tests and providing additional validation steps are not required, but it is recommended and may reduce review time and time to merge.*



Diff:
diff --git a/nodeadm/internal/containerd/config.go b/nodeadm/internal/containerd/config.go
index f11200dfb..ba123d480 100644
--- a/nodeadm/internal/containerd/config.go
+++ b/nodeadm/internal/containerd/config.go
@@ -33,10 +33,6 @@ type containerdTemplateVars struct {
 }
 
 func writeContainerdConfig(cfg *api.NodeConfig) error {
-	if err := writeBaseRuntimeSpec(cfg); err != nil {
-		return err
-	}
-
 	containerdConfig, err := generateContainerdConfig(cfg)
 	if err != nil {
 		return err
@@ -61,12 +57,12 @@ func writeContainerdConfig(cfg *api.NodeConfig) error {
 }
 
 func generateContainerdConfig(cfg *api.NodeConfig) ([]byte, error) {
-	instanceOptions := applyInstanceTypeMixins(cfg.Status.Instance.Type)
+	runtimeOptions := getRuntimeOptions(cfg)
 
 	configVars := containerdTemplateVars{
 		SandboxImage:      cfg.Status.Defaults.SandboxImage,
-		RuntimeBinaryName: instanceOptions.RuntimeBinaryName,
-		RuntimeName:       instanceOptions.RuntimeName,
+		RuntimeBinaryName: runtimeOptions.RuntimeBinaryPath,
+		RuntimeName:       runtimeOptions.RuntimeName,
 		EnableCDI:         semver.Compare(cfg.Status.KubeletVersion, "v1.32.0") >= 0,
 	}
 	var buf bytes.Buffer
diff --git a/nodeadm/internal/containerd/daemon.go b/nodeadm/internal/containerd/daemon.go
index 76f1766b1..22cb8edcb 100644
--- a/nodeadm/internal/containerd/daemon.go
+++ b/nodeadm/internal/containerd/daemon.go
@@ -20,6 +20,9 @@ func NewContainerdDaemon(daemonManager daemon.DaemonManager) daemon.Daemon {
 }
 
 func (cd *containerd) Configure(c *api.NodeConfig) error {
+	if err := writeBaseRuntimeSpec(c); err != nil {
+		return err
+	}
 	return writeContainerdConfig(c)
 }
 
diff --git a/nodeadm/internal/containerd/runtime_config.go b/nodeadm/internal/containerd/runtime_config.go
index 9ad31043d..1f28de3de 100644
--- a/nodeadm/internal/containerd/runtime_config.go
+++ b/nodeadm/internal/containerd/runtime_config.go
@@ -1,65 +1,37 @@
 package containerd
 
-import (
-	"slices"
-	"strings"
+import "github.com/awslabs/amazon-eks-ami/nodeadm/internal/api"
 
-	"go.uber.org/zap"
-)
-
-type instanceOptions struct {
+type runtimeConfig struct {
 	RuntimeName       string
-	RuntimeBinaryName string
-}
-
-type instanceTypeMixin struct {
-	instanceFamilies []string
-	apply            func() instanceOptions
+	RuntimeBinaryPath string
 }
 
-func (m *instanceTypeMixin) matches(instanceType string) bool {
-	instanceFamily := strings.Split(instanceType, ".")[0]
-	return slices.Contains(m.instanceFamilies, instanceFamily)
+type runtimeConfigMixin interface {
+	Apply(*runtimeConfig)
+	Matches(*api.NodeConfig) bool
 }
 
-var (
-	// TODO: fetch this list dynamically
-	nvidiaInstances         = []string{"p3", "p3dn", "p4d", "p4de", "p5", "p5e", "p5en", "g4", "g4dn", "g5", "g6", "g6e", "g5g"}
-	NvidiaInstanceTypeMixin = instanceTypeMixin{
-		instanceFamilies: nvidiaInstances,
-		apply:            applyNvidia,
-	}
-
-	mixins = []instanceTypeMixin{
-		NvidiaInstanceTypeMixin,
-	}
+const (
+	defaultRuntimeName       = "runc"
+	defaultRuntimeBinaryPath = "/usr/sbin/runc"
 )
 
-const nvidiaRuntimeName = "nvidia"
-const nvidiaRuntimeBinaryName = "/usr/bin/nvidia-container-runtime"
-const defaultRuntimeName = "runc"
-const defaultRuntimeBinaryName = "/usr/sbin/runc"
+var mixins = []runtimeConfigMixin{
+	NewNvidiaRuntimeConfigMixin(),
+}
 
-// applyInstanceTypeMixins adds the needed OCI hook options to containerd config.toml
-// based on the instance family
-func applyInstanceTypeMixins(instanceType string) instanceOptions {
+// getRuntimeOptions adds the needed OCI hook options to containerd config.toml
+// based on the instance family and available runtime binaries
+func getRuntimeOptions(cfg *api.NodeConfig) runtimeConfig {
+	options := runtimeConfig{
+		RuntimeName:       defaultRuntimeName,
+		RuntimeBinaryPath: defaultRuntimeBinaryPath,
+	}
 	for _, mixin := range mixins {
-		if mixin.matches(instanceType) {
-			return mixin.apply()
+		if mixin.Matches(cfg) {
+			mixin.Apply(&options)
 		}
 	}
-	zap.L().Info("No instance specific containerd runtime configuration needed..", zap.String("instanceType", instanceType))
-	return applyDefault()
-}
-
-// applyNvidia adds the needed NVIDIA containerd options
-func applyNvidia() instanceOptions {
-	zap.L().Info("Configuring NVIDIA runtime..")
-	return instanceOptions{RuntimeName: nvidiaRuntimeName, RuntimeBinaryName: nvidiaRuntimeBinaryName}
-}
-
-// applyDefault adds the default runc containerd options
-func applyDefault() instanceOptions {
-	zap.L().Info("Configuring default runtime..")
-	return instanceOptions{RuntimeName: defaultRuntimeName, RuntimeBinaryName: defaultRuntimeBinaryName}
+	return options
 }
diff --git a/nodeadm/internal/containerd/runtime_config_nvidia.go b/nodeadm/internal/containerd/runtime_config_nvidia.go
new file mode 100644
index 000000000..cf53faace
--- /dev/null
+++ b/nodeadm/internal/containerd/runtime_config_nvidia.go
@@ -0,0 +1,35 @@
+package containerd
+
+import (
+	"os"
+
+	"github.com/awslabs/amazon-eks-ami/nodeadm/internal/api"
+	"go.uber.org/zap"
+)
+
+const (
+	nvidiaRuntimeName       = "nvidia"
+	nvidiaRuntimeBinaryPath = "/usr/bin/nvidia-container-runtime"
+)
+
+func NewNvidiaRuntimeConfigMixin() *nvidiaRuntimeConfigMixin {
+	return &nvidiaRuntimeConfigMixin{
+		runtimeBinaryPath: nvidiaRuntimeBinaryPath,
+	}
+}
+
+type nvidiaRuntimeConfigMixin struct {
+	runtimeBinaryPath string
+}
+
+func (m *nvidiaRuntimeConfigMixin) Matches(*api.NodeConfig) bool {
+	// TODO: use nodeconfig data to discern if necessary.
+	_, err := os.Stat(m.runtimeBinaryPath)
+	return err == nil
+}
+
+func (m *nvidiaRuntimeConfigMixin) Apply(opts *runtimeConfig) {
+	zap.L().Info("Configuring NVIDIA runtime..")
+	opts.RuntimeName = nvidiaRuntimeName
+	opts.RuntimeBinaryPath = m.runtimeBinaryPath
+}
diff --git a/nodeadm/internal/containerd/runtime_config_test.go b/nodeadm/internal/containerd/runtime_config_test.go
index 10d7f988b..6e0a37f96 100644
--- a/nodeadm/internal/containerd/runtime_config_test.go
+++ b/nodeadm/internal/containerd/runtime_config_test.go
@@ -1,31 +1,38 @@
 package containerd
 
 import (
-	"reflect"
+	"os"
+	"path/filepath"
 	"testing"
+
+	"github.com/awslabs/amazon-eks-ami/nodeadm/internal/api"
+	"github.com/stretchr/testify/assert"
 )
 
-func TestApplyInstanceTypeMixins(t *testing.T) {
-
-	var nvidiaExpectedOutput = instanceOptions{RuntimeName: "nvidia", RuntimeBinaryName: "/usr/bin/nvidia-container-runtime"}
-	var neuronExpectedOutput = instanceOptions{RuntimeName: "runc", RuntimeBinaryName: "/usr/sbin/runc"}
-	var nonAcceleratedExpectedOutput = instanceOptions{RuntimeName: "runc", RuntimeBinaryName: "/usr/sbin/runc"}
-
-	var tests = []struct {
-		name           string
-		instanceType   string
-		expectedOutput instanceOptions
-	}{
-		{name: "nvidia_test", instanceType: "p5.xlarge", expectedOutput: nvidiaExpectedOutput},
-		{name: "neuron_test", instanceType: "inf2.xlarge", expectedOutput: neuronExpectedOutput},
-		// non accelerated instance
-		{name: "non_accelerated_test", instanceType: "m5.xlarge", expectedOutput: nonAcceleratedExpectedOutput},
+func TestDefaultRuntimeOptions(t *testing.T) {
+	expectedRuntimeConfig := runtimeConfig{
+		RuntimeName:       defaultRuntimeName,
+		RuntimeBinaryPath: defaultRuntimeBinaryPath,
 	}
-	for _, test := range tests {
-		expected := applyInstanceTypeMixins(test.instanceType)
+	actualRuntimeConfig := getRuntimeOptions(&api.NodeConfig{})
+
+	assert.Equal(t, expectedRuntimeConfig, actualRuntimeConfig)
+}
 
-		if !reflect.DeepEqual(expected, test.expectedOutput) {
-			t.Fatalf("unexpected output in test case %s: %s, expecting: %s", test.name, expected, test.expectedOutput)
-		}
+func TestNvidiaRuntimeOptionsMixin(t *testing.T) {
+	mockNvidiaContainerRuntimePath := filepath.Join(t.TempDir(), "nvidia-container-runtime")
+	_, err := os.Create(mockNvidiaContainerRuntimePath)
+	assert.NoError(t, err)
+
+	mixin := nvidiaRuntimeConfigMixin{runtimeBinaryPath: mockNvidiaContainerRuntimePath}
+	expectedRuntimeConfig := runtimeConfig{
+		RuntimeName:       nvidiaRuntimeName,
+		RuntimeBinaryPath: mockNvidiaContainerRuntimePath,
 	}
+	assert.True(t, mixin.Matches(&api.NodeConfig{}))
+
+	var actualRuntimeConfig runtimeConfig
+	mixin.Apply(&actualRuntimeConfig)
+
+	assert.Equal(t, expectedRuntimeConfig, actualRuntimeConfig)
 }
diff --git a/nodeadm/test/e2e/cases/containerd-runtime-config-nvidia/run.sh b/nodeadm/test/e2e/cases/containerd-runtime-config-nvidia/run.sh
index 98ed4c2de..c16f9e1b4 100755
--- a/nodeadm/test/e2e/cases/containerd-runtime-config-nvidia/run.sh
+++ b/nodeadm/test/e2e/cases/containerd-runtime-config-nvidia/run.sh
@@ -10,6 +10,8 @@ mock::aws aemm-g5-config.json
 mock::kubelet 1.27.0
 wait::dbus-ready
 
+touch /usr/bin/nvidia-container-runtime
+
 nodeadm init --skip run --config-source file://config.yaml
 
 assert::files-equal /etc/containerd/config.toml expected-containerd-config.toml


Reviews:
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR configures the container runtime based on the presence of the Nvidia container runtime binary rather than instance type validation. Key changes include refactoring runtime options to use a mixin model, introducing a new Nvidia runtime configuration file, and adjusting tests and configuration writing to reflect these changes.

### Reviewed Changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated no comments.

<details>
<summary>Show a summary per file</summary>

| File                                                   | Description                                                             |
| ------------------------------------------------------ | ----------------------------------------------------------------------- |
| nodeadm/internal/containerd/runtime_config_test.go   | Updated tests to use a setup function with temporary environments.      |
| nodeadm/internal/containerd/runtime_config_nvidia.go | Introduced Nvidia runtime mixin that selects the binary via ENV override. |
| nodeadm/internal/containerd/runtime_config.go        | Refactored runtime configuration to use the new mixin approach.           |
| nodeadm/internal/containerd/daemon.go                | Added call to writeBaseRuntimeSpec in the Configure function.           |
| nodeadm/internal/containerd/config.go                | Removed redundant base runtime spec call; updated runtime option usage.   |
</details>


<details>
<summary>Files not reviewed (1)</summary>

* **nodeadm/test/e2e/cases/containerd-runtime-config-nvidia/run.sh**: Language not supported
</details>



state: COMMENTED
author_association: NONE
submitted_at: 2025-04-24T02:04:42Z
user: login: cartermckinnon
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-24T02:43:35Z
user: login: ndbaker1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-24T17:24:27Z
user: login: ndbaker1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-24T17:24:51Z
user: login: mselim00
body: lgtm, seems like a great way to get rid of a hardcoded list using a cheap call
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-30T22:03:44Z

Review comments:
diff_hunk: @@ -0,0 +1,39 @@
+package containerd
+
+import (
+	"os"
+
+	"github.com/awslabs/amazon-eks-ami/nodeadm/internal/api"
+	"go.uber.org/zap"
+)
+
+const (
+	nvidiaRuntimeName       = "nvidia"
+	nvidiaRuntimeBinaryPath = "/usr/bin/nvidia-container-runtime"
+)
+
+func NewNvidiaRuntimeConfigMixin() *nvidiaRuntimeConfigMixin {
+	runtimeOptionMixin := nvidiaRuntimeConfigMixin{
+		runtimeBinaryName: nvidiaRuntimeBinaryPath,
+	}
+	if binPath, ok := os.LookupEnv("NODEADM_NVIDIA_CONTAINER_RUNTIME_PATH"); ok {
+		runtimeOptionMixin.runtimeBinaryName = binPath
+	}
path: nodeadm/internal/containerd/runtime_config_nvidia.go
user: login: cartermckinnon
body: could you override `runtimeBinaryName` in your unit tests and avoid adding this fallback to prod?
created_at: 2025-04-24T02:12:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,65 +1,35 @@
 package containerd
 
-import (
-	"slices"
-	"strings"
+import "github.com/awslabs/amazon-eks-ami/nodeadm/internal/api"
 
-	"go.uber.org/zap"
-)
-
-type instanceOptions struct {
+type runtimeConfig struct {
 	RuntimeName       string
-	RuntimeBinaryName string
-}
-
-type instanceTypeMixin struct {
-	instanceFamilies []string
-	apply            func() instanceOptions
+	RuntimeBinaryPath string
 }
 
-func (m *instanceTypeMixin) matches(instanceType string) bool {
-	instanceFamily := strings.Split(instanceType, ".")[0]
-	return slices.Contains(m.instanceFamilies, instanceFamily)
+type runtimeConfigMixin interface {
+	Apply(*runtimeConfig)
+	Matches(*api.NodeConfig) bool
 }
 
-var (
-	// TODO: fetch this list dynamically
-	nvidiaInstances         = []string{"p3", "p3dn", "p4d", "p4de", "p5", "p5e", "p5en", "g4", "g4dn", "g5", "g6", "g6e", "g5g"}
-	NvidiaInstanceTypeMixin = instanceTypeMixin{
-		instanceFamilies: nvidiaInstances,
-		apply:            applyNvidia,
-	}
-
-	mixins = []instanceTypeMixin{
-		NvidiaInstanceTypeMixin,
-	}
+const (
+	defaultRuntimeName       = "runc"
+	defaultRuntimeBinaryPath = "/usr/sbin/runc"
 )
 
-const nvidiaRuntimeName = "nvidia"
-const nvidiaRuntimeBinaryName = "/usr/bin/nvidia-container-runtime"
-const defaultRuntimeName = "runc"
-const defaultRuntimeBinaryName = "/usr/sbin/runc"
-
-// applyInstanceTypeMixins adds the needed OCI hook options to containerd config.toml
-// based on the instance family
-func applyInstanceTypeMixins(instanceType string) instanceOptions {
-	for _, mixin := range mixins {
-		if mixin.matches(instanceType) {
-			return mixin.apply()
+// getRuntimeOptions adds the needed OCI hook options to containerd config.toml
+// based on the instance family and available runtime binaries
+func getRuntimeOptions(cfg *api.NodeConfig) runtimeConfig {
+	options := runtimeConfig{
+		RuntimeName:       defaultRuntimeName,
+		RuntimeBinaryPath: defaultRuntimeBinaryPath,
+	}
+	for _, mixin := range []runtimeConfigMixin{
+		NewNvidiaRuntimeConfigMixin(),
+	} {
path: nodeadm/internal/containerd/runtime_config.go
user: login: cartermckinnon
body: nit: would declare this []mixin at package scope
created_at: 2025-04-24T02:13:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,65 +1,35 @@
 package containerd
 
-import (
-	"slices"
-	"strings"
+import "github.com/awslabs/amazon-eks-ami/nodeadm/internal/api"
 
-	"go.uber.org/zap"
-)
-
-type instanceOptions struct {
+type runtimeConfig struct {
 	RuntimeName       string
-	RuntimeBinaryName string
-}
-
-type instanceTypeMixin struct {
-	instanceFamilies []string
-	apply            func() instanceOptions
+	RuntimeBinaryPath string
 }
 
-func (m *instanceTypeMixin) matches(instanceType string) bool {
-	instanceFamily := strings.Split(instanceType, ".")[0]
-	return slices.Contains(m.instanceFamilies, instanceFamily)
+type runtimeConfigMixin interface {
+	Apply(*runtimeConfig)
+	Matches(*api.NodeConfig) bool
 }
 
-var (
-	// TODO: fetch this list dynamically
-	nvidiaInstances         = []string{"p3", "p3dn", "p4d", "p4de", "p5", "p5e", "p5en", "g4", "g4dn", "g5", "g6", "g6e", "g5g"}
-	NvidiaInstanceTypeMixin = instanceTypeMixin{
-		instanceFamilies: nvidiaInstances,
-		apply:            applyNvidia,
-	}
-
-	mixins = []instanceTypeMixin{
-		NvidiaInstanceTypeMixin,
-	}
+const (
+	defaultRuntimeName       = "runc"
+	defaultRuntimeBinaryPath = "/usr/sbin/runc"
 )
 
-const nvidiaRuntimeName = "nvidia"
-const nvidiaRuntimeBinaryName = "/usr/bin/nvidia-container-runtime"
-const defaultRuntimeName = "runc"
-const defaultRuntimeBinaryName = "/usr/sbin/runc"
-
-// applyInstanceTypeMixins adds the needed OCI hook options to containerd config.toml
-// based on the instance family
-func applyInstanceTypeMixins(instanceType string) instanceOptions {
-	for _, mixin := range mixins {
-		if mixin.matches(instanceType) {
-			return mixin.apply()
+// getRuntimeOptions adds the needed OCI hook options to containerd config.toml
+// based on the instance family and available runtime binaries
+func getRuntimeOptions(cfg *api.NodeConfig) runtimeConfig {
+	options := runtimeConfig{
+		RuntimeName:       defaultRuntimeName,
+		RuntimeBinaryPath: defaultRuntimeBinaryPath,
+	}
+	for _, mixin := range []runtimeConfigMixin{
+		NewNvidiaRuntimeConfigMixin(),
+	} {
path: nodeadm/internal/containerd/runtime_config.go
user: login: ndbaker1
body: updated
created_at: 2025-04-24T17:24:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,39 @@
+package containerd
+
+import (
+	"os"
+
+	"github.com/awslabs/amazon-eks-ami/nodeadm/internal/api"
+	"go.uber.org/zap"
+)
+
+const (
+	nvidiaRuntimeName       = "nvidia"
+	nvidiaRuntimeBinaryPath = "/usr/bin/nvidia-container-runtime"
+)
+
+func NewNvidiaRuntimeConfigMixin() *nvidiaRuntimeConfigMixin {
+	runtimeOptionMixin := nvidiaRuntimeConfigMixin{
+		runtimeBinaryName: nvidiaRuntimeBinaryPath,
+	}
+	if binPath, ok := os.LookupEnv("NODEADM_NVIDIA_CONTAINER_RUNTIME_PATH"); ok {
+		runtimeOptionMixin.runtimeBinaryName = binPath
+	}
path: nodeadm/internal/containerd/runtime_config_nvidia.go
user: login: ndbaker1
body: sure, let me take this out and refactor the test
created_at: 2025-04-24T17:24:51Z
author_association: CONTRIBUTOR

PR comments:
user: login: ndbaker1
created_at: 2025-04-23T17:28:56Z
body: testing GPU AMI on non-GPU instance

/ci
+workflow:k8s_versions 1.32
+build enable_accelerator=nvidia enable_efa=true
+test --instance-types=m5.4xlarge
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-04-23T17:29:23Z
body: @ndbaker1 roger [that](https://github.com/awslabs/amazon-eks-ami/pull/2227#issuecomment-2825024917)! I've dispatched a [workflow](https://github.com/awslabs/amazon-eks-ami/actions/runs/14624351612). 👍
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-04-23T18:46:17Z
body: @ndbaker1 the <a href=https://github.com/awslabs/amazon-eks-ami/actions/runs/14624351612>workflow</a> that you <a href=https://github.com/awslabs/amazon-eks-ami/pull/2227#issuecomment-2825024917>requested</a> has completed. 🎉<table><tr><th>AMI variant</th><th>Build</th><th>Test</th></tr><tr><td>1.32 / al2023</td><td>success ✅</td><td>success ✅</td></tr></table>

author_association: CONTRIBUTOR
user: login: ndbaker1
created_at: 2025-04-23T20:18:43Z
body: test GPU types still work

/ci
+workflow:k8s_versions 1.32
+build enable_accelerator=nvidia enable_efa=true
+test --instance-types=g4dn.16xlarge
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-04-23T20:19:08Z
body: @ndbaker1 roger [that](https://github.com/awslabs/amazon-eks-ami/pull/2227#issuecomment-2825415179)! I've dispatched a [workflow](https://github.com/awslabs/amazon-eks-ami/actions/runs/14627312755). 👍
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-04-23T21:31:43Z
body: @ndbaker1 the <a href=https://github.com/awslabs/amazon-eks-ami/actions/runs/14627312755>workflow</a> that you <a href=https://github.com/awslabs/amazon-eks-ami/pull/2227#issuecomment-2825415179>requested</a> has completed. 🎉<table><tr><th>AMI variant</th><th>Build</th><th>Test</th></tr><tr><td>1.32 / al2023</td><td>success ✅</td><td>failure ❌</td></tr></table>

author_association: CONTRIBUTOR
user: login: ndbaker1
created_at: 2025-04-24T00:55:34Z
body: the capacity didn't launch

/ci
+workflow:k8s_versions 1.32
+build enable_accelerator=nvidia enable_efa=true
+test --instance-types=g4dn.xlarge,g4dn.2xlarge,g4dn.4xlarge,g4dn.8xlarge,g4dn.16xlarge
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-04-24T00:56:03Z
body: @ndbaker1 roger [that](https://github.com/awslabs/amazon-eks-ami/pull/2227#issuecomment-2825882861)! I've dispatched a [workflow](https://github.com/awslabs/amazon-eks-ami/actions/runs/14631060260). 👍
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-04-24T02:10:55Z
body: @ndbaker1 the <a href=https://github.com/awslabs/amazon-eks-ami/actions/runs/14631060260>workflow</a> that you <a href=https://github.com/awslabs/amazon-eks-ami/pull/2227#issuecomment-2825882861>requested</a> has completed. 🎉<table><tr><th>AMI variant</th><th>Build</th><th>Test</th></tr><tr><td>1.32 / al2023</td><td>success ✅</td><td>failure ❌</td></tr></table>

author_association: CONTRIBUTOR
user: login: ndbaker1
created_at: 2025-04-24T17:36:33Z
body: i was able to build and launch a `g4dn.xlarge` in my account with the args

```bash
make k8s=1.32 os_distro=al2023 enable_accelerator=nvidia enable_efa=true
```
author_association: CONTRIBUTOR
user: login: ndbaker1
created_at: 2025-04-30T21:08:23Z
body: increased ec2 limits first and retrying

/ci
+workflow:k8s_versions 1.32
+build enable_accelerator=nvidia enable_efa=true
+test --instance-types=g4dn.xlarge,g4dn.2xlarge,g4dn.4xlarge,g4dn.8xlarge,g4dn.16xlarge
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-04-30T21:08:58Z
body: @ndbaker1 roger [that](https://github.com/awslabs/amazon-eks-ami/pull/2227#issuecomment-2843286304)! I've dispatched a [workflow](https://github.com/awslabs/amazon-eks-ami/actions/runs/14764397846). 👍
author_association: CONTRIBUTOR
user: login: wwvela
created_at: 2025-04-30T22:19:32Z
body: saw the test has passed in latest ci https://github.com/awslabs/amazon-eks-ami/actions/runs/14764397846/job/41452518330. Should be good to merge.
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-04-30T22:25:34Z
body: @ndbaker1 the <a href=https://github.com/awslabs/amazon-eks-ami/actions/runs/14764397846>workflow</a> that you <a href=https://github.com/awslabs/amazon-eks-ami/pull/2227#issuecomment-2843286304>requested</a> has completed. 🎉<table><tr><th>AMI variant</th><th>Build</th><th>Test</th></tr><tr><td>1.32 / al2023</td><td>success ✅</td><td>success ✅</td></tr></table>

author_association: CONTRIBUTOR