Skip to content

Add Pipeline to deploy custom agent image for FIPS testing #8035

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 60 commits into from
Jun 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
ea416ea
Add Pipeline to deploy custom agent image for FIPS testing
michel-laterman Apr 29, 2025
c9d4023
Add new pipeline as triggered step
michel-laterman Apr 29, 2025
f8d343b
Use normal bk agent
michel-laterman Apr 29, 2025
46ec87a
Add bk agent provider and machinetype
michel-laterman May 1, 2025
cd7f72a
Add FIPS support to cloud:push
michel-laterman May 1, 2025
3ae5f92
Fix magefile
michel-laterman May 1, 2025
b84b803
Merge branch 'main' into fips-ech
michel-laterman May 1, 2025
838cdbd
Push image to beats-ci, add docker login hook
michel-laterman May 6, 2025
7515f8f
Fix pipeline
michel-laterman May 6, 2025
8ad48a3
Add FIPS env check to buildkite-integration-tests.sh
michel-laterman May 6, 2025
0ace521
Remove integration.fips addition
michel-laterman May 7, 2025
005746a
Merge branch 'main' into fips-ech
michel-laterman May 7, 2025
bd6119d
Fix label names
michel-laterman May 7, 2025
85ae7fa
revert change to integration tests
michel-laterman May 8, 2025
11b8ada
Pass FIPS
michel-laterman May 8, 2025
3ddecb1
Merge branch 'main' into fips-ech
michel-laterman May 9, 2025
775bd58
Add integration test with FIPS: true in requirements
michel-laterman May 9, 2025
5fb8569
Remove extra test
michel-laterman May 9, 2025
bb16fc7
Merge branch 'main' into fips-ech
michel-laterman May 9, 2025
9800591
Review feedback
michel-laterman May 9, 2025
6ee1fde
Change to k8s testing 9.1.0, change to running test on aws FIPS enabl…
michel-laterman May 9, 2025
878203f
Use ARM fips image
michel-laterman May 21, 2025
628f05d
Merge branch 'main' into fips-ech
michel-laterman May 21, 2025
68cc3cb
Fix pipeline
michel-laterman May 21, 2025
74c7e0f
Merge branch 'main' into fips-ech
michel-laterman May 22, 2025
cd6c00a
Change to using imagePrefix for all images
michel-laterman May 26, 2025
6f5dcfa
Remove FIPS k8s tests
michel-laterman May 27, 2025
86621bb
Remove -integration.fips arg so standard tests run
michel-laterman May 27, 2025
88900f8
Remove go from .tool-versions
michel-laterman May 28, 2025
2e8f6a7
Reuse docker image from package step
michel-laterman May 28, 2025
f4f947b
Remove env tag from cloud:import
michel-laterman May 28, 2025
a96f408
Add verbosity to cloud import and push
michel-laterman May 28, 2025
6eb8a2f
Change from image import to image load
michel-laterman May 29, 2025
769ccf7
Use fully qualified images for buildkite
michel-laterman Jun 2, 2025
3530c3c
Check for msft/go, fix fips test
michel-laterman Jun 2, 2025
f74a82a
Fix var name
michel-laterman Jun 2, 2025
4fd6902
Update fips bk images
michel-laterman Jun 2, 2025
796b4e4
Merge branch 'main' into fips-ech
michel-laterman Jun 2, 2025
35c33f2
Remove additional logging
michel-laterman Jun 2, 2025
dc3a78d
fix passing integration.fips, define TF_VAR as pipeline variable
michel-laterman Jun 2, 2025
3e6575a
imageName -> image
michel-laterman Jun 2, 2025
0889b8a
Change test requirement order, remove extra groups
michel-laterman Jun 2, 2025
4ae0723
Add log line to failing test
michel-laterman Jun 2, 2025
2fef8eb
Apply suggestions from code review
michel-laterman Jun 3, 2025
95dc6bb
Add comments for dependencies
michel-laterman Jun 3, 2025
2debfd2
Merge remote-tracking branch 'origin/main' into fips-ech
michel-laterman Jun 3, 2025
6381a61
step specific env vars
michel-laterman Jun 4, 2025
d90d974
Fix TF var
michel-laterman Jun 4, 2025
362b17e
comment out agentStatus from test
michel-laterman Jun 5, 2025
c0be6f9
Update pipelines
michel-laterman Jun 5, 2025
074832a
Merge branch 'main' into fips-ech
michel-laterman Jun 5, 2025
c3bfadd
Update .buildkite/bk.integration-fips.pipeline.yml
michel-laterman Jun 5, 2025
afb5d73
Merge branch 'main' into fips-ech
michel-laterman Jun 5, 2025
8f6ff7a
Update .buildkite/bk.integration-fips.pipeline.yml
michel-laterman Jun 5, 2025
645c8b6
Merge branch 'main' into fips-ech
michel-laterman Jun 5, 2025
33647be
Merge branch 'main' into fips-ech
michel-laterman Jun 6, 2025
19ebf48
Change bk instance where image is pushed
michel-laterman Jun 6, 2025
a2c3227
Update bk images, add to automation
michel-laterman Jun 9, 2025
59fa434
Merge branch 'main' into fips-ech
michel-laterman Jun 9, 2025
4ef376f
Remove key for aggregate-reports-fips
michel-laterman Jun 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions .buildkite/bk.integration-fips.pipeline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/buildkite/pipeline-schema/main/schema.json

