Skip to content

Commit cea0d41

Browse files
authored
Run SSI e2e tests on Amazon EKS in addition to Kind (#47143)
### What does this PR do? Adds support for running SSI e2e tests on Amazon EKS, in addition to the existing Kind provisioner. Key changes: - Introduces `E2E_PROVISIONER` parameter to select the Kubernetes provisioner (`kind`, `kind-local`, `eks`) - Adds `WithAgentDependentWorkloadApp` to the EKS scenario to ensure workloads are deployed after the Datadog agent, which guarantees the admission webhook is ready before pod creation - Splits the `new-e2e-ssi` CI job into `new-e2e-ssi-kind` and `new-e2e-ssi-eks` to run tests on both platforms ### Motivation https://datadoghq.atlassian.net/browse/INPLAT-917 Testing on EKS provides confidence that the admission controller injection works correctly in a real managed Kubernetes environment, not just in Kind clusters. ### Describe how you validated your changes - Ran the SSI test suite with `E2E_PROVISIONER=eks` ### Additional Notes `WithAgentDependentWorkloadApp` was already implemented in the kind provisioners Co-authored-by: luc.vieillescazes <luc.vieillescazes@datadoghq.com>
1 parent ce383dc commit cea0d41

File tree

8 files changed

+175
-35
lines changed

8 files changed

+175
-35
lines changed

.gitlab/test/e2e/e2e.yml

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,7 @@ new-e2e-otel:
939939
TEAM: otel
940940
ON_NIGHTLY_FIPS: "true"
941941

942-
new-e2e-ssi:
942+
.new-e2e_ssi:
943943
extends: .new_e2e_template
944944
rules:
945945
- !reference [.on_ssi_or_e2e_changes]
@@ -952,6 +952,59 @@ new-e2e-ssi:
952952
TARGETS: ./tests/ssi
953953
TEAM: injection-platform
954954

955+
.new-e2e_ssi_extra_distribution_init:
956+
stage: e2e_init
957+
extends: .new_e2e_template
958+
needs:
959+
- go_e2e_deps
960+
- go_tools_deps
961+
rules:
962+
- !reference [.on_e2e_main_release_or_rc]
963+
- changes:
964+
paths:
965+
- test/new-e2e/tests/ssi/**/*
966+
compare_to: $COMPARE_TO_BRANCH
967+
- !reference [.manual]
968+
variables:
969+
TARGETS: ./tests/ssi
970+
TEAM: injection-platform
971+
E2E_INIT_ONLY: "true"
972+
SHOULD_RUN_IN_FLAKES_FINDER: "false"
973+
allow_failure: true
974+
retry: !reference [.retry_only_infra_failure, retry]
975+
976+
.new-e2e_ssi_extra_distribution:
977+
extends: .new-e2e_ssi
978+
rules:
979+
- !reference [.on_e2e_main_release_or_rc]
980+
- changes:
981+
paths:
982+
- test/new-e2e/tests/ssi/**/*
983+
compare_to: $COMPARE_TO_BRANCH
984+
- !reference [.manual]
985+
986+
new-e2e-ssi-kind:
987+
extends: .new-e2e_ssi
988+
variables:
989+
E2E_PROVISIONER: kind
990+
E2E_STACK_NAME_SUFFIX: kind
991+
992+
new-e2e-ssi-eks-init:
993+
extends: .new-e2e_ssi_extra_distribution_init
994+
variables:
995+
E2E_PROVISIONER: eks
996+
E2E_STACK_NAME_SUFFIX: eks
997+
998+
new-e2e-ssi-eks:
999+
extends: .new-e2e_ssi_extra_distribution
1000+
needs:
1001+
- !reference [.new-e2e_ssi_extra_distribution, needs]
1002+
- new-e2e-ssi-eks-init
1003+
variables:
1004+
E2E_PROVISIONER: eks
1005+
E2E_STACK_NAME_SUFFIX: eks
1006+
E2E_PRE_INITIALIZED: "true"
1007+
9551008
.new-e2e_package_signing:
9561009
variables:
9571010
TARGETS: ./tests/agent-platform/package-signing

test/e2e-framework/scenarios/aws/eks/run.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,5 +204,15 @@ func RunWithEnv(ctx *pulumi.Context, awsEnv resourcesAws.Environment, env output
204204
return err
205205
}
206206
}
207+
208+
// Deploy workloads that must wait for the agent.
209+
if dependsOnDDAgent != nil {
210+
for _, appFunc := range params.depWorkloadAppFuncs {
211+
_, err := appFunc(&awsEnv, cluster.KubeProvider, dependsOnDDAgent)
212+
if err != nil {
213+
return err
214+
}
215+
}
216+
}
207217
return nil
208218
}

