Skip to content

Commit

Permalink
Merge pull request #3 from instana/ko-add-more-complex-example
Browse files Browse the repository at this point in the history
feat: Add detailed GitOps example including upgrades via version pinning
  • Loading branch information
konrad-ohms authored Sep 2, 2024
2 parents ea94106 + a13a3b3 commit b0931d6
Show file tree
Hide file tree
Showing 11 changed files with 223 additions and 7 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/instana-gitops-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,25 @@
### For more information on the Instana GitHub action for GitOps update, refer to:
### https://github.com/instana/github-action-update-agent-configurations

name: Instana GitOps update
name: Instana GitOps update - Prod

on:
push:
paths-ignore:
- 'renovate.json'
- 'README.md'
branches: [ main ]

jobs:
build:
push-gitops-config:
runs-on: ubuntu-latest

steps:
- uses: instana/[email protected]
with:
# At least one of 'agent_zone' and 'agent_tags' should be set
agent_zone: my_zone
agent_tags: 'gitops_environment=prod'
agent_zone: gitops-demo
agent_tags: gitops_environment=prod
env:
INSTANA_API_ENDPOINT: ${{ secrets.INSTANA_API_ENDPOINT }}
INSTANA_API_TOKEN: ${{ secrets.INSTANA_API_TOKEN }}
66 changes: 66 additions & 0 deletions .github/workflows/sync-agent-version-to-main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# This workflow is used to create a PR with the existing agent version from the test branch to main

name: Sync Agent Version to main