env:
DOCKER_REGISTRY: "docker.elastic.co"
ASDF_MAGE_VERSION: 1.14.0

IMAGE_UBUNTU_2404_X86_64: "platform-ingest-elastic-agent-ubuntu-2404-1749258065"
IMAGE_UBUNTU_X86_64_FIPS: "platform-ingest-elastic-agent-ubuntu-2204-fips-1748955449"
IMAGE_UBUNTU_ARM64_FIPS: "platform-ingest-elastic-agent-ubuntu-2204-fips-aarch64-1748955449"

steps:
- label: Build and push custom elastic-agent image
depends_on:
- 'packaging-containers-x86-64-fips' # Reuse artifacts produced in .buildkite/integration.pipeline.yml
key: integration-fips-cloud-image
env:
FIPS: "true"
CUSTOM_IMAGE_TAG: "git-${BUILDKITE_COMMIT:0:12}"
CI_ELASTIC_AGENT_DOCKER_IMAGE: "docker.elastic.co/beats-ci/elastic-agent-fips-cloud"
TF_VAR_integration_server_docker_image: "docker.elastic.co/beats-ci/elastic-agent-fips-cloud:git-${BUILDKITE_COMMIT:0:12}"
command: |
buildkite-agent artifact download build/distributions/elastic-agent-fips-cloud-*-linux-amd64.docker.tar.gz . --step 'packaging-containers-x86-64-fips'
mage cloud:load
mage cloud:push
agents:
provider: "gcp"
machineType: "n1-standard-8"
image: "${IMAGE_UBUNTU_2404_X86_64}"