test/e2e-framework/scenarios/aws/eks/run_args.go

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,17 @@ const (
2626

2727
// RunParams collects high-level scenario parameters for the EKS scenario.
2828
type RunParams struct {
29-
Name string
30-
vmOptions []ec2.VMOption
31-
agentOptions []kubernetesagentparams.Option
32-
fakeintakeOptions []fakeintake.Option
33-
eksOptions []Option
34-
extraConfigParams runner.ConfigMap
35-
workloadAppFuncs []kubecomp.WorkloadAppFunc
36-
operatorOptions []operatorparams.Option
37-
operatorDDAOptions []agentwithoperatorparams.Option
38-
ciliumOptions []cilium.Option
29+
Name string
30+
vmOptions []ec2.VMOption
31+
agentOptions []kubernetesagentparams.Option
32+
fakeintakeOptions []fakeintake.Option
33+
eksOptions []Option
34+
extraConfigParams runner.ConfigMap
35+
workloadAppFuncs []kubecomp.WorkloadAppFunc
36+
depWorkloadAppFuncs []kubecomp.AgentDependentWorkloadAppFunc
37+
operatorOptions []operatorparams.Option
38+
operatorDDAOptions []agentwithoperatorparams.Option
39+
ciliumOptions []cilium.Option
3940

4041
eksLinuxNodeGroup bool
4142
eksLinuxARMNodeGroup bool
@@ -52,16 +53,17 @@ type RunOption = func(*RunParams) error
5253

5354
func GetRunParams(opts ...RunOption) *RunParams {
5455
params := &RunParams{
55-
Name: defaultEKSName,
56-
vmOptions: []ec2.VMOption{},
57-
agentOptions: []kubernetesagentparams.Option{},
58-
fakeintakeOptions: []fakeintake.Option{},
59-
eksOptions: []Option{},
60-
extraConfigParams: runner.ConfigMap{},
61-
workloadAppFuncs: []kubecomp.WorkloadAppFunc{},
62-
operatorOptions: []operatorparams.Option{},
63-
operatorDDAOptions: []agentwithoperatorparams.Option{},
64-
ciliumOptions: []cilium.Option{},
56+
Name: defaultEKSName,
57+
vmOptions: []ec2.VMOption{},
58+
agentOptions: []kubernetesagentparams.Option{},
59+
fakeintakeOptions: []fakeintake.Option{},
60+
eksOptions: []Option{},
61+
extraConfigParams: runner.ConfigMap{},
62+
workloadAppFuncs: []kubecomp.WorkloadAppFunc{},
63+
depWorkloadAppFuncs: []kubecomp.AgentDependentWorkloadAppFunc{},
64+
operatorOptions: []operatorparams.Option{},
65+
operatorDDAOptions: []agentwithoperatorparams.Option{},
66+
ciliumOptions: []cilium.Option{},
6567
}
6668
err := optional.ApplyOptions(params, opts)
6769
if err != nil {
@@ -190,6 +192,14 @@ func WithWorkloadApp(appFunc kubecomp.WorkloadAppFunc) RunOption {
190192
}
191193
}
192194

195+
// WithAgentDependentWorkloadApp adds a workload app that depends on the agent being deployed first.
196+
func WithAgentDependentWorkloadApp(appFunc kubecomp.AgentDependentWorkloadAppFunc) RunOption {
197+
return func(params *RunParams) error {
198+
params.depWorkloadAppFuncs = append(params.depWorkloadAppFuncs, appFunc)
199+
return nil
200+
}
201+
}
202+
193203
// WithAwsEnv asks the provisioner to use the given environment, it is created otherwise
194204
func WithAwsEnv(env *aws.Environment) RunOption {
195205
return func(params *RunParams) error {

test/e2e-framework/scenarios/aws/kindvm/run.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ func RunWithEnv(ctx *pulumi.Context, awsEnv resAws.Environment, env outputs.Kube
114114
return err
115115
}
116116

117+
// If InitOnly is set, return after creating the cluster.
118+
if awsEnv.InitOnly() {
119+
return nil
120+
}
121+
117122
kubeProvider, err := kubernetes.NewProvider(ctx, awsEnv.Namer.ResourceName("k8s-provider"), &kubernetes.ProviderArgs{
118123
EnableServerSideApply: pulumi.Bool(true),
119124
Kubeconfig: kindCluster.KubeConfig,

test/e2e-framework/testing/runner/parameters/const.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ const (
6969
DevMode StoreKey = "dev_mode"
7070
// DevLocal uses local Kind cluster instead of AWS for faster development
7171
DevLocal StoreKey = "dev_local"
72+
// Provisioner specifies the Kubernetes provisioner to use (e.g., "kind", "kind-local", "eks").
73+
// Not all tests honor this parameter.
74+
Provisioner StoreKey = "provisioner"
7275
// InitOnly config flag parameter name
7376
InitOnly StoreKey = "init_only"
7477
// TeardownOnly config flag parameter name

test/e2e-framework/testing/runner/parameters/store_config_file.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,16 @@ type Config struct {
3636

3737
// ConfigParams instance contains config relayed parameters
3838
type ConfigParams struct {
39-
AWS AWS `yaml:"aws"`
40-
Azure Azure `yaml:"azure"`
41-
GCP GCP `yaml:"gcp"`
42-
Local Local `yaml:"local"`
43-
Agent Agent `yaml:"agent"`
44-
OutputDir string `yaml:"outputDir"`
45-
Pulumi Pulumi `yaml:"pulumi"`
46-
DevMode string `yaml:"devMode"`
47-
DevLocal string `yaml:"devLocal"`
39+
AWS AWS `yaml:"aws"`
40+
Azure Azure `yaml:"azure"`
41+
GCP GCP `yaml:"gcp"`
42+
Local Local `yaml:"local"`
43+
Agent Agent `yaml:"agent"`
44+
OutputDir string `yaml:"outputDir"`
45+
Pulumi Pulumi `yaml:"pulumi"`
46+
DevMode string `yaml:"devMode"`
47+
DevLocal string `yaml:"devLocal"`
48+
Provisioner string `yaml:"provisioner"`
4849
}
4950

5051
// AWS instance contains AWS related parameters
@@ -203,6 +204,8 @@ func (s configFileValueStore) get(key StoreKey) (string, error) {
203204
value = s.config.ConfigParams.DevMode
204205
case DevLocal:
205206
value = s.config.ConfigParams.DevLocal
207+
case Provisioner:
208+
value = s.config.ConfigParams.Provisioner
206209
}
207210

208211
if value == "" {

test/e2e-framework/testing/runner/parameters/store_env.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,15 @@ var envVariablesByStoreKey = map[StoreKey]string{
4242
PulumiVerboseProgressStreams: "E2E_PULUMI_VERBOSE_PROGRESS_STREAMS",
4343
DevMode: "E2E_DEV_MODE",
4444
DevLocal: "E2E_DEV_LOCAL",
45+
Provisioner: "E2E_PROVISIONER",
4546
InitOnly: "E2E_INIT_ONLY",
4647
TeardownOnly: "E2E_TEARDOWN_ONLY",
4748
MajorVersion: "E2E_MAJOR_VERSION",
4849
PreInitialized: "E2E_PRE_INITIALIZED",
4950
FIPS: "E2E_FIPS",
5051
CoveragePipeline: "E2E_COVERAGE_PIPELINE",
5152
CoverageOutDir: "E2E_COVERAGE_OUT_DIR",
53+
StackNameSuffix: "E2E_STACK_NAME_SUFFIX",
5254
SkipWindows: "E2E_SKIP_WINDOWS",
5355
}
5456

test/new-e2e/tests/ssi/provisioner.go

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,67 @@
66
package ssi
77

88
import (
9+
"strings"
10+
911
"github.com/DataDog/datadog-agent/test/e2e-framework/components/datadog/kubernetesagentparams"
1012
kubeComp "github.com/DataDog/datadog-agent/test/e2e-framework/components/kubernetes"
13+
scenarioeks "github.com/DataDog/datadog-agent/test/e2e-framework/scenarios/aws/eks"
1114
"github.com/DataDog/datadog-agent/test/e2e-framework/scenarios/aws/kindvm"
1215
"github.com/DataDog/datadog-agent/test/e2e-framework/testing/environments"
1316
"github.com/DataDog/datadog-agent/test/e2e-framework/testing/provisioners"
17+
proveks "github.com/DataDog/datadog-agent/test/e2e-framework/testing/provisioners/aws/kubernetes/eks"
1418
provkindvm "github.com/DataDog/datadog-agent/test/e2e-framework/testing/provisioners/aws/kubernetes/kindvm"
1519
localkind "github.com/DataDog/datadog-agent/test/e2e-framework/testing/provisioners/local/kubernetes"
1620
"github.com/DataDog/datadog-agent/test/e2e-framework/testing/runner"
1721
"github.com/DataDog/datadog-agent/test/e2e-framework/testing/runner/parameters"
1822
)
1923

24+
// ProvisionerType represents the type of Kubernetes provisioner to use.
25+
type ProvisionerType string
26+
27+
const (
28+
// ProvisionerKindAWS uses Kind running on an AWS VM (default).
29+
ProvisionerKindAWS ProvisionerType = "kind"
30+
// ProvisionerKindLocal uses Kind running locally.
31+
ProvisionerKindLocal ProvisionerType = "kind-local"
32+
// ProvisionerEKS uses Amazon EKS.
33+
ProvisionerEKS ProvisionerType = "eks"
34+
)
35+
2036
// ProvisionerOptions contains the common options for Kubernetes provisioners.
2137
type ProvisionerOptions struct {
2238
AgentOptions []kubernetesagentparams.Option
2339
WorkloadAppFunc kubeComp.WorkloadAppFunc
2440
AgentDependentWorkloadAppFunc kubeComp.AgentDependentWorkloadAppFunc
2541
}
2642

27-
// Provisioner returns a Kubernetes provisioner based on E2E_DEV_LOCAL parameter.
28-
// If E2E_DEV_LOCAL=true, returns a local Kind provisioner for faster development.
29-
// Otherwise, returns an AWS Kind VM provisioner.
43+
// Provisioner returns a Kubernetes provisioner based on E2E_PROVISIONER and E2E_DEV_LOCAL parameters.
44+
// Supported provisioners: "kind" (default), "kind-local", "eks".
45+
// E2E_DEV_LOCAL=true is a shortcut for E2E_PROVISIONER=kind-local.
3046
func Provisioner(opts ProvisionerOptions) provisioners.TypedProvisioner[environments.Kubernetes] {
31-
if isLocalMode() {
47+
provisionerType := getProvisionerType()
48+
switch provisionerType {
49+
case ProvisionerKindLocal:
3250
return localKindProvisioner(opts)
51+
case ProvisionerEKS:
52+
return eksProvisioner(opts)
53+
default:
54+
return awsKindProvisioner(opts)
55+
}
56+
}
57+
58+
// getProvisionerType returns the provisioner type from E2E_PROVISIONER parameter or E2E_DEV_LOCAL.
59+
func getProvisionerType() ProvisionerType {
60+
// Check E2E_PROVISIONER first (via env var or config file).
61+
provisioner, err := runner.GetProfile().ParamStore().GetWithDefault(parameters.Provisioner, "")
62+
if err == nil && provisioner != "" {
63+
return ProvisionerType(strings.ToLower(provisioner))
64+
}
65+
// Fall back to E2E_DEV_LOCAL for backward compatibility.
66+
if isLocalMode() {
67+
return ProvisionerKindLocal
3368
}
34-
return awsKindProvisioner(opts)
69+
return ProvisionerKindAWS
3570
}
3671

3772
// isLocalMode returns true if E2E_DEV_LOCAL is set to "true" (via env var or config file)
@@ -72,3 +107,22 @@ func awsKindProvisioner(opts ProvisionerOptions) provisioners.TypedProvisioner[e
72107
}
73108
return provkindvm.Provisioner(provkindvm.WithRunOptions(runOpts...))
74109
}
110+
111+
// eksProvisioner returns an Amazon EKS provisioner.
112+
func eksProvisioner(opts ProvisionerOptions) provisioners.TypedProvisioner[environments.Kubernetes] {
113+
var runOpts []scenarioeks.RunOption
114+
115+
// Add a Linux node group by default.
116+
runOpts = append(runOpts, scenarioeks.WithEKSOptions(scenarioeks.WithLinuxNodeGroup()))
117+
118+
if len(opts.AgentOptions) > 0 {
119+
runOpts = append(runOpts, scenarioeks.WithAgentOptions(opts.AgentOptions...))
120+
}
121+
if opts.WorkloadAppFunc != nil {
122+
runOpts = append(runOpts, scenarioeks.WithWorkloadApp(opts.WorkloadAppFunc))
123+
}
124+
if opts.AgentDependentWorkloadAppFunc != nil {
125+
runOpts = append(runOpts, scenarioeks.WithAgentDependentWorkloadApp(opts.AgentDependentWorkloadAppFunc))
126+
}
127+
return proveks.Provisioner(proveks.WithRunOptions(runOpts...))
128+
}

0 commit comments

Comments
 (0)