# Controls when the workflow will run
on:
push:
branches: [ "test" ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:
open-pr:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v4

# Runs a set of commands using the runners shell
- name: Copy AgentBootrap to main
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
echo "Showing content of current AgentBootstrap"
cat instana/com.instana.agent.bootstrap.AgentBootstrap.cfg
rm -f /tmp/com.instana.agent.bootstrap.AgentBootstrap.cfg
echo "Create temporary copy of the configuration file"
cp instana/com.instana.agent.bootstrap.AgentBootstrap.cfg /tmp/
echo "Checking out main branch"
git fetch origin main
git checkout main
echo "Creating new branch from main"
git checkout -b promote-test-to-main
echo "Replace config file on main"
rm -f instana/com.instana.agent.bootstrap.AgentBootstrap.cfg
cp -f /tmp/com.instana.agent.bootstrap.AgentBootstrap.cfg instana/com.instana.agent.bootstrap.AgentBootstrap.cfg
echo "Check if file was changed"
if [[ `git status --porcelain` ]]; then
echo "The file has changed, continue to commit and push"
else
echo "The file is unchanged, main is already in sync with test branch, no further action needed"
exit 0
fi
echo "Setting git author"
git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"
git config --global user.name "${GITHUB_ACTOR}"
echo "Commiting change"
git add instana/com.instana.agent.bootstrap.AgentBootstrap.cfg
git commit -m "chore: Sync AgentBootstrap from current test branch"
echo "Push change to feature branch"
git push origin -f promote-test-to-main
UPDATED_VERSION=$(cat instana/com.instana.agent.bootstrap.AgentBootstrap.cfg | grep "version = " | grep -v "#" | cut -c11-)
PR_TITLE="chore(deps): Update Instana Agent Production to v${UPDATED_VERSION}"
echo "Automated sync of instana/com.instana.agent.bootstrap.AgentBootstrap.cfg from branch \"test\" to \"main\"." > body-file.txt
echo "Make sure that the test environment works as expected before approving and merging the change." >> body-file.txt
echo "Merging will **trigger an production update including an agent restart**." >> body-file.txt
echo "" >> body-file.txt
echo "This update was driven by [this GitHub Action Workflow](https://github.com/instana/gitops-demo/blob/test/.github/workflows/sync-agent-version-to-main.yml)." >> body-file.txt
echo "Available Instana Agent tags can be found on the [instana/agent-updates](https://github.com/instana/agent-updates/tags) repository." >> body-file.txt
gh pr create -B main --title "${PR_TITLE}" --body-file "body-file.txt" --label "production" || \
gh pr edit -B main --title "${PR_TITLE}" --body-file "body-file.txt" --add-label "production"
119 changes: 119 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,122 @@ The [.github/workflows/instana-gitops-update.yml](.github/workflows/instana-gito
* [Instana's Git-based Configuration Management documentation](https://www.instana.com/docs/setup_and_manage/host_agent/configuration/git_ops#with-the-api)
* [Instana GitHub action for GitOps](https://github.com/instana/github-action-update-agent-configurations)
* [Githooks documentation](https://git-scm.com/docs/githooks)


## Quickstart

### Preparing the repository

Fork this repository to get started or copy files as desired to a new git repository.

Change files in the [instana](./instana) folder to match the new target environment. Ensure to change files on branches `main` for production and on branch `test` for the test environment.

To be able to run the GitHub Actions Workflows, define credentials for the Instana backend and a GitHub personal access token.

To generate an Instana backend token, login into the Instana UI and navigate to `Settings > Team Settings > API Tokens > New API Token` and select the `Configuration of agents` permission and `Save`.

![](./images/generate-api-token-instana-backend.png)

The GitHub workflow which promotes changes from the `test` branch to `main` requires access to the GitHub repository via GitHub Personal Access Token which can be generated in GitHub's Developer Settings > [New personal access token (classic)](https://github.com/settings/tokens/new).
The access token requires permission on the forked repository and the following repository permissions:

- repo > public repo

If the repository is not public, permission to access a private repository is also required.

In the GitHub settings of the gitops repository navigate to `Secrets and variables > Actions` and define the following entries as repository secrets:

- `GH_TOKEN`: Personal access token for the GitHub API
- `INSTANA_API_ENDPOINT`: URL used for the Instana login, e.g.: https://qa-instana.instana.io
- `INSTANA_API_TOKEN`: API token for the Instana API

To receive updates via renovate, install the [Renovate GitHub App](https://github.com/apps/renovate) on this repository.

### Installing the agents

Installing and configuring new agents to pull updates from this repository can be performed during installation or by changing configuration of existing agents.

By defining `main` as branch name new agents will be onboarded with production configuration, choosing `test` will apply the configuration of the test branch from this repository.

**Linux Host agents via One-Line-Installer**:

```#!/bin/bash
curl -o setup_agent.sh https://setup.instana.io/agent && chmod 700 ./setup_agent.sh && sudo ./setup_agent.sh \
-a xxx \
-d xxx \
-t dynamic \
-e ingress-red-saas.instana.io:443 \
-s \
-g https://github.com/instana/gitops-demo.git \
-b test
```

**Docker based installation**

```#!/bin/bash
docker run \
--detach \
--name instana-agent \
--volume /var/run:/var/run \
--volume /run:/run \
--volume /dev:/dev:ro \
--volume /sys:/sys:ro \
--volume /var/log:/var/log:ro \
--privileged \
--net=host \
--pid=host \
--env="INSTANA_AGENT_ENDPOINT=ingress-red-saas.instana.io" \
--env="INSTANA_AGENT_ENDPOINT_PORT=443" \
--env="INSTANA_AGENT_KEY=xxx" \
--env="INSTANA_DOWNLOAD_KEY=xxx" \
--env="INSTANA_GIT_REMOTE_BRANCH=test" \
--env="INSTANA_GIT_REMOTE_REPOSITORY=https://github.com/instana/gitops-demo.git" \
icr.io/instana/agent
```

**Manual mode**

Export the environment variables `INSTANA_GIT_REMOTE_BRANCH`, `INSTANA_GIT_REMOTE_REPOSITORY` and optional credentials (`INSTANA_GIT_REMOTE_USERNAME`, `INSTANA_GIT_REMOTE_PASSWORD`) in case of a private repository to the instana agent process. This can e.g. be achieved via systemd, see also the [Instana Documentation](https://www.ibm.com/docs/en/instana-observability/current?topic=agents-git-based-configuration-management) for more details.

The examples above onboard a new agent to the test environment, if the agent should join the production group, define `main` instead of `test` as `INSTANA_GIT_REMOTE_REPOSITORY`.

**Configuring Git-based configuration management on existing agents**

An existing host agent can be configured to pull changes from a git repository. Navigate into the Instana UI and open the Agent Dashboard. Click on the `Initialize` button shown in the `Configuration Management` section. After entering the details and clicking on `Initialize & Restart` the configuration will be loaded and applied.

![enable-git-configuration-on-existing-agent](./images/enable-git-configuration-on-existing-agent.png)

Note: After applying new agent versions, it can take up to a few minutes before the new version is shown correctly in the Agent Dashboard view, as values are cached.

## Update Workflow

This project uses [renovate](https://github.com/apps/renovate) to automatically watch the [instana/agent-updates](https://github.com/instana/agent-updates/tags) repositories for new tags and to create a pull request (PR) against the `test` branch.

![renovate-pr](./images/renovate-pull-request.png)

Once the PR was reviewed and merged, GitHub Actions will run a workflow to send an update request to the configured Instana backend.
A second workflow is triggered to open a PR with changes from the `test` branch against the `main` branch.

![pr-sync-test-to-main](./images/pr-sync-test-to-main.png)

This is meant to be a quality gate which provides an option for customers to validate a new agent version in their given environment before pushing it out to production. When the new agent version is validated the PR against `main` can be merged and the update gets promoted by a GitHub Actions workflow which notifies the Instana backend to send update requests to the selected agent groups.

In the given example, it is assumed that all systems in the test or production group will receive updates at once. If a staged rollout is desired, more detailed tags can be defined or more branches can be used so that update requests could be send in batches via additional steps in the GitHub Actions workflow.

The intial update PRs against the `test` branch are raised by [renovate](https://github.com/renovatebot/renovate). It is parsing the comment defined in [instana-gitops-update.yml](.github/workflows/instana-gitops-update.yml) to detect where to search for new instana agent tags in GitHub:

```
# renovate: datasource=github-tags depName=instana/agent-updates versioning=loose
version = 2024.08.20.0843
```

The [renovate configuration](./renovate.json) defines a regular expression to match the version number and to replace it with the new tags on a feature branch. The feature branch is used in a PR against the `test` branch. Renovate will always check the `renovate.json` found on the main branch, but it can define base branches to update (in this example, it only proposes updates to branch `test`). For more details see the [renovate documentation](https://docs.renovatebot.com/modules/manager/regex/).

GitHub Actions will use the workflow definitions of the branch which currently triggered the action. A push to the `test` branch will therefore trigger the GitHub workflow store in the `test` branch rather than the definition stored in `main`.

## Usage of different tooling

This repository uses GitHub Actions to send agent update requests to the Instana Backend and uses a reusable GitHub Action for that purpuse. If other CI tools like Jenkins or Tekton should be used, any HTTP client can be leveraged to send a request, see the usage of `curl` in the [GitHub Action definition](https://github.com/instana/github-action-update-agent-configurations/blob/master/entrypoint.sh) for more details.

To get automatic update notifications, renovate was used in this example. Renovate can be installed as GitHub app, but it can be self-hosted on own infrastructure if prefered.
If renovate should not be used at all, tags can be updates manually or by running scripts periodically.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/generate-api-token-instana-backend.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/pr-sync-test-to-main.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/renovate-pull-request.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions instana/com.instana.agent.bootstrap.AgentBootstrap.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This field specifies which version set of components should be used by the agent;
# its value must be a valid tag from https://github.com/instana/agent-updates/tags
# version = <tag>
# renovate: datasource=github-tags depName=instana/agent-updates versioning=loose
version = 2024.08.20.0843

# This field controls which set of components is used by the agent at runtime.
productName = ${env:INSTANA_PRODUCT_NAME}

origin = package dynamic
3 changes: 0 additions & 3 deletions instana/configuration-test.yaml

This file was deleted.

6 changes: 6 additions & 0 deletions instana/configuration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
com.instana.plugin.host:
tags:
- gitops_environment=prod
com.instana.plugin.generic.hardware:
enabled: true
availability-zone: gitops-demo
15 changes: 15 additions & 0 deletions renovate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended", ":dependencyDashboard"],
"baseBranches": ["test"],
"customManagers": [
{
"customType": "regex",
"fileMatch": ["instana/com.instana.agent.bootstrap.AgentBootstrap.cfg"],
"matchStrings": [
"# renovate: datasource=(?<datasource>[a-z-]+?)(?: depName=(?<depName>.*?))(?: versioning=(?<versioning>[a-z-]+?))?\\sversion\\s=\\s(?<currentValue>.+?)\\s"
],
"versioningTemplate": "{{#if versioning}}{{{versioning}}}{{else}}semver{{/if}}"
}
]
}

0 comments on commit b0931d6

Please sign in to comment.