Skip to content

[8.19] (backport #8035) Add Pipeline to deploy custom agent image for FIPS testing #8415

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 4 commits into from
Jun 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .buildkite/hooks/pre-command
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,8 @@ if [[ "$BUILDKITE_PIPELINE_SLUG" == "elastic-agent-binary-dra" ]]; then
release_manager_login
fi
fi

# BUILDKITE_PIPELINE_SLUG should match elastic-agent for PRs, and elastic-agent-extended-tests once it has merged to main
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 @@ -50,7 +55,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 @@ -979,6 +979,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 @@ -998,7 +1029,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 @@ -1007,7 +1051,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