- label: Start ESS stack for FIPS integration tests
key: integration-fips-ess
depends_on:
- integration-fips-cloud-image
env:
ASDF_TERRAFORM_VERSION: 1.9.2
CUSTOM_IMAGE_TAG: "git-${BUILDKITE_COMMIT:0:12}"
CI_ELASTIC_AGENT_DOCKER_IMAGE: "docker.elastic.co/beats-ci/elastic-agent-fips-cloud"
TF_VAR_integration_server_docker_image: "docker.elastic.co/beats-ci/elastic-agent-fips-cloud:git-${BUILDKITE_COMMIT:0:12}"
command: |
source .buildkite/scripts/steps/ess_start.sh
artifact_paths:
- test_infra/ess/*.tfstate
- test_infra/ess/*.lock.hcl
agents:
image: "docker.elastic.co/ci-agent-images/platform-ingest/buildkite-agent-beats-ci-with-hooks:0.5"
useCustomGlobalHooks: true

- group: "fips:Stateful:Ubuntu"
key: integration-tests-ubuntu-fips
depends_on:
- integration-fips-ess
steps:
- label: "fips:x86_64:sudo-{{matrix.sudo}}:{{matrix.groups}}"
depends_on:
- packaging-ubuntu-x86-64-fips # Reuse artifacts produced in .buildkite/integration.pipeline.yml
env:
FIPS: "true"
CUSTOM_IMAGE_TAG: "git-${BUILDKITE_COMMIT:0:12}"
CI_ELASTIC_AGENT_DOCKER_IMAGE: "docker.elastic.co/beats-ci/elastic-agent-fips-cloud"
TF_VAR_integration_server_docker_image: "docker.elastic.co/beats-ci/elastic-agent-fips-cloud:git-${BUILDKITE_COMMIT:0:12}"
command: |
buildkite-agent artifact download build/distributions/** . --step 'packaging-ubuntu-x86-64-fips'
.buildkite/scripts/steps/integration_tests_tf.sh {{matrix.groups}} {{matrix.sudo}}
artifact_paths:
- build/**
- build/diagnostics/**
retry:
automatic:
limit: 1
agents:
provider: "aws"
image: "${IMAGE_UBUNTU_X86_64_FIPS}"
instanceType: "m5.2xlarge"
matrix:
setup:
sudo:
- "false"
- "true"
groups:
- fleet # currently there is only a single test in the fleet group, add more tests once they have been defined

- label: "fips:arm64:sudo-{{matrix.sudo}}:{{matrix.groups}}"
depends_on:
- packaging-ubuntu-arm64-fips
env:
FIPS: "true"
CUSTOM_IMAGE_TAG: "git-${BUILDKITE_COMMIT:0:12}"
CI_ELASTIC_AGENT_DOCKER_IMAGE: "docker.elastic.co/beats-ci/elastic-agent-fips-cloud"
TF_VAR_integration_server_docker_image: "docker.elastic.co/beats-ci/elastic-agent-fips-cloud:git-${BUILDKITE_COMMIT:0:12}"
command: |
buildkite-agent artifact download build/distributions/** . --step 'packaging-ubuntu-arm64-fips'
.buildkite/scripts/steps/integration_tests_tf.sh {{matrix.groups}} {{matrix.sudo}}
artifact_paths:
- build/**
- build/diagnostics/**
retry:
automatic:
limit: 1
agents:
provider: "aws"
image: "${IMAGE_UBUNTU_ARM64_FIPS}"
instanceType: "m6g.2xlarge"
matrix:
setup:
sudo:
- "false"
- "true"
groups:
- fleet

- label: ESS FIPS stack cleanup
depends_on:
- integration-tests-ubuntu-fips
allow_dependency_failure: true
command: |
buildkite-agent artifact download "test_infra/ess/**" . --step "integration-fips-ess"
ls -lah test_infra/ess
.buildkite/scripts/steps/ess_down.sh
agents:
image: "docker.elastic.co/ci-agent-images/platform-ingest/buildkite-agent-beats-ci-with-hooks:0.5"
useCustomGlobalHooks: true

- label: Aggregate test reports
depends_on:
- integration-tests-ubuntu-fips
allow_dependency_failure: true
command: |
buildkite-agent artifact download "build/*.xml" .
agents:
image: "docker.elastic.co/ci-agent-images/platform-ingest/buildkite-agent-beats-ci-with-hooks:0.5"
useCustomGlobalHooks: true
soft_fail:
- exit_status: "*"
plugins:
- elastic/vault-secrets#v0.1.0:
path: "kv/ci-shared/platform-ingest/buildkite_analytics_token"
field: "token"
env_var: "BUILDKITE_ANALYTICS_TOKEN"
- test-collector#v1.11.0:
files: "build/*.xml"
format: "junit"
branches: "main"
debug: true
4 changes: 4 additions & 0 deletions .buildkite/hooks/pre-command
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,7 @@ if [[ "$BUILDKITE_PIPELINE_SLUG" == "elastic-agent-binary-dra" ]]; then
release_manager_login
fi
fi

if [[ "$BUILDKITE_PIPELINE_SLUG" == "elastic-agent" && "$BUILDKITE_STEP_KEY" == "integration-fips-cloud-image" ]]; then
docker_login
fi
5 changes: 5 additions & 0 deletions .buildkite/integration.pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,8 @@ steps:
depends_on:
- int-packaging
command: "buildkite-agent pipeline upload .buildkite/bk.integration.pipeline.yml"

- label: "Triggering custom FIPS integration tests"
depends_on:
- int-packaging
command: "buildkite-agent pipeline upload .buildkite/bk.integration-fips.pipeline.yml"
7 changes: 6 additions & 1 deletion .buildkite/scripts/buildkite-integration-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ if [ -z "$TEST_SUDO" ]; then
exit 1
fi

if [ "${FIPS:-false}" == "true" ]; then
echo "~~~FIPS: Checking msft-go is installed"
GOEXPERIMENT=systemcrypto go version
fi

if [ "$TEST_SUDO" == "true" ]; then
echo "Re-initializing ASDF. The user is changed to root..."
export ASDF_DATA_DIR="/opt/buildkite-agent/.asdf"
Expand Down Expand Up @@ -51,7 +56,7 @@ GOTEST_ARGS=(-tags integration -test.shuffle on -test.timeout 2h0m0s)
if [ -n "$TEST_NAME_PATTERN" ]; then
GOTEST_ARGS+=(-run="${TEST_NAME_PATTERN}")
fi
GOTEST_ARGS+=("github.com/elastic/elastic-agent/testing/integration" -v -args "-integration.groups=${GROUP_NAME}" "-integration.sudo=${TEST_SUDO}")
GOTEST_ARGS+=("github.com/elastic/elastic-agent/testing/integration" -v -args "-integration.groups=${GROUP_NAME}" "-integration.sudo=${TEST_SUDO}" "-integration.fips=${FIPS:-false}")

set +e
TEST_BINARY_NAME="elastic-agent" AGENT_VERSION="${AGENT_VERSION}" SNAPSHOT=true \
Expand Down
10 changes: 10 additions & 0 deletions .ci/updatecli/updatecli-bump-vm-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,13 @@ targets:
file: .buildkite/bk.integration.pipeline.yml
matchpattern: '(IMAGE_.+): "platform-ingest-elastic-agent-(.+)-(.+)"'
replacepattern: '$1: "platform-ingest-elastic-agent-$2-{{ source "latestVersion" }}"'

update-buildkite-bk.integration-fips.pipeline:
name: "Update .buildkite/bk.integration-fips.pipeline.yml"
sourceid: latestVersion
scmid: githubConfig
kind: file
spec:
file: .buildkite/bk.integration-fips.pipeline.yml
matchpattern: '(IMAGE_.+): "platform-ingest-elastic-agent-(.+)-(.+)"'
replacepattern: '$1: "platform-ingest-elastic-agent-$2-{{ source "latestVersion" }}"'
1 change: 0 additions & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
mage 1.14.0
golang 1.24.0
terraform 1.9.3
46 changes: 45 additions & 1 deletion magefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,37 @@ func (Cloud) Image(ctx context.Context) {
Package(ctx)
}

// Load loads an artifact as a docker image.
// Looks in build/distributions for an elastic-agent-cloud*.docker.tar.gz artifact and imports it as docker.elastic.co/beats-ci/elastic-agent-cloud:$VERSION
// DOCKER_IMPORT_SOURCE - override source for import
func (Cloud) Load() error {
snapshot := os.Getenv(snapshotEnv)
defer os.Setenv(snapshotEnv, snapshot)
os.Setenv(snapshotEnv, "true")

version := getVersion()

// Need to get the FIPS env var flag to see if we are using the normal source cloud image name, or the FIPS variant
fips := os.Getenv(fipsEnv)
defer os.Setenv(fipsEnv, fips)
fipsVal, err := strconv.ParseBool(fips)
if err != nil {
fipsVal = false
}
os.Setenv(fipsEnv, strconv.FormatBool(fipsVal))
devtools.FIPSBuild = fipsVal

source := "build/distributions/elastic-agent-cloud-" + version + "-linux-" + runtime.GOARCH + ".docker.tar.gz"
if fipsVal {
source = "build/distributions/elastic-agent-fips-cloud-" + version + "-linux-" + runtime.GOARCH + ".docker.tar.gz"
}
if envSource, ok := os.LookupEnv("DOCKER_IMPORT_SOURCE"); ok && envSource != "" {
source = envSource
}

return sh.RunV("docker", "image", "load", "-i", source)
}

// Push builds a cloud image tags it correctly and pushes to remote image repo.
// Previous login to elastic registry is required!
func (Cloud) Push() error {
Expand All @@ -1003,7 +1034,20 @@ func (Cloud) Push() error {
tag = fmt.Sprintf("%s-%s-%d", version, commit, time)
}

// Need to get the FIPS env var flag to see if we are using the normal source cloud image name, or the FIPS variant
fips := os.Getenv(fipsEnv)
defer os.Setenv(fipsEnv, fips)
fipsVal, err := strconv.ParseBool(fips)
if err != nil {
fipsVal = false
}
os.Setenv(fipsEnv, strconv.FormatBool(fipsVal))
devtools.FIPSBuild = fipsVal

sourceCloudImageName := fmt.Sprintf("docker.elastic.co/beats-ci/elastic-agent-cloud:%s", version)
if fipsVal {
sourceCloudImageName = fmt.Sprintf("docker.elastic.co/beats-ci/elastic-agent-fips-cloud:%s", version)
}
var targetCloudImageName string
if customImage, isPresent := os.LookupEnv("CI_ELASTIC_AGENT_DOCKER_IMAGE"); isPresent && len(customImage) > 0 {
targetCloudImageName = fmt.Sprintf("%s:%s", customImage, tag)
Expand All @@ -1012,7 +1056,7 @@ func (Cloud) Push() error {
}

fmt.Printf(">> Setting a docker image tag to %s\n", targetCloudImageName)
err := sh.RunV("docker", "tag", sourceCloudImageName, targetCloudImageName)
err = sh.RunV("docker", "tag", sourceCloudImageName, targetCloudImageName)
if err != nil {
return fmt.Errorf("Failed setting a docker image tag: %w", err)
}
Expand Down
18 changes: 10 additions & 8 deletions testing/integration/fleetserver_fips_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import (
"encoding/json"
"net/http"
"net/url"
"os"
"testing"
"time"

"github.com/stretchr/testify/require"

"github.com/elastic/elastic-agent-libs/kibana"
"github.com/elastic/elastic-agent/pkg/testing/define"
"github.com/elastic/elastic-agent/pkg/testing/tools/fleettools"
)

const cloudAgentPolicyID = "policy-elastic-agent-on-cloud"
Expand All @@ -42,8 +42,8 @@ func TestFIPSAgentConnectingToFIPSFleetServerInECHFRH(t *testing.T) {
FIPS: true,
})

// Check that the Fleet Server in the deployment is healthy
fleetServerHost := os.Getenv("INTEGRATIONS_SERVER_HOST")
fleetServerHost, err := fleettools.DefaultURL(t.Context(), info.KibanaClient)
require.NoError(t, err)
statusUrl, err := url.JoinPath(fleetServerHost, "/api/status")
require.NoError(t, err)

Expand All @@ -59,28 +59,30 @@ func TestFIPSAgentConnectingToFIPSFleetServerInECHFRH(t *testing.T) {
err = decoder.Decode(&body)
require.NoError(t, err)

require.Equal(t, "HEALTHY", body.Status)
require.Equalf(t, "HEALTHY", body.Status, "response status code: %d", resp.StatusCode)

// Get all Agents
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
ctx, cancel := context.WithTimeout(t.Context(), 5*time.Second)
defer cancel()
agents, err := info.KibanaClient.ListAgents(ctx, kibana.ListAgentsRequest{})
require.NoError(t, err)

// Find Fleet Server's own Agent and get its status and whether it's
// FIPS-capable
var agentStatus string
//var agentStatus string
var agentIsFIPS bool
for _, item := range agents.Items {
if item.PolicyID == cloudAgentPolicyID {
agentStatus = item.Status
t.Logf("Found fleet-server entry: %+v", item)
//agentStatus = item.Status
agentIsFIPS = item.LocalMetadata.Elastic.Agent.FIPS
break
}
}

// Check that this Agent is online (i.e. healthy) and is FIPS-capable. This
// will prove that a FIPS-capable Agent is able to connect to a FIPS-capable
// Fleet Server, with both running in ECH.
require.Equal(t, "online", agentStatus)
require.Equal(t, true, agentIsFIPS)
//require.Equal(t, "online", agentStatus) // FIXME: Uncomment after https://github.com/elastic/apm-server/issues/17063 is resolved
}