diff --git a/.ci/scripts/push-pgo-pr.sh b/.ci/scripts/push-pgo-pr.sh new file mode 100755 index 0000000000..93366424c7 --- /dev/null +++ b/.ci/scripts/push-pgo-pr.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -eo pipefail + +PGO_BRANCH="update-pgo-$(date +%s)" +cd $WORKSPACE_PATH +git fetch origin main +git checkout main +git checkout -b $PGO_BRANCH +mv $PROFILE_PATH x-pack/apm-server/default.pgo +git add x-pack/apm-server/default.pgo +git commit -m "PGO: Update default.pgo from benchmarks $WORKFLOW." +git push -u origin $PGO_BRANCH +gh pr create -B main -H $PGO_BRANCH -t "PGO: Update default.pgo" -b "Update default.pgo CPU profile from the benchmarks [workflow]($WORKFLOW)." -R elastic/apm-server +gh pr merge --auto --delete-branch --squash $PGO_BRANCH \ No newline at end of file diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index eda117cdc7..bdf4e14faf 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -3,6 +3,11 @@ name: benchmarks on: workflow_dispatch: inputs: + runStandalone: + description: 'Run the benchmarks against standalone APM Server with Moxy' + required: false + type: boolean + default: false profile: description: 'The system profile used to run the benchmarks' required: false @@ -21,10 +26,12 @@ on: required: false type: string schedule: - - cron: '0 17 * * *' + - cron: '0 17 * * *' # Scheduled regular benchmarks. + - cron: '0 5 */5 * *' # Scheduled PGO benchmarks. env: PNG_REPORT_FILE: out.png + BENCHMARK_CPU_OUT: default.pgo BENCHMARK_RESULT: benchmark-result.txt WORKING_DIRECTORY: testing/benchmark @@ -38,12 +45,13 @@ jobs: run: working-directory: ${{ env.WORKING_DIRECTORY }} permissions: - contents: read + contents: write id-token: write env: SSH_KEY: ./id_rsa_terraform TF_VAR_private_key: ./id_rsa_terraform TF_VAR_public_key: ./id_rsa_terraform.pub + RUN_STANDALONE: ${{ inputs.runStandalone || github.event.schedule=='0 5 */5 * *' }} TFVARS_SOURCE: ${{ inputs.profile || 'system-profiles/8GBx1zone.tfvars' }} # // Default to use an 8gb profile TF_VAR_BUILD_ID: ${{ github.run_id }} TF_VAR_ENVIRONMENT: ci @@ -101,28 +109,48 @@ jobs: terraform_version: 1.3.7 terraform_wrapper: false + - name: Init terraform module + id: init + run: make init + - name: Build apmbench run: make apmbench $SSH_KEY terraform.tfvars + - name: Build APM Server and Moxy + if: ${{ env.RUN_STANDALONE == 'true' }} + run: | + make apm-server + make moxy + - name: Override docker committed version - if: ${{ ! inputs.runOnStable }} + if: ${{ ! inputs.runOnStable && env.RUN_STANDALONE == 'false' }} run: make docker-override-committed-version - name: Spin up benchmark environment id: deploy run: | - make init apply + make apply admin_console_url=$(terraform output -raw admin_console_url) echo "admin_console_url=$admin_console_url" >> "$GITHUB_OUTPUT" echo "-> infra setup done" + env: + TF_VAR_worker_region: ${{ env.AWS_REGION }} + TF_VAR_run_standalone: ${{ env.RUN_STANDALONE }} - name: Run benchmarks autotuned if: ${{ inputs.benchmarkAgents == '' }} - run: make run-benchmark-autotuned index-benchmark-results + run: make run-benchmark-autotuned - name: Run benchmarks self tuned if: ${{ inputs.benchmarkAgents != '' }} - run: make run-benchmark index-benchmark-results + run: make run-benchmark + + - name: Cat standalone server logs + if: ${{ env.RUN_STANDALONE == 'true' && failure() }} + run: make cat-apm-server-logs + + - name: Index benchmarks result + run: make index-benchmark-results - name: Download PNG run: >- @@ -150,15 +178,65 @@ jobs: - name: Upload benchmark result uses: actions/upload-artifact@v4 - if: always() with: name: benchmark-result path: ${{ env.WORKING_DIRECTORY }}/${{ env.BENCHMARK_RESULT }} if-no-files-found: error + # The next section injects CPU profile collected by apmbench into the build. + # By copying the profile, uploading it to the artifacts and pushing it + # via a PR to update default.pgo. + + - name: Copy CPU profile + run: make cp-cpuprof + + - name: Upload CPU profile + uses: actions/upload-artifact@v4 + with: + name: cpu-profile + path: ${{ env.WORKING_DIRECTORY }}/${{ env.BENCHMARK_CPU_OUT }} + if-no-files-found: error + + - name: Get token + id: get_token + uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0 + with: + app_id: ${{ secrets.OBS_AUTOMATION_APP_ID }} + private_key: ${{ secrets.OBS_AUTOMATION_APP_PEM }} + permissions: >- + { + "contents": "write", + "pull_requests": "write" + } + + # Required to use a service account, otherwise PRs created by + # GitHub bot won't trigger any CI builds. + # See https://github.com/peter-evans/create-pull-request/issues/48#issuecomment-537478081 + - name: Configure git user + uses: elastic/oblt-actions/git/setup@v1 + with: + github-token: ${{ steps.get_token.outputs.token }} + + - name: Import GPG key + uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0 + with: + gpg_private_key: ${{ secrets.APM_SERVER_RELEASE_GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.APM_SERVER_RELEASE_PASSPHRASE }} + git_user_signingkey: true + git_commit_gpgsign: true + + - name: Open PGO PR + if: ${{ env.RUN_STANDALONE == 'true' && github.ref == 'refs/heads/main' }} + run: ${{ github.workspace }}/.ci/scripts/push-pgo-pr.sh + env: + WORKSPACE_PATH: ${{ github.workspace }} + PROFILE_PATH: ${{ env.WORKING_DIRECTORY }}/${{ env.BENCHMARK_CPU_OUT }} + GITHUB_TOKEN: ${{ steps.get_token.outputs.token }} + WORKFLOW: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }} + - name: Tear down benchmark environment if: always() - run: make destroy + run: make init destroy # Notify failure to Slack only on schedule (nightly run) - if: failure() && github.event_name == 'schedule' diff --git a/systemtest/benchtest/profiles.go b/systemtest/benchtest/profiles.go index 9e2ee89b43..e3dd240df4 100644 --- a/systemtest/benchtest/profiles.go +++ b/systemtest/benchtest/profiles.go @@ -88,7 +88,7 @@ func (p *profiles) recordCPU() error { if benchConfig.CPUProfile == "" { return nil } - duration := 2 * benchConfig.Benchtime + duration := benchConfig.Benchtime profile, err := fetchProfile("/debug/pprof/profile", duration) if err != nil { return fmt.Errorf("failed to fetch CPU profile: %w", err) diff --git a/testing/benchmark/Makefile b/testing/benchmark/Makefile index cf894325b5..3344de04c0 100644 --- a/testing/benchmark/Makefile +++ b/testing/benchmark/Makefile @@ -2,6 +2,12 @@ APMBENCH_PATH ?= ../../systemtest/cmd/apmbench APMBENCH_GOOS ?= linux APMBENCH_GOARCH ?= amd64 +MOXY_GOOS ?= linux +MOXY_GOARCH ?= amd64 + +APM_SERVER_GOOS ?= linux +APM_SERVER_GOARCH ?= amd64 + TFVARS_SOURCE ?= terraform.tfvars.example BENCHMARK_WARMUP_TIME ?= 5m @@ -23,6 +29,8 @@ SSH_USER ?= ec2-user SSH_OPTS ?= -o LogLevel=ERROR -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=10 SSH_KEY ?= ~/.ssh/id_rsa_terraform WORKER_IP = $(shell terraform output -raw public_ip) +APM_SERVER_IP = $(shell terraform output -raw apm_server_ip) +RUN_STANDALONE = $(shell echo var.run_standalone | terraform console | tr -d '"') SHELL = /bin/bash .SHELLFLAGS = -o pipefail -c @@ -67,6 +75,15 @@ apmbench: @echo "-> Building apmbench..." @cd $(APMBENCH_PATH) && CGO_ENABLED=0 GOOS=$(APMBENCH_GOOS) GOARCH=$(APMBENCH_GOARCH) go build . +.PHONY: moxy +moxy: + @echo "-> Building moxy..." + @cd ../../tools && CGO_ENABLED=0 GOOS=$(MOXY_GOOS) GOARCH=$(MOXY_GOARCH) go build -o "../build" github.com/elastic/apm-perf/cmd/moxy + +.PHONY: apm-server +apm-server: + @cd ../.. && make build/apm-server-$(APM_SERVER_GOOS)-$(APM_SERVER_GOARCH) && mv build/apm-server-$(APM_SERVER_GOOS)-$(APM_SERVER_GOARCH) build/apm-server + .PHONY: init init: @terraform init @@ -110,6 +127,12 @@ index-benchmark-results: _default-gobench-vars .PHONY: _default-gobench-vars _default-gobench-vars: +ifeq ($(RUN_STANDALONE),true) + $(eval GOBENCH_DEFAULT_TAGS = $(GOBENCH_DEFAULT_TAGS),apm_server_size=$(shell echo var.standalone_apm_server_instance_size | terraform console | tr -d '"')) + $(eval GOBENCH_DEFAULT_TAGS = $(GOBENCH_DEFAULT_TAGS),moxy_size=$(shell echo var.standalone_moxy_instance_size | terraform console | tr -d '"')) + $(eval GOBENCH_DEFAULT_TAGS = $(GOBENCH_DEFAULT_TAGS),build_sha=$(shell git rev-parse HEAD)) + $(eval GOBENCH_DEFAULT_TAGS = $(GOBENCH_DEFAULT_TAGS),bench_mode=standalone) +else # TODO(marclop) Update code below to use a foor loop, rather than copying the lines. $(eval GOBENCH_DEFAULT_TAGS = $(GOBENCH_DEFAULT_TAGS),apm_server_size=$(shell echo var.apm_server_size | terraform console | tr -d '"')) $(eval GOBENCH_DEFAULT_TAGS = $(GOBENCH_DEFAULT_TAGS),elasticsearch_size=$(shell echo var.elasticsearch_size | terraform console | tr -d '"')) @@ -117,6 +140,12 @@ _default-gobench-vars: $(eval GOBENCH_DEFAULT_TAGS = $(GOBENCH_DEFAULT_TAGS),apm_server_zone_count=$(shell echo var.apm_server_zone_count | terraform console | tr -d '"')) $(eval GOBENCH_DEFAULT_TAGS = $(GOBENCH_DEFAULT_TAGS),elasticsearch_zone_count=$(shell echo var.elasticsearch_zone_count | terraform console | tr -d '"')) $(eval GOBENCH_DEFAULT_TAGS = $(GOBENCH_DEFAULT_TAGS),build_sha=$(shell curl -sL -H "Authorization: Bearer $(shell terraform output -raw apm_secret_token )" $(shell terraform output -raw apm_server_url ) | jq -r '.build_sha')) + $(eval GOBENCH_DEFAULT_TAGS = $(GOBENCH_DEFAULT_TAGS),bench_mode=cloud) +endif + +.PHONY: cat-apm-server-logs +cat-apm-server-logs: + @ssh $(SSH_OPTS) -i $(SSH_KEY) $(SSH_USER)@$(APM_SERVER_IP) "cat /var/log/apm-server/*" $(SSH_KEY): @ssh-keygen -t rsa -b 4096 -C "$(USER)@elastic.co" -N "" -f $(SSH_KEY) @@ -172,4 +201,4 @@ elastic_agent_docker_image: build_elastic_agent_docker_image build_elastic_agent_docker_image: @env BASE_IMAGE=${ELASTIC_AGENT_DOCKER_IMAGE}:${ELASTIC_AGENT_IMAGE_TAG} GOARCH=amd64 \ bash ${REPO_ROOT}/testing/docker/elastic-agent/build.sh \ - -t ${CI_ELASTIC_AGENT_DOCKER_IMAGE}:${CUSTOM_IMAGE_TAG} + -t ${CI_ELASTIC_AGENT_DOCKER_IMAGE}:${CUSTOM_IMAGE_TAG} \ No newline at end of file diff --git a/testing/benchmark/README.md b/testing/benchmark/README.md index ab2f89c6aa..c3cf50297e 100644 --- a/testing/benchmark/README.md +++ b/testing/benchmark/README.md @@ -89,7 +89,7 @@ overridden automatically, you need to remove it manually if present. #### Override docker image tag It is possible to override the tag of the docker image that is run in the remote ESS deployment. You can -specify any of the avilable tags (such as `8.3.0-SNAPSHOT` or a more specific tag `8.3.0-c655cda8-SNAPSHOT`). +specify any of the available tags (such as `8.3.0-SNAPSHOT` or a more specific tag `8.3.0-c655cda8-SNAPSHOT`). Alternatively, you can run `make docker-override-committed-version` in your shell, to have use the committed tags in the `docker-compose.yml` file in the repository root. diff --git a/testing/benchmark/main.tf b/testing/benchmark/main.tf index e699f56485..4b888e7a78 100644 --- a/testing/benchmark/main.tf +++ b/testing/benchmark/main.tf @@ -45,7 +45,46 @@ locals { name_prefix = "${coalesce(var.user_name, "unknown-user")}-bench" } +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "3.14.0" + + name = "${var.user_name}-worker" + cidr = var.vpc_cidr + + azs = ["${var.worker_region}a"] + public_subnets = var.public_cidr + enable_ipv6 = false + enable_nat_gateway = false + single_nat_gateway = false + + manage_default_security_group = true + default_security_group_ingress = [ + { + "from_port" : 0, + "to_port" : 0, + "protocol" : -1, + "self" : true, + "cidr_blocks" : "0.0.0.0/0", + } + ] + default_security_group_egress = [ + { + "from_port" : 0, + "to_port" : 0, + "protocol" : -1, + "cidr_blocks" : "0.0.0.0/0", + } + ] + + tags = merge(local.ci_tags, module.tags.tags) + vpc_tags = { + Name = "vpc-${var.user_name}-worker" + } +} + module "ec_deployment" { + count = var.run_standalone ? 0 : 1 source = "../infra/terraform/modules/ec_deployment" region = var.ess_region @@ -73,12 +112,13 @@ module "ec_deployment" { module "benchmark_worker" { source = "../infra/terraform/modules/benchmark_executor" - region = var.worker_region + vpc_id = module.vpc.vpc_id + region = var.worker_region user_name = var.user_name - apm_server_url = module.ec_deployment.apm_url - apm_secret_token = module.ec_deployment.apm_secret_token + apm_server_url = var.run_standalone ? module.standalone_apm_server[0].apm_server_url : module.ec_deployment[0].apm_url + apm_secret_token = var.run_standalone ? module.standalone_apm_server[0].apm_secret_token : module.ec_deployment[0].apm_secret_token apmbench_bin_path = var.apmbench_bin_path instance_type = var.worker_instance_type @@ -86,5 +126,41 @@ module "benchmark_worker" { public_key = var.public_key private_key = var.private_key - tags = merge(local.ci_tags, module.tags.tags) + tags = merge(local.ci_tags, module.tags.tags) + depends_on = [module.standalone_apm_server, module.ec_deployment] +} + +module "moxy" { + count = var.run_standalone ? 1 : 0 + source = "../infra/terraform/modules/moxy" + + vpc_id = module.vpc.vpc_id + instance_type = var.standalone_moxy_instance_size + moxy_bin_path = var.moxy_bin_path + + aws_provisioner_key_name = var.private_key + + tags = merge(local.ci_tags, module.tags.tags) + depends_on = [module.vpc] +} + + +module "standalone_apm_server" { + count = var.run_standalone ? 1 : 0 + source = "../infra/terraform/modules/standalone_apm_server" + + vpc_id = module.vpc.vpc_id + aws_os = "amzn2-ami-hvm-*-x86_64-ebs" + apm_instance_type = var.standalone_apm_server_instance_size + apm_server_bin_path = var.apm_server_bin_path + ea_managed = false + + aws_provisioner_key_name = var.private_key + + elasticsearch_url = module.moxy[0].moxy_url + elasticsearch_username = "elastic" + elasticsearch_password = module.moxy[0].moxy_password + + tags = merge(local.ci_tags, module.tags.tags) + depends_on = [module.moxy] } diff --git a/testing/benchmark/outputs.tf b/testing/benchmark/outputs.tf index 371d9c4376..2cad799412 100644 --- a/testing/benchmark/outputs.tf +++ b/testing/benchmark/outputs.tf @@ -4,38 +4,45 @@ output "public_ip" { } output "elasticsearch_url" { - value = module.ec_deployment.elasticsearch_url + value = var.run_standalone ? module.moxy[0].moxy_url : module.ec_deployment[0].elasticsearch_url description = "The secure Elasticsearch URL" } output "elasticsearch_username" { - value = module.ec_deployment.elasticsearch_username + value = var.run_standalone ? "elastic" : module.ec_deployment[0].elasticsearch_username description = "The Elasticsearch username" sensitive = true } output "elasticsearch_password" { - value = module.ec_deployment.elasticsearch_password + value = var.run_standalone ? module.moxy[0].moxy_password : module.ec_deployment[0].elasticsearch_password description = "The Elasticsearch password" sensitive = true } output "kibana_url" { - value = module.ec_deployment.kibana_url + value = var.run_standalone ? "" : module.ec_deployment[0].kibana_url description = "The secure Kibana URL" } + output "apm_secret_token" { - value = module.ec_deployment.apm_secret_token + value = var.run_standalone ? module.standalone_apm_server[0].apm_secret_token : module.ec_deployment[0].apm_secret_token description = "The APM Server secret token" sensitive = true } output "apm_server_url" { - value = module.ec_deployment.apm_url + value = var.run_standalone ? module.standalone_apm_server[0].apm_server_url : module.ec_deployment[0].apm_url description = "The APM Server URL" + sensitive = true +} + +output "apm_server_ip" { + value = var.run_standalone ? module.standalone_apm_server[0].apm_server_ip : "" + description = "The APM Server EC2 IP address" } output "admin_console_url" { - value = module.ec_deployment.admin_console_url + value = var.run_standalone ? "" : module.ec_deployment[0].admin_console_url description = "The admin console URL" } diff --git a/testing/benchmark/system-profiles/16GBx2zone.tfvars b/testing/benchmark/system-profiles/16GBx2zone.tfvars index d081604f33..84da1c4878 100644 --- a/testing/benchmark/system-profiles/16GBx2zone.tfvars +++ b/testing/benchmark/system-profiles/16GBx2zone.tfvars @@ -1,5 +1,11 @@ user_name = "USER" +# APM bench + +worker_instance_type = "c6i.2xlarge" + +# Elastic Cloud + # The number of AZs the APM Server should span. apm_server_zone_count = 1 # The Elasticsearch cluster node size. @@ -10,5 +16,8 @@ elasticsearch_zone_count = 2 apm_server_size = "16g" # Number of shards for the ES indices apm_shards = 4 -# Benchmarks executor size executor -worker_instance_type = "c6i.2xlarge" + +# Standalone + +standalone_apm_server_instance_size = "c6i.2xlarge" +standalone_moxy_instance_size = "c6i.4xlarge" diff --git a/testing/benchmark/system-profiles/1GBx1zone.tfvars b/testing/benchmark/system-profiles/1GBx1zone.tfvars index a2ca3dac00..8b1ff546e6 100644 --- a/testing/benchmark/system-profiles/1GBx1zone.tfvars +++ b/testing/benchmark/system-profiles/1GBx1zone.tfvars @@ -1,5 +1,11 @@ user_name = "USER" +# APM bench + +worker_instance_type = "c6i.large" + +# Elastic Cloud + # The number of AZs the APM Server should span. apm_server_zone_count = 1 # The Elasticsearch cluster node size. @@ -8,3 +14,8 @@ elasticsearch_size = "16g" elasticsearch_zone_count = 2 # APM server instance size apm_server_size = "1g" + +# Standalone + +standalone_apm_server_instance_size = "c6i.large" +standalone_moxy_instance_size = "c6i.xlarge" diff --git a/testing/benchmark/system-profiles/2GBx1zone.tfvars b/testing/benchmark/system-profiles/2GBx1zone.tfvars index 668f12f9ed..a3114b4b98 100644 --- a/testing/benchmark/system-profiles/2GBx1zone.tfvars +++ b/testing/benchmark/system-profiles/2GBx1zone.tfvars @@ -1,5 +1,11 @@ user_name = "USER" +# APM bench + +worker_instance_type = "c6i.large" + +# Elastic Cloud + # The number of AZs the APM Server should span. apm_server_zone_count = 1 # The Elasticsearch cluster node size. @@ -7,4 +13,9 @@ elasticsearch_size = "16g" # The number of AZs the Elasticsearch cluster should have. elasticsearch_zone_count = 2 # APM server instance size -apm_server_size = "2g" \ No newline at end of file +apm_server_size = "2g" + +# Standalone + +standalone_apm_server_instance_size = "c6i.large" +standalone_moxy_instance_size = "c6i.xlarge" diff --git a/testing/benchmark/system-profiles/32GBx2zone.tfvars b/testing/benchmark/system-profiles/32GBx2zone.tfvars index 10a9180257..67cc51afc2 100644 --- a/testing/benchmark/system-profiles/32GBx2zone.tfvars +++ b/testing/benchmark/system-profiles/32GBx2zone.tfvars @@ -1,5 +1,11 @@ user_name = "USER" +# APM bench + +worker_instance_type = "c6i.2xlarge" + +# Elastic Cloud + # The number of AZs the APM Server should span. apm_server_zone_count = 1 # The Elasticsearch cluster node size. @@ -12,5 +18,8 @@ elasticsearch_dedicated_masters = true apm_server_size = "32g" # Number of shards for the ES indices apm_shards = 4 -# Benchmarks executor size executor -worker_instance_type = "c6i.2xlarge" + +# Standalone + +standalone_apm_server_instance_size = "c6i.4xlarge" +standalone_moxy_instance_size = "c6i.8xlarge" diff --git a/testing/benchmark/system-profiles/4GBx1zone.tfvars b/testing/benchmark/system-profiles/4GBx1zone.tfvars index f55f909944..3ffda6cdc3 100644 --- a/testing/benchmark/system-profiles/4GBx1zone.tfvars +++ b/testing/benchmark/system-profiles/4GBx1zone.tfvars @@ -1,5 +1,11 @@ user_name = "USER" +# APM bench + +worker_instance_type = "c6i.large" + +# Elastic Cloud + # The number of AZs the APM Server should span. apm_server_zone_count = 1 # The Elasticsearch cluster node size. @@ -7,4 +13,9 @@ elasticsearch_size = "32g" # The number of AZs the Elasticsearch cluster should have. elasticsearch_zone_count = 2 # APM server instance size -apm_server_size = "4g" \ No newline at end of file +apm_server_size = "4g" + +# Standalone + +standalone_apm_server_instance_size = "c6i.large" +standalone_moxy_instance_size = "c6i.xlarge" diff --git a/testing/benchmark/system-profiles/8GBx1zone.tfvars b/testing/benchmark/system-profiles/8GBx1zone.tfvars index 62719a89b1..b3b42e7440 100644 --- a/testing/benchmark/system-profiles/8GBx1zone.tfvars +++ b/testing/benchmark/system-profiles/8GBx1zone.tfvars @@ -1,5 +1,11 @@ user_name = "USER" +# APM bench + +worker_instance_type = "c6i.xlarge" + +# Elastic Cloud + # The number of AZs the APM Server should span. apm_server_zone_count = 1 # The Elasticsearch cluster node size. @@ -8,5 +14,8 @@ elasticsearch_size = "64g" elasticsearch_zone_count = 2 # APM server instance size apm_server_size = "8g" -# Benchmarks executor size executor -worker_instance_type = "c6i.2xlarge" + +# Standalone + +standalone_apm_server_instance_size = "c6i.xlarge" +standalone_moxy_instance_size = "c6i.2xlarge" diff --git a/testing/benchmark/terraform.tfvars.example b/testing/benchmark/terraform.tfvars.example index d58973b61b..2b44a828d6 100644 --- a/testing/benchmark/terraform.tfvars.example +++ b/testing/benchmark/terraform.tfvars.example @@ -67,3 +67,9 @@ user_name = "USER" # Override the default shard settings for APM indices. Defaults to 0, which doesn't # change the default shard settings. # apm_shards = 12 + +# Override the default APM Server VM size in standalone bench mode. +# standalone_apm_server_instance_size = "c6i.2xlarge" + +# Override the default Moxy VM size in standalone bench mode. +# standalone_moxy_instance_size = "c6i.4xlarge" \ No newline at end of file diff --git a/testing/benchmark/variables.tf b/testing/benchmark/variables.tf index deb2d05d6b..b06a4d7a6b 100644 --- a/testing/benchmark/variables.tf +++ b/testing/benchmark/variables.tf @@ -5,6 +5,12 @@ variable "user_name" { type = string } +variable "run_standalone" { + default = false + description = "If set run benchmarks against standalone APM Server connected to moxy" + type = bool +} + ## Deployment configuration variable "ess_region" { @@ -86,7 +92,49 @@ variable "drop_pipeline" { type = bool } -## Worker configuraiton +# Standalone + +variable "apm_server_bin_path" { + default = "../../build" + type = string + description = "Optional path to APM Server binary" +} + +variable "moxy_bin_path" { + default = "../../build" + type = string + description = "Optional path to moxy binary" +} + +variable "standalone_apm_server_instance_size" { + default = "c6i.2xlarge" + type = string + description = "Optional instance type to use for APM Server VM" +} + +variable "standalone_moxy_instance_size" { + default = "c6i.4xlarge" + type = string + description = "Optional instance type to use for moxy VM" +} + +## VPC Network settings + +variable "vpc_cidr" { + default = "192.168.44.0/24" + type = string +} + +variable "public_cidr" { + default = [ + "192.168.44.0/26", + "192.168.44.64/26", + "192.168.44.128/26", + ] + type = list(string) +} + +## Worker configuration variable "worker_region" { default = "us-west-2" diff --git a/testing/infra/terraform/modules/benchmark_executor/README.md b/testing/infra/terraform/modules/benchmark_executor/README.md index 315861b641..6eca6317a7 100644 --- a/testing/infra/terraform/modules/benchmark_executor/README.md +++ b/testing/infra/terraform/modules/benchmark_executor/README.md @@ -17,7 +17,6 @@ so that `apmbench` can be run against a configured APM Server. | Name | Source | Version | |------|--------|---------| | [ec2\_instance](#module\_ec2\_instance) | terraform-aws-modules/ec2-instance/aws | 3.5.0 | -| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | 3.14.0 | ## Resources @@ -28,6 +27,8 @@ so that `apmbench` can be run against a configured APM Server. | [null_resource.apmbench](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | | [null_resource.envrc](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | | [aws_ami.worker_ami](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_security_group.security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/security_group) | data source | +| [aws_subnets.public_subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | ## Inputs @@ -38,12 +39,11 @@ so that `apmbench` can be run against a configured APM Server. | [apmbench\_bin\_path](#input\_apmbench\_bin\_path) | Optionally upload the apmbench binary from the specified path to the worker machine | `string` | `""` | no | | [instance\_type](#input\_instance\_type) | Optional instance type to use for the worker VM | `string` | `"c6i.large"` | no | | [private\_key](#input\_private\_key) | n/a | `string` | `"~/.ssh/id_rsa_terraform"` | no | -| [public\_cidr](#input\_public\_cidr) | n/a | `list(string)` |
[
"192.168.44.0/26",
"192.168.44.64/26",
"192.168.44.128/26"
]
| no | | [public\_key](#input\_public\_key) | n/a | `string` | `"~/.ssh/id_rsa_terraform.pub"` | no | | [region](#input\_region) | n/a | `string` | `"us-west2"` | no | | [tags](#input\_tags) | Optional set of tags to use for all resources | `map(string)` | `{}` | no | | [user\_name](#input\_user\_name) | Required username to use for resource name prefixes | `string` | n/a | yes | -| [vpc\_cidr](#input\_vpc\_cidr) | n/a | `string` | `"192.168.44.0/24"` | no | +| [vpc\_id](#input\_vpc\_id) | VPC ID to provision the EC2 instance | `string` | n/a | yes | ## Outputs diff --git a/testing/infra/terraform/modules/benchmark_executor/instance.tf b/testing/infra/terraform/modules/benchmark_executor/instance.tf index 18d55462c6..7b41f643eb 100644 --- a/testing/infra/terraform/modules/benchmark_executor/instance.tf +++ b/testing/infra/terraform/modules/benchmark_executor/instance.tf @@ -6,50 +6,6 @@ locals { } } -module "vpc" { - source = "terraform-aws-modules/vpc/aws" - version = "3.14.0" - - name = "${var.user_name}-worker" - cidr = var.vpc_cidr - - azs = [for letter in ["a", "b", "c"] : "${var.region}${letter}"] - public_subnets = var.public_cidr - enable_ipv6 = false - enable_nat_gateway = false - single_nat_gateway = false - - manage_default_security_group = true - default_security_group_ingress = [ - { - "from_port" : 0, - "to_port" : 0, - "protocol" : -1, - "self" : true, - "cidr_blocks" : "0.0.0.0/0", - } - ] - default_security_group_egress = [ - { - "from_port" : 0, - "to_port" : 0, - "protocol" : -1, - "cidr_blocks" : "0.0.0.0/0", - } - ] - - tags = merge(var.tags, local.ec2_tags) - vpc_tags = { - Name = "vpc-${var.user_name}-worker" - } -} - -resource "aws_key_pair" "worker" { - key_name = "${var.user_name}_worker_key" - public_key = file(var.public_key) - tags = merge(var.tags, local.ec2_tags) -} - data "aws_ami" "worker_ami" { owners = ["amazon"] most_recent = true @@ -60,6 +16,18 @@ data "aws_ami" "worker_ami" { } } +data "aws_subnets" "public_subnets" { + filter { + name = "vpc-id" + values = [var.vpc_id] + } +} + +data "aws_security_group" "security_group" { + vpc_id = var.vpc_id + name = "default" +} + module "ec2_instance" { source = "terraform-aws-modules/ec2-instance/aws" @@ -68,9 +36,15 @@ module "ec2_instance" { ami = data.aws_ami.worker_ami.id instance_type = var.instance_type monitoring = false - vpc_security_group_ids = [module.vpc.default_security_group_id] - subnet_id = module.vpc.public_subnets[0] + vpc_security_group_ids = [data.aws_security_group.security_group.id] + subnet_id = data.aws_subnets.public_subnets.ids[0] associate_public_ip_address = true key_name = aws_key_pair.worker.id tags = merge(var.tags, local.ec2_tags) } + +resource "aws_key_pair" "worker" { + key_name = "${var.user_name}_worker_key" + public_key = file(var.public_key) + tags = merge(var.tags, local.ec2_tags) +} diff --git a/testing/infra/terraform/modules/benchmark_executor/variables.tf b/testing/infra/terraform/modules/benchmark_executor/variables.tf index 5edc17f5ba..79e21837e5 100644 --- a/testing/infra/terraform/modules/benchmark_executor/variables.tf +++ b/testing/infra/terraform/modules/benchmark_executor/variables.tf @@ -18,6 +18,11 @@ variable "instance_type" { description = "Optional instance type to use for the worker VM" } +variable "vpc_id" { + description = "VPC ID to provision the EC2 instance" + type = string +} + variable "apm_secret_token" { default = "" type = string @@ -39,22 +44,6 @@ variable "tags" { description = "Optional set of tags to use for all resources" } -## VPC Network settings - -variable "vpc_cidr" { - default = "192.168.44.0/24" - type = string -} - -variable "public_cidr" { - default = [ - "192.168.44.0/26", - "192.168.44.64/26", - "192.168.44.128/26", - ] - type = list(string) -} - variable "region" { default = "us-west2" type = string diff --git a/testing/infra/terraform/modules/moxy/README.md b/testing/infra/terraform/modules/moxy/README.md new file mode 100644 index 0000000000..68935f1f6b --- /dev/null +++ b/testing/infra/terraform/modules/moxy/README.md @@ -0,0 +1,40 @@ + +# Moxy module + +This module can be used to create a stub ElasticSearch deployment (Moxy). + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | n/a | +| [random](#provider\_random) | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_instance.moxy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) | resource | +| [aws_key_pair.provisioner_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/key_pair) | resource | +| [aws_security_group.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [random_password.moxy_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | +| [aws_ami.worker_ami](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_subnets.public_subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [aws\_provisioner\_key\_name](#input\_aws\_provisioner\_key\_name) | ssh key name to create the aws key pair and remote provision the EC2 instance | `string` | n/a | yes | +| [instance\_type](#input\_instance\_type) | Moxy instance type | `string` | n/a | yes | +| [moxy\_bin\_path](#input\_moxy\_bin\_path) | Moxy path to binary to copy to the worker machine | `string` | n/a | yes | +| [tags](#input\_tags) | Optional set of tags to use for all resources | `map(string)` | `{}` | no | +| [vpc\_id](#input\_vpc\_id) | VPC ID to provision the EC2 instance | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [moxy\_password](#output\_moxy\_password) | Moxy server password | +| [moxy\_url](#output\_moxy\_url) | Moxy server URL | + \ No newline at end of file diff --git a/testing/infra/terraform/modules/moxy/header.md b/testing/infra/terraform/modules/moxy/header.md new file mode 100644 index 0000000000..519b5d9b58 --- /dev/null +++ b/testing/infra/terraform/modules/moxy/header.md @@ -0,0 +1,3 @@ +# Moxy module + +This module can be used to create a stub ElasticSearch deployment (Moxy). diff --git a/testing/infra/terraform/modules/moxy/main.tf b/testing/infra/terraform/modules/moxy/main.tf new file mode 100644 index 0000000000..245b69f098 --- /dev/null +++ b/testing/infra/terraform/modules/moxy/main.tf @@ -0,0 +1,103 @@ +locals { + moxy_port = "9200" + bin_path = "/tmp/moxy" +} + +data "aws_ami" "worker_ami" { + owners = ["amazon"] + most_recent = true + + filter { + name = "name" + values = ["amzn2-ami-hvm-*-x86_64-ebs"] + } +} + +data "aws_subnets" "public_subnets" { + filter { + name = "vpc-id" + values = [var.vpc_id] + } +} + +resource "aws_security_group" "main" { + vpc_id = var.vpc_id + egress = [ + { + cidr_blocks = ["0.0.0.0/0"] + description = "" + from_port = 0 + ipv6_cidr_blocks = [] + prefix_list_ids = [] + protocol = "-1" + security_groups = [] + self = false + to_port = 0 + } + ] + ingress = [ + { + cidr_blocks = ["0.0.0.0/0"] + description = "" + from_port = 22 + ipv6_cidr_blocks = [] + prefix_list_ids = [] + protocol = "tcp" + security_groups = [] + self = false + to_port = 22 + }, + { + cidr_blocks = ["0.0.0.0/0"] + description = "" + from_port = local.moxy_port + ipv6_cidr_blocks = [] + prefix_list_ids = [] + protocol = "tcp" + security_groups = [] + self = false + to_port = local.moxy_port + } + ] +} + +resource "aws_instance" "moxy" { + ami = data.aws_ami.worker_ami.id + instance_type = var.instance_type + subnet_id = data.aws_subnets.public_subnets.ids[0] + vpc_security_group_ids = [aws_security_group.main.id] + key_name = aws_key_pair.provisioner_key.key_name + monitoring = false + + connection { + type = "ssh" + user = "ec2-user" + host = self.public_ip + private_key = file("${var.aws_provisioner_key_name}") + } + + provisioner "file" { + source = "${var.moxy_bin_path}/moxy" + destination = local.bin_path + } + provisioner "remote-exec" { + inline = [ + "sudo cp ${local.bin_path} moxy", + "sudo chmod +x moxy", + "screen -d -m ./moxy -port=${local.moxy_port} -password=${random_password.moxy_password.result}", + "sleep 1" + ] + } + + tags = var.tags +} + +resource "aws_key_pair" "provisioner_key" { + public_key = file("${var.aws_provisioner_key_name}.pub") + tags = var.tags +} + +resource "random_password" "moxy_password" { + length = 16 + special = false +} diff --git a/testing/infra/terraform/modules/moxy/outputs.tf b/testing/infra/terraform/modules/moxy/outputs.tf new file mode 100644 index 0000000000..ad4cb489be --- /dev/null +++ b/testing/infra/terraform/modules/moxy/outputs.tf @@ -0,0 +1,10 @@ +output "moxy_url" { + value = "http://${aws_instance.moxy.public_ip}:${local.moxy_port}" + description = "Moxy server URL" +} + +output "moxy_password" { + value = random_password.moxy_password.result + description = "Moxy server password" + sensitive = true +} diff --git a/testing/infra/terraform/modules/moxy/variables.tf b/testing/infra/terraform/modules/moxy/variables.tf new file mode 100644 index 0000000000..4c8538b266 --- /dev/null +++ b/testing/infra/terraform/modules/moxy/variables.tf @@ -0,0 +1,25 @@ +variable "instance_type" { + type = string + description = "Moxy instance type" +} + +variable "vpc_id" { + description = "VPC ID to provision the EC2 instance" + type = string +} + +variable "aws_provisioner_key_name" { + description = "ssh key name to create the aws key pair and remote provision the EC2 instance" + type = string +} + +variable "moxy_bin_path" { + type = string + description = "Moxy path to binary to copy to the worker machine" +} + +variable "tags" { + type = map(string) + default = {} + description = "Optional set of tags to use for all resources" +} diff --git a/testing/infra/terraform/modules/standalone_apm_server/README.md b/testing/infra/terraform/modules/standalone_apm_server/README.md new file mode 100644 index 0000000000..6b452b50ca --- /dev/null +++ b/testing/infra/terraform/modules/standalone_apm_server/README.md @@ -0,0 +1,53 @@ + +# Standalone APM Server module + +This module can be used to create a standalone APM Server deployment against a set of predefined architectures and instance types. + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | n/a | +| [external](#provider\_external) | n/a | +| [null](#provider\_null) | n/a | +| [random](#provider\_random) | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_instance.apm](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) | resource | +| [aws_key_pair.provisioner_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/key_pair) | resource | +| [aws_security_group.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [null_resource.apm_server_log](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | +| [random_password.apm_secret_token](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | +| [aws_ami.os](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | +| [aws_subnets.public_subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | +| [external_external.latest_apm_server](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source | +| [external_external.latest_elastic_agent](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [apm\_instance\_type](#input\_apm\_instance\_type) | Optional apm server instance type overide | `string` | `""` | no | +| [apm\_server\_bin\_path](#input\_apm\_server\_bin\_path) | Optionally use the apm-server binary from the specified path instead | `string` | `""` | no | +| [aws\_os](#input\_aws\_os) | Optional aws EC2 instance OS | `string` | `""` | no | +| [aws\_provisioner\_key\_name](#input\_aws\_provisioner\_key\_name) | ssh key name to create the aws key pair and remote provision the EC2 instance | `string` | n/a | yes | +| [ea\_managed](#input\_ea\_managed) | Whether or not install Elastic Agent managed APM Server | `bool` | `false` | no | +| [elasticsearch\_password](#input\_elasticsearch\_password) | The Elasticsearch password | `string` | n/a | yes | +| [elasticsearch\_url](#input\_elasticsearch\_url) | The secure Elasticsearch URL | `string` | n/a | yes | +| [elasticsearch\_username](#input\_elasticsearch\_username) | The Elasticsearch username | `string` | n/a | yes | +| [stack\_version](#input\_stack\_version) | Optional stack version | `string` | `"latest"` | no | +| [tags](#input\_tags) | Optional set of tags to use for all deployments | `map(string)` | `{}` | no | +| [vpc\_id](#input\_vpc\_id) | VPC ID to provision the EC2 instance | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [apm\_secret\_token](#output\_apm\_secret\_token) | The APM Server secret token | +| [apm\_server\_ip](#output\_apm\_server\_ip) | The APM Server EC2 IP address | +| [apm\_server\_url](#output\_apm\_server\_url) | The APM Server URL | + \ No newline at end of file diff --git a/testing/infra/terraform/modules/standalone_apm_server/apm-server.yml.tftpl b/testing/infra/terraform/modules/standalone_apm_server/apm-server.yml.tftpl index 5061811d90..e51007ccf5 100644 --- a/testing/infra/terraform/modules/standalone_apm_server/apm-server.yml.tftpl +++ b/testing/infra/terraform/modules/standalone_apm_server/apm-server.yml.tftpl @@ -6,6 +6,11 @@ apm-server: secret_token: ${apm_secret_token} rum: enabled: true + expvar: + enabled: true + pprof: + enabled: true + output: elasticsearch: hosts: [ ${elasticsearch_url} ] diff --git a/testing/infra/terraform/modules/standalone_apm_server/header.md b/testing/infra/terraform/modules/standalone_apm_server/header.md new file mode 100644 index 0000000000..84009bb8dc --- /dev/null +++ b/testing/infra/terraform/modules/standalone_apm_server/header.md @@ -0,0 +1,3 @@ +# Standalone APM Server module + +This module can be used to create a standalone APM Server deployment against a set of predefined architectures and instance types. diff --git a/testing/infra/terraform/modules/standalone_apm_server/main.tf b/testing/infra/terraform/modules/standalone_apm_server/main.tf index 251251181b..e426fa0e5c 100644 --- a/testing/infra/terraform/modules/standalone_apm_server/main.tf +++ b/testing/infra/terraform/modules/standalone_apm_server/main.tf @@ -6,6 +6,7 @@ locals { "debian-10-arm64" = "136693071363" # debian "debian-11-arm64" = "136693071363" # debian "amzn2-ami-kernel-5.10" = "137112412989" # amazon + "amzn2-ami-hvm-*-x86_64-ebs" = "137112412989" # amazon "al2023-ami-2023" = "137112412989" # amazon "RHEL-7" = "309956199498" # Red Hat "RHEL-8" = "309956199498" # Red Hat @@ -18,6 +19,7 @@ locals { "debian-10-arm64" = "t4g.nano" "debian-11-arm64" = "t4g.nano" "amzn2-ami-kernel-5.10" = "t4g.nano" + "amzn2-ami-hvm-*-x86_64-ebs" = "t4g.nano" "al2023-ami-2023" = "t4g.nano" "RHEL-7" = "t3a.micro" # RHEL-7 doesn't support arm "RHEL-8" = "t4g.micro" # RHEL doesn't support nano instances @@ -30,6 +32,7 @@ locals { "debian-10-arm64" = "arm64" "debian-11-arm64" = "arm64" "amzn2-ami-kernel-5.10" = "arm64" + "amzn2-ami-hvm-*-x86_64-ebs" = "x86_64" "al2023-ami-2023" = "arm64" "RHEL-7" = "x86_64" # RHEL-7 doesn't support arm "RHEL-8" = "arm64" @@ -66,13 +69,16 @@ locals { "debian-10-arm64" = "admin" "debian-11-arm64" = "admin" "amzn2-ami-kernel-5.10" = "ec2-user" + "amzn2-ami-hvm-*-x86_64-ebs" = "ec2-user" "al2023-ami-2023" = "ec2-user" "RHEL-7" = "ec2-user" "RHEL-8" = "ec2-user" "RHEL-9" = "ec2-user" } + apm_port = "8200" conf_path = "/tmp/local-apm-config.yml" + bin_path = "/tmp/apm-server" } data "aws_ami" "os" { @@ -101,10 +107,24 @@ data "aws_ami" "os" { owners = [local.image_owners[var.aws_os]] } +data "aws_region" "current" {} + +data "aws_subnets" "public_subnets" { + filter { + name = "vpc-id" + values = [var.vpc_id] + } + filter { + name = "availability-zone" + values = ["${data.aws_region.current.name}a"] + } +} + resource "aws_security_group" "main" { + vpc_id = var.vpc_id egress = [ { - cidr_blocks = ["0.0.0.0/0", ] + cidr_blocks = ["0.0.0.0/0"] description = "" from_port = 0 ipv6_cidr_blocks = [] @@ -117,7 +137,7 @@ resource "aws_security_group" "main" { ] ingress = [ { - cidr_blocks = ["0.0.0.0/0", ] + cidr_blocks = ["0.0.0.0/0"] description = "" from_port = 22 ipv6_cidr_blocks = [] @@ -128,7 +148,7 @@ resource "aws_security_group" "main" { to_port = 22 }, { - cidr_blocks = ["0.0.0.0/0", ] + cidr_blocks = ["0.0.0.0/0"] description = "" from_port = local.apm_port ipv6_cidr_blocks = [] @@ -142,9 +162,12 @@ resource "aws_security_group" "main" { } resource "aws_instance" "apm" { - ami = data.aws_ami.os.id - instance_type = local.instance_types[var.aws_os] - key_name = aws_key_pair.provisioner_key.key_name + ami = data.aws_ami.os.id + instance_type = var.apm_instance_type == "" ? local.instance_types[var.aws_os] : var.apm_instance_type + subnet_id = data.aws_subnets.public_subnets.ids[0] + vpc_security_group_ids = [aws_security_group.main.id] + key_name = aws_key_pair.provisioner_key.key_name + monitoring = false connection { type = "ssh" @@ -153,6 +176,12 @@ resource "aws_instance" "apm" { private_key = file("${var.aws_provisioner_key_name}") } + provisioner "file" { + source = "${var.apm_server_bin_path}/apm-server" + destination = local.bin_path + on_failure = continue + } + provisioner "file" { destination = local.conf_path content = templatefile(var.ea_managed ? "${path.module}/elastic-agent.yml.tftpl" : "${path.module}/apm-server.yml.tftpl", { @@ -172,15 +201,24 @@ resource "aws_instance" "apm" { "sudo cp ${local.conf_path} /etc/elastic-agent/elastic-agent.yml", "sudo systemctl start elastic-agent", "sleep 1", - ] : [ - local.instance_standalone_provision_cmd[var.aws_os], - "sudo cp ${local.conf_path} /etc/apm-server/apm-server.yml", - "sudo systemctl start apm-server", - "sleep 1", - ] + ] : ( + var.apm_server_bin_path == "" ? [ + local.instance_standalone_provision_cmd[var.aws_os], + "sudo cp ${local.conf_path} /etc/apm-server/apm-server.yml", + "sudo systemctl start apm-server", + "sleep 1", + ] : [ + "sudo cp ${local.bin_path} apm-server", + "sudo chmod +x apm-server", + "sudo cp ${local.conf_path} apm-server.yml", + "sudo mkdir -m 777 /var/log/apm-server", + "screen -d -m ./apm-server", + "sleep 1" + ] + ) } - vpc_security_group_ids = [aws_security_group.main.id] + tags = var.tags } resource "null_resource" "apm_server_log" { @@ -208,8 +246,8 @@ data "external" "latest_apm_server" { } resource "aws_key_pair" "provisioner_key" { - key_name = var.aws_provisioner_key_name public_key = file("${var.aws_provisioner_key_name}.pub") + tags = var.tags } resource "random_password" "apm_secret_token" { diff --git a/testing/infra/terraform/modules/standalone_apm_server/outputs.tf b/testing/infra/terraform/modules/standalone_apm_server/outputs.tf index f3cda74107..138e496e59 100644 --- a/testing/infra/terraform/modules/standalone_apm_server/outputs.tf +++ b/testing/infra/terraform/modules/standalone_apm_server/outputs.tf @@ -5,6 +5,11 @@ output "apm_secret_token" { } output "apm_server_url" { - value = "${aws_instance.apm.public_ip}:${local.apm_port}" + value = "http://${aws_instance.apm.public_ip}:${local.apm_port}" description = "The APM Server URL" } + +output "apm_server_ip" { + value = aws_instance.apm.public_ip + description = "The APM Server EC2 IP address" +} diff --git a/testing/infra/terraform/modules/standalone_apm_server/provider.tf b/testing/infra/terraform/modules/standalone_apm_server/provider.tf deleted file mode 100644 index 3d86029815..0000000000 --- a/testing/infra/terraform/modules/standalone_apm_server/provider.tf +++ /dev/null @@ -1,6 +0,0 @@ -provider "aws" { - region = var.worker_region - default_tags { - tags = var.tags - } -} diff --git a/testing/infra/terraform/modules/standalone_apm_server/variables.tf b/testing/infra/terraform/modules/standalone_apm_server/variables.tf index d0e1189083..dbdf8dd723 100644 --- a/testing/infra/terraform/modules/standalone_apm_server/variables.tf +++ b/testing/infra/terraform/modules/standalone_apm_server/variables.tf @@ -1,12 +1,22 @@ variable "aws_os" { default = "" - description = "Optional aws ec2 instance OS" + description = "Optional aws EC2 instance OS" type = string } -variable "aws_provisioner_key_name" { +variable "apm_instance_type" { default = "" - description = "Optional ssh key name to create the aws key pair and remote provision the ec2 instance" + type = string + description = "Optional apm server instance type overide" +} + +variable "vpc_id" { + description = "VPC ID to provision the EC2 instance" + type = string +} + +variable "aws_provisioner_key_name" { + description = "ssh key name to create the aws key pair and remote provision the EC2 instance" type = string } @@ -33,50 +43,20 @@ variable "stack_version" { type = string } -variable "region" { - default = "gcp-us-west2" - description = "Optional ESS region where to run the smoke tests" - type = string -} - -variable "worker_region" { - default = "us-west-2" - description = "Optional AWS region where the workers will be created. Defaults to us-west-2 (AWS)" - type = string -} - variable "ea_managed" { default = false description = "Whether or not install Elastic Agent managed APM Server" type = bool } +variable "apm_server_bin_path" { + default = "" + type = string + description = "Optionally use the apm-server binary from the specified path instead" +} + variable "tags" { type = map(string) default = {} description = "Optional set of tags to use for all deployments" } - -# CI variables -variable "BRANCH" { - description = "Branch name or pull request for tagging purposes" - default = "unknown" -} - -variable "BUILD_ID" { - description = "Build ID in the CI for tagging purposes" - default = "unknown" -} - -variable "CREATED_DATE" { - description = "Creation date in epoch time for tagging purposes" - default = "unknown" -} - -variable "ENVIRONMENT" { - default = "unknown" -} - -variable "REPO" { - default = "unknown" -} diff --git a/testing/infra/terraform/modules/tags/vars.tf b/testing/infra/terraform/modules/tags/vars.tf index b4ca5f3598..fb84b7d572 100644 --- a/testing/infra/terraform/modules/tags/vars.tf +++ b/testing/infra/terraform/modules/tags/vars.tf @@ -1,8 +1,10 @@ variable "project" { description = "The value to use for the project tag/label" + type = string } variable "build" { description = "The value to use for the build tag/label" + type = string default = "unknown" } diff --git a/testing/smoke/managed/main.tf b/testing/smoke/managed/main.tf index 3fead67e50..caf816aa62 100644 --- a/testing/smoke/managed/main.tf +++ b/testing/smoke/managed/main.tf @@ -25,6 +25,10 @@ locals { } } +data "aws_vpc" "default" { + default = true +} + module "ec_deployment" { source = "../../infra/terraform/modules/ec_deployment" region = var.region @@ -44,7 +48,7 @@ module "ec_deployment" { module "standalone_apm_server" { source = "../../infra/terraform/modules/standalone_apm_server" - worker_region = var.worker_region + vpc_id = data.aws_vpc.default.id aws_os = var.aws_os aws_provisioner_key_name = var.aws_provisioner_key_name @@ -52,16 +56,9 @@ module "standalone_apm_server" { elasticsearch_username = module.ec_deployment.elasticsearch_username elasticsearch_password = module.ec_deployment.elasticsearch_password stack_version = var.stack_version - region = var.region tags = merge(local.ci_tags, module.tags.tags) ea_managed = true - - BRANCH = var.BRANCH - BUILD_ID = var.BUILD_ID - CREATED_DATE = var.CREATED_DATE - ENVIRONMENT = var.ENVIRONMENT - REPO = var.REPO } variable "aws_os" { @@ -88,12 +85,6 @@ variable "region" { type = string } -variable "worker_region" { - default = "us-west-2" - description = "Optional AWS region where the workers will be created. Defaults to us-west-2 (AWS)" - type = string -} - # CI variables variable "BRANCH" { description = "Branch name or pull request for tagging purposes" diff --git a/testing/smoke/supported-os/main.tf b/testing/smoke/supported-os/main.tf index 9674b1829b..9835da198c 100644 --- a/testing/smoke/supported-os/main.tf +++ b/testing/smoke/supported-os/main.tf @@ -25,6 +25,10 @@ locals { } } +data "aws_vpc" "default" { + default = true +} + module "ec_deployment" { source = "../../infra/terraform/modules/ec_deployment" region = var.region @@ -44,7 +48,7 @@ module "ec_deployment" { module "standalone_apm_server" { source = "../../infra/terraform/modules/standalone_apm_server" - worker_region = var.worker_region + vpc_id = data.aws_vpc.default.id aws_os = var.aws_os aws_provisioner_key_name = var.aws_provisioner_key_name @@ -52,16 +56,9 @@ module "standalone_apm_server" { elasticsearch_username = module.ec_deployment.elasticsearch_username elasticsearch_password = module.ec_deployment.elasticsearch_password stack_version = var.stack_version - region = var.region tags = merge(local.ci_tags, module.tags.tags) ea_managed = false - - BRANCH = var.BRANCH - BUILD_ID = var.BUILD_ID - CREATED_DATE = var.CREATED_DATE - ENVIRONMENT = var.ENVIRONMENT - REPO = var.REPO } variable "aws_os" { @@ -88,12 +85,6 @@ variable "region" { type = string } -variable "worker_region" { - default = "us-west-2" - description = "Optional AWS region where the workers will be created. Defaults to us-west-2 (AWS)" - type = string -} - # CI variables variable "BRANCH" { description = "Branch name or pull request for tagging purposes" diff --git a/tools/go.mod b/tools/go.mod index 6c3fc8c4ce..8b7a7226c6 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -3,6 +3,7 @@ module github.com/elastic/apm-server/tools go 1.23.0 require ( + github.com/elastic/apm-perf v0.0.0-20240925232339-499ba2a27fd4 github.com/elastic/apm-tools v0.0.0-20230828065051-3f799314cc8b github.com/elastic/go-licenser v0.4.2 github.com/elastic/gobench v0.0.0-20220608141032-f30bc57e329c @@ -75,7 +76,7 @@ require ( github.com/invopop/jsonschema v0.12.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/compress v1.17.10 // indirect github.com/klauspost/pgzip v1.2.6 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -111,9 +112,9 @@ require ( github.com/spf13/viper v1.19.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/terraform-docs/terraform-config-inspect v0.0.0-20210728164355-9c1f178932fa // indirect - github.com/tidwall/gjson v1.14.4 // indirect + github.com/tidwall/gjson v1.17.3 // indirect github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect github.com/ulikunitz/xz v0.5.12 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect @@ -121,6 +122,7 @@ require ( github.com/zclconf/go-cty v1.15.0 // indirect gitlab.com/digitalxero/go-conventional-commit v1.0.7 // indirect go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.27.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 // indirect @@ -133,7 +135,7 @@ require ( golang.org/x/tools v0.25.0 // indirect golang.org/x/tools/go/vcs v0.1.0-deprecated // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/grpc v1.66.2 // indirect + google.golang.org/grpc v1.67.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/tools/go.sum b/tools/go.sum index 5069f0920c..837f563f5b 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -69,6 +69,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= +github.com/elastic/apm-perf v0.0.0-20240925232339-499ba2a27fd4 h1:IMvFDtKRa3QSkj1Zr0yesEwubOCp9YARpR4KrHOMYb0= +github.com/elastic/apm-perf v0.0.0-20240925232339-499ba2a27fd4/go.mod h1:K/l3iP9/AYOQ5QTb0JZbWR+Law4vLfpLFmhZ+5KoRRY= github.com/elastic/apm-tools v0.0.0-20230828065051-3f799314cc8b h1:47VFNMVQQt7WTHF7NdS37Qkk4fMx4uGhM5WWf5lUqio= github.com/elastic/apm-tools v0.0.0-20230828065051-3f799314cc8b/go.mod h1:IUMdGldUOSqfeXSj+zIjYaBX6WFM7M95WU2VdmZ5ZyE= github.com/elastic/elastic-transport-go/v8 v8.3.0 h1:DJGxovyQLXGr62e9nDMPSxRyWION0Bh6d9eCFBriiHo= @@ -170,8 +172,8 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= +github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -292,12 +294,13 @@ github.com/terraform-docs/terraform-config-inspect v0.0.0-20210728164355-9c1f178 github.com/terraform-docs/terraform-docs v0.19.0 h1:YDC9YTxEzH0NPbXaqSwi1opp3+F2Ka3ZL/vIUa1Dv68= github.com/terraform-docs/terraform-docs v0.19.0/go.mod h1:+Hd2ngjXmsC9H9hHDz4BXdxLaOHJX3/cZEWqaeaG8m0= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= -github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94= +github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= @@ -319,8 +322,12 @@ gitlab.com/digitalxero/go-conventional-commit v1.0.7 h1:8/dO6WWG+98PMhlZowt/Yjui gitlab.com/digitalxero/go-conventional-commit v1.0.7/go.mod h1:05Xc2BFsSyC5tKhK0y+P3bs0AwUtNuTp+mTpbCU/DZ0= go.elastic.co/go-licence-detector v0.7.0 h1:qC31sfyfNcNx/zMYcLABU0ac3MbGHZgksCAb5lMDUMg= go.elastic.co/go-licence-detector v0.7.0/go.mod h1:f5ty8pjynzQD8BcS+s0qtlOGKc35/HKQxCVi8SHhV5k= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -448,8 +455,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo= -google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= +google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= +google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/tools/tools.go b/tools/tools.go index f869641019..4484e8a01f 100644 --- a/tools/tools.go +++ b/tools/tools.go @@ -38,4 +38,6 @@ import ( _ "github.com/elastic/go-licenser" // go.mod/go.sum _ "github.com/elastic/gobench" // go.mod/go.sum + + _ "github.com/elastic/apm-perf/cmd/moxy" // go.mod/go.sum )