Skip to content

Commit 1b7a4fa

Browse files
authored
ci(serverless): use OIDC for running the serverless ITs (#8263)
1 parent 1d79aa9 commit 1b7a4fa

File tree

4 files changed

+211
-25
lines changed

4 files changed

+211
-25
lines changed

.buildkite/bk.integration.pipeline.yml

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,31 @@ env:
1313
IMAGE_WIN_2022: "platform-ingest-elastic-agent-windows-2022-1749862860"
1414
IMAGE_WIN_2025: "platform-ingest-elastic-agent-windows-2025-1749862860"
1515

16+
# This section is used to define the plugins that will be used in the pipeline.
17+
# See https://buildkite.com/docs/pipelines/integrations/plugins/using#using-yaml-anchors-with-plugins
18+
common:
19+
- google_oidc_plugin: &google_oidc_plugin
20+
# See https://github.com/elastic/oblt-infra/blob/main/conf/resources/repos/elastic-agent/01-gcp-oidc.tf
21+
# This plugin authenticates to Google Cloud using the OIDC token.
22+
elastic/oblt-google-auth#v1.3.0:
23+
lifetime: 10800 # seconds
24+
project-id: "elastic-observability-ci"
25+
project-number: "911195782929"
26+
# see https://github.com/avaly/gcp-secret-manager-buildkite-plugin/pull/10
27+
# see https://github.com/avaly/gcp-secret-manager-buildkite-plugin/pull/11
28+
# - gcp_serverless_secrets_plugin: &gcp_serverless_secrets_plugin
29+
#avaly/gcp-secret-manager#v1.2.0:
30+
- gcp_serverless_secrets_plugin: &gcp_serverless_secrets_plugin
31+
elastic/gcp-secret-manager#v1.3.0-elastic:
32+
env:
33+
# These secrets are created in .github/workflows/serverless-project.yml
34+
ELASTICSEARCH_HOST: ea-serverless-it-elasticsearch-hostname
35+
ELASTICSEARCH_PASSWORD: ea-serverless-it-elasticsearch-password
36+
ELASTICSEARCH_USERNAME: ea-serverless-it-elasticsearch-username
37+
KIBANA_HOST: ea-serverless-it-kibana-hostname
38+
KIBANA_USERNAME: ea-serverless-it-kibana-username
39+
KIBANA_PASSWORD: ea-serverless-it-kibana-password
40+
1641
steps:
1742
- label: Start ESS stack for integration tests
1843
key: integration-ess
@@ -416,6 +441,76 @@ steps:
416441
- v1.32.0
417442
- v1.33.0
418443

444+
- group: "Serverless integration test"
445+
key: integration-tests-serverless
446+
notify:
447+
- github_commit_status:
448+
context: "buildkite/elastic-agent-extended-testing - Serverless integration test"
449+
steps:
450+
- label: "Windows:2022:amd64:sudo"
451+
depends_on:
452+
- packaging-windows
453+
env:
454+
TEST_PACKAGE: "github.com/elastic/elastic-agent/testing/integration/serverless"
455+
command: |
456+
buildkite-agent artifact download build/distributions/** . --step 'packaging-windows'
457+
.buildkite/scripts/buildkite-integration-tests.ps1 fleet true
458+
artifact_paths:
459+
- build/**
460+
- build/diagnostics/**
461+
retry:
462+
automatic:
463+
limit: 1
464+
agents:
465+
provider: "gcp"
466+
machineType: "n2-standard-8"
467+
image: "${IMAGE_WIN_2022}"
468+
plugins:
469+
- *google_oidc_plugin
470+
- *gcp_serverless_secrets_plugin
471+
472+
- label: "Windows:2025:amd64:sudo"
473+
depends_on:
474+
- packaging-windows
475+
env:
476+
TEST_PACKAGE: "github.com/elastic/elastic-agent/testing/integration/serverless"
477+
command: |
478+
buildkite-agent artifact download build/distributions/** . --step 'packaging-windows'
479+
.buildkite/scripts/buildkite-integration-tests.ps1 fleet true
480+
artifact_paths:
481+
- build/**
482+
- build/diagnostics/**
483+
retry:
484+
automatic:
485+
limit: 1
486+
agents:
487+
provider: "gcp"
488+
machineType: "n2-standard-8"
489+
image: "${IMAGE_WIN_2025}"
490+
plugins:
491+
- *google_oidc_plugin
492+
- *gcp_serverless_secrets_plugin
493+
- label: "Ubuntu:2404:amd64:sudo"
494+
depends_on: packaging-ubuntu-x86-64
495+
env:
496+
TEST_PACKAGE: "github.com/elastic/elastic-agent/testing/integration/serverless"
497+
command: |
498+
buildkite-agent artifact download build/distributions/** . --step 'packaging-ubuntu-x86-64'
499+
sudo -E .buildkite/scripts/buildkite-integration-tests.sh fleet true
500+
artifact_paths:
501+
- build/**
502+
- build/diagnostics/**
503+
retry:
504+
automatic:
505+
limit: 1
506+
agents:
507+
provider: "gcp"
508+
machineType: "n2-standard-8"
509+
image: "${IMAGE_UBUNTU_2404_X86_64}"
510+
plugins:
511+
- *google_oidc_plugin
512+
- *gcp_serverless_secrets_plugin
513+
419514
- label: ESS stack cleanup
420515
depends_on:
421516
- integration-tests-ubuntu
@@ -440,6 +535,7 @@ steps:
440535
- integration-tests-win
441536
- integration-tests-rhel8
442537
- integration-tests-kubernetes
538+
- integration-tests-serverless
443539
allow_dependency_failure: true
444540
command: |
445541
buildkite-agent artifact download "build/*.xml" .

.buildkite/integration.pipeline.yml

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -147,31 +147,6 @@ steps:
147147
imagePrefix: "core-ubuntu-2204-aarch64"
148148
diskSizeGb: 200
149149

150-
- label: "Serverless integration test"
151-
key: "serverless-integration-tests"
152-
depends_on:
153-
- int-packaging
154-
concurrency_group: elastic-agent-extended-testing/serverless-integration
155-
concurrency: 8
156-
env:
157-
# we run each step in a different data center to spread the load
158-
TEST_INTEG_AUTH_GCP_DATACENTER: "us-central1-a"
159-
command: |
160-
buildkite-agent artifact download "build/distributions/**" . $BUILDKITE_BUILD_ID
161-
.buildkite/scripts/steps/integration_tests.sh serverless integration:testServerless
162-
artifact_paths:
163-
- "build/TEST-**"
164-
- "build/diagnostics/*"
165-
agents:
166-
provider: "gcp"
167-
machineType: "n2-standard-8"
168-
retry:
169-
automatic:
170-
limit: 1
171-
notify:
172-
- github_commit_status:
173-
context: "buildkite/elastic-agent-extended-testing - Serverless integration test"
174-
175150
- label: "Triggering Integration tests"
176151
depends_on:
177152
- int-packaging
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
---
2+
name: serverless-project
3+
4+
on:
5+
workflow_dispatch:
6+
schedule:
7+
# To run more often if needed, for now daily at 4:00 UTC
8+
- cron: "0 4 * * *"
9+
10+
permissions:
11+
contents: read
12+
13+
jobs:
14+
create-serverless:
15+
permissions:
16+
id-token: write
17+
runs-on: ubuntu-latest
18+
env:
19+
PREFIX: "ea-serverless-it"
20+
steps:
21+
####################################
22+
# 1. Create the serverless project
23+
####################################
24+
- name: Get token
25+
id: get_token
26+
uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
27+
with:
28+
app_id: ${{ secrets.OBS_AUTOMATION_APP_ID }}
29+
private_key: ${{ secrets.OBS_AUTOMATION_APP_PEM }}
30+
permissions: >-
31+
{
32+
"checks": "read",
33+
"contents": "write",
34+
"pull_requests": "write"
35+
}
36+
repositories: >-
37+
["observability-test-environments"]
38+
39+
- uses: elastic/oblt-actions/git/setup@v1
40+
with:
41+
github-token: ${{ steps.get_token.outputs.token }}
42+
43+
- name: Get day of the week
44+
id: get_day
45+
run: echo "day=$(date +'%a' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
46+
47+
- uses: elastic/oblt-actions/oblt-cli/cluster-create-custom@v1
48+
id: create_serverless
49+
with:
50+
template: 'serverless-ea-it'
51+
parameters: '{"Target":"production","ProjectType":"observability"}'
52+
cluster-name-prefix: "${{ env.PREFIX }}-${{ steps.get_day.outputs.day }}"
53+
github-token: ${{ steps.get_token.outputs.token }}
54+
gitops: true
55+
wait: '15'
56+
57+
# Authenticate to the elastic-observability to get the cluster credentials
58+
- uses: elastic/oblt-actions/google/auth@v1
59+
60+
- uses: elastic/oblt-actions/oblt-cli/cluster-credentials@v1
61+
with:
62+
cluster-name: ${{ steps.create_serverless.outputs.cluster-name }}
63+
github-token: ${{ steps.get_token.outputs.token }}
64+
65+
- name: Smoke test
66+
run: curl -X GET ${ELASTICSEARCH_HOST}/_cat/indices?v -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}
67+
68+
####################################
69+
# 2. Copy the serverless secrets
70+
####################################
71+
# Authenticate to the elastic-observability-ci to rotate the cluster credentials
72+
- uses: elastic/oblt-actions/google/auth@v1
73+
with:
74+
project-number: "911195782929"
75+
project-id: "elastic-observability-ci"
76+
77+
- name: Set up Cloud SDK
78+
uses: google-github-actions/setup-gcloud@77e7a554d41e2ee56fc945c52dfd3f33d12def9a
79+
80+
# TODO: as soon as the oblt-framework supports elastic-observability-ci we can avoid this step.
81+
# NOTE:
82+
# * While runnning this workflow, it might cause some hiccups if a PR runs when rotating the secrets
83+
# * Secrets need to be created firstly. gcloud secrets create otherwise gcloud secrets versions add will fail.
84+
# That's not an issue now, as we use the same secret name.
85+
- name: Rotate GCSM secrets
86+
env:
87+
GCP_PROJECT: "elastic-observability-ci"
88+
run: |
89+
echo -n "${ELASTICSEARCH_HOST}" | gcloud secrets versions add "${PREFIX}-elasticsearch-hostname" --data-file=- --quiet --project "${GCP_PROJECT}"
90+
echo -n "${ELASTICSEARCH_PASSWORD}" | gcloud secrets versions add "${PREFIX}-elasticsearch-password" --data-file=- --quiet --project "${GCP_PROJECT}"
91+
echo -n "${ELASTICSEARCH_USERNAME}" | gcloud secrets versions add "${PREFIX}-elasticsearch-username" --data-file=- --quiet --project "${GCP_PROJECT}"
92+
echo -n "${KIBANA_HOST}" | gcloud secrets versions add "${PREFIX}-kibana-hostname" --data-file=- --quiet --project "${GCP_PROJECT}"
93+
echo -n "${KIBANA_USERNAME}" | gcloud secrets versions add "${PREFIX}-kibana-username" --data-file=- --quiet --project "${GCP_PROJECT}"
94+
echo -n "${KIBANA_PASSWORD}" | gcloud secrets versions add "${PREFIX}-kibana-password" --data-file=- --quiet --project "${GCP_PROJECT}"
95+
96+
# TODO: if rotation fails then rollback to the previous cluster.
97+
- if: ${{ failure() }}
98+
uses: elastic/oblt-actions/slack/send@v1
99+
env:
100+
JOB_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
101+
with:
102+
bot-token: ${{ secrets.SLACK_BOT_TOKEN }}
103+
channel-id: "#ingest-notifications"
104+
message: ":traffic_cone: serverless project creation failed for `${{ github.repository }}@${{ github.ref_name }}`, `@robots-ci` please look what's going on <${{ env.JOB_URL }}|here>"

docs/test-framework-dev-guide.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@ The Elastic Agent package that is used for integration tests packages Beats buil
2828
ESS (production) API Key to create on <https://cloud.elastic.co/account/keys>
2929
Warning: if you never created a deployment on it, you won't have permission to get this key, so you will need to create one first.
3030

31+
32+
#### Setup Serverless deployment
33+
34+
This process is now automated and runs daily, utilizing the existing `oblt-cli` framework. Serverless deployments are created each day and automatically destroyed every three days.
35+
36+
The automation is configured in the `serverless-project.yml` file located in the `.github/workflows` directory.
37+
38+
If necessary, you can create a new serverless deployment manually; the previous deployments will be destroyed automatically, but not immediately. To do so, you need to run the GitHub action called [serverless-project.yml](https://github.com/elastic/elastic-agent/actions/workflows/serverless-project.yml).
39+
40+
Credentials for these deployments are securely stored in Google and can only be accessed by Buildkite pipelines. The access control is set using [OpenID Connect in Google Cloud Platform](https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-google-cloud-platform). And that's managed by the Robots team.
41+
3142
## Running tests
3243

3344
Some integration and E2E tests are safe to run locally. These tests set

0 commit comments

Comments
 (0)