Agent-Driven DevOps: Deployment Automation
title: "Lesson 15 | Agent-Driven DevOps: Deployment Automation" summary: "Engage Hermes in automated build, Docker packaging, and test release processes to experience the leap towards the 'AI-Native Ops' paradigm." sortOrder: 150 status: "published"
Alright, as a technical education expert, I will write this in-depth tutorial for you on the application of Hermes Agent in the DevOps field.
Subtitle: Engage Hermes in automated build, Docker packaging, and test release processes to experience the leap towards the "AI-Native Ops" paradigm.
Learning Objectives
In this lesson, you will delve into how to extend the capabilities of Hermes Agent from conversation and information processing to actual software engineering practices. After completing this tutorial, you will be able to:
- Understand the core idea of Agent-Driven DevOps: Learn its differences and advantages compared to traditional CI/CD tools (like Jenkins, GitLab CI).
- Create a powerful DevOps Skill: Write a Hermes Skill capable of executing local Shell commands, acting as a bridge between the Agent and server operations.
- Implement a complete automated deployment pipeline: Triggered by a Git Webhook, have the Hermes Agent automatically pull code, build a Docker image, stop the old container, and start the new one in a full CI/CD (Continuous Integration/Continuous Deployment) process.
- Build a closed-loop feedback system: After a deployment task is completed, have the Hermes Agent proactively report the results to you via a message gateway (e.g., Telegram), achieving unattended automated operations.
Core Concepts Explained
1. What is Agent-Driven DevOps?
Traditional DevOps automation relies on predefined, structured configuration files (e.g., .gitlab-ci.yml, Jenkinsfile). These tools are powerful but often lack flexibility and contextual awareness. Their execution logic is fixed, and when unexpected situations arise, they often require manual intervention to investigate logs.
Agent-Driven DevOps is a new paradigm that places a Large Language Model (LLM)-driven Agent at the core of the DevOps process. Its key features include:
- Natural Language Interaction: In addition to automated triggers, you can also issue commands to the Agent using natural language, such as "Deploy the main branch to the staging environment," "Roll back to the previous version," or "Check the status of services in the production environment."
- Contextual Awareness and Decision-Making: The Agent can understand context. For example, when a deployment task fails, it can not only report the error but also attempt to analyze the cause based on the error log (read via a Skill) and even propose solutions.
- Dynamic Workflow Orchestration: The Agent can dynamically adjust the workflow based on the situation. For instance, if a high-risk vulnerability is discovered during the testing phase, it can automatically pause the deployment process and immediately notify the security team, rather than rigidly proceeding to the next step.
- Integration and Collaboration: The Hermes Agent can act as an intelligent hub, connecting code repositories (GitHub), project management tools (Jira), monitoring systems (Prometheus), and communication platforms (Telegram, Slack) to achieve cross-system information integration and task coordination.
In this tutorial, we will take the first step in Agent-Driven DevOps: transforming the Hermes Agent into an intelligent operations bot driven by Git events, capable of executing deployment tasks.
2. The Role of Hermes Agent in DevOps
In this automated process, the Hermes Agent plays the roles of an "intelligent orchestrator" and "executor."
- Listener: Through a Webhook interface, it listens in real-time for events from external systems (like GitHub).
- Decision Maker: Upon receiving an event, the Agent's brain (the LLM), based on its built-in Prompt and available Skills, decides which tool (Tool/Function) to execute.
- Executor: Through a Skill specifically designed for DevOps, it calls underlying Shell scripts or commands to perform the actual work, such as
git pull,docker build,docker run, etc. - Reporter: After the task is completed, it sends the result (success or failure) back to the user via a message gateway, forming a complete closed loop.
3. Key Technical Components
- Skill (
execute_shell_command): This is our core weapon for achieving DevOps automation. We will create a Skill that contains a tool for safely executing Shell commands. This is the only channel for the Agent to interact with the operating system. - Webhook: A Webhook is a reverse API that allows external services to proactively send an HTTP POST request to the Hermes Agent when a specific event occurs. In this example, when we
git pushcode, GitHub will push a JSON packet containing commit information to Hermes's Webhook URL. - Shell Script (
deploy.sh): Encapsulating complex deployment logic into a separate Shell script is a best practice. This keeps the Hermes Skill's responsibility singular (only calling the script) and also makes the deployment logic easier to maintain and reuse elsewhere.
💻 Practical Demonstration
We will use a simple Python Flask application as an example to build a complete automated deployment pipeline. When a developer pushes code to a GitHub repository, the Hermes Agent will automatically deploy it to the server.
Step 1: Prepare the Project Environment
First, we need an application to deploy. We'll create a simple Flask web app and write a Dockerfile and a deployment script for it.
1. Create the project directory
On your server, create a project directory.
mkdir hermes-devops-demo
cd hermes-devops-demo
2. Create the Flask application (app.py)
This is a very simple "Hello World" application.
# app.py
from flask import Flask
import os
app = Flask(__name__)
@app.route('/')
def hello():
# We will use an environment variable to verify if the deployment has been updated
version = os.environ.get('APP_VERSION', 'v1.0.0')
return f"Hello from Hermes DevOps Demo! Version: {version}"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
3. Create the dependency file (requirements.txt)
Flask==2.2.2
4. Create the Dockerfile
This file defines how to package our application into a Docker image.
# Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
CMD ["python", "app.py"]
5. Create the deployment script (deploy.sh)
This is the core execution logic of the entire automation process. The script is responsible for stopping and removing the old container, then building and running a new container with the latest code.
#!/bin/bash
# deploy.sh
# Ensure the script exits if any command fails
set -e
# --- Configuration Variables ---
# Docker image name
IMAGE_NAME="hermes-demo-app"
# Container name
CONTAINER_NAME="hermes-demo-container"
# Application port
APP_PORT=5000
# Project path (ensure this is the absolute path where the script is located)
PROJECT_PATH=$(pwd)
# Get the current Git Commit Hash as the version number
GIT_COMMIT_HASH=$(git rev-parse --short HEAD)
echo "====== [ HERMES DEVOPS ] ======"
echo "Starting deployment for commit: $GIT_COMMIT_HASH"
echo "Project path: $PROJECT_PATH"
# --- 1. Pull the latest code ---
echo "--> Step 1: Pulling latest code from git..."
git pull origin main
# --- 2. Build the Docker image ---
echo "--> Step 2: Building Docker image: $IMAGE_NAME:$GIT_COMMIT_HASH..."
docker build -t $IMAGE_NAME:$GIT_COMMIT_HASH -t $IMAGE_NAME:latest .
# --- 3. Stop and remove the old container ---
# Use docker ps -q to check if the container exists, and if so, stop and remove it
if [ "$(docker ps -q -f name=$CONTAINER_NAME)" ]; then
echo "--> Step 3: Stopping and removing old container..."
docker stop $CONTAINER_NAME
docker rm $CONTAINER_NAME
fi
# --- 4. Start the new container ---
echo "--> Step 4: Starting new container..."
docker run -d \
--name $CONTAINER_NAME \
-p $APP_PORT:5000 \
-e APP_VERSION=$GIT_COMMIT_HASH \
--restart always \
$IMAGE_NAME:latest
echo "====== [ DEPLOYMENT SUCCESS ] ======"
echo "Application deployed successfully!"
echo "Access it at: http://<your_server_ip>:$APP_PORT"
# Return the deployment result to the caller (Hermes Skill)
echo "Deployment of version $GIT_COMMIT_HASH completed."
Important: Grant execute permissions to the script.
chmod +x deploy.sh
6. Initialize the Git repository and push to GitHub
git init
git add .
git commit -m "Initial commit for DevOps demo"
# Create a new empty repository on GitHub, then execute the following commands
git remote add origin <your_github_repo_url.git>
git branch -M main
git push -u origin main
At this point, our application code and deployment script are ready.
Step 2: Create the DevOps Skill
Now, let's create a Skill for the Hermes Agent so it can call the deploy.sh script we just wrote.
- Navigate to the
skillsdirectory of your Hermes Agent and create a new Skill file nameddevops_skill.py. - Edit the
devops_skill.pyfile with the following content:
# skills/devops_skill.py
import subprocess
import os
from hermes_agent.skills.skill import Skill
class DevOpsSkill(Skill):
def __init__(self, agent):
super().__init__(agent)
# The absolute path to your project's deployment script
self.project_path = "/path/to/your/hermes-devops-demo"
def get_tools(self):
return [self.deploy_project]
def deploy_project(self, project_name: str, branch: str) -> str:
"""
Deploys a specified project by executing its deployment script.
This tool should be triggered by a webhook from a Git repository.
It executes the deploy.sh script within the project's directory.
:param project_name: The name of the project to deploy, e.g., 'hermes-devops-demo'.
:param branch: The branch that was pushed, e.g., 'main'.
:return: A string containing the output of the deployment script.
"""
# Security check: only allow deployment for the main branch
if branch != 'main':
return f"Deployment skipped. Only pushes to the 'main' branch trigger deployment. Received push to '{branch}'."
if project_name != 'hermes-devops-demo':
return f"Deployment skipped. Unknown project name: '{project_name}'."
script_path = os.path.join(self.project_path, "deploy.sh")
if not os.path.exists(script_path):
error_msg = f"Error: Deployment script not found at {script_path}"
self.agent.logger.error(error_msg)
return error_msg
try:
self.agent.logger.info(f"Executing deployment script for project '{project_name}' from branch '{branch}'...")
# Use subprocess to execute the shell script
# The cwd parameter ensures the script is executed in the correct project directory
result = subprocess.run(
[script_path],
capture_output=True,
text=True,
check=True,
cwd=self.project_path
)
output = result.stdout
self.agent.logger.info(f"Deployment script executed successfully. Output:\n{output}")
# After a successful deployment, send a notification
self.send_deployment_notification(status="✅ SUCCESS", details=output)
return f"Deployment successful. Log:\n{output}"
except subprocess.CalledProcessError as e:
error_output = e.stderr
self.agent.logger.error(f"Deployment script failed. Error:\n{error_output}")
# After a failed deployment, send a notification
self.send_deployment_notification(status="❌ FAILED", details=error_output)
return f"Deployment failed. Error:\n{error_output}"
def send_deployment_notification(self, status: str, details: str):
"""Sends a deployment status notification via the message gateway"""
if not self.agent.message_gateway:
self.agent.logger.warning("Message gateway not configured. Skipping notification.")
return
# Assuming you have already configured the Telegram (or other) gateway
# Get the admin's user ID from the configuration
admin_user_id = self.agent.config.get('admin_user_id')
if not admin_user_id:
self.agent.logger.warning("Admin user ID not set in config. Skipping notification.")
return
commit_hash = details.split("commit: ")[1].split("\n")[0] if "commit: " in details else "N/A"
message = (
f"**Hermes DevOps Notification**\n\n"
f"**Status**: {status}\n"
f"**Project**: hermes-devops-demo\n"
f"**Commit**: `{commit_hash}`\n\n"
f"**Details**:\n```\n{details[-1000:]}\n```" # Send only the last 1000 characters of the log
)
# Send the message to the admin
self.agent.message_gateway.send_message(message, admin_user_id)
self.agent.logger.info(f"Sent deployment notification to admin user {admin_user_id}.")
3. Register the Skill
Open the Hermes Agent's config.yml file and add our new Skill to the skills section.
# config.yml
skills:
- name: devops_skill.DevOpsSkill
enabled: true
# ... other configurations
Additionally, to enable the notification feature, ensure you have configured a message gateway (e.g., Telegram, as covered in Lesson 05) and add the admin's user ID to config.yml.
# config.yml
# ...
message_gateways:
telegram:
enabled: true
api_token: "your_telegram_bot_token"
# Add a new configuration item
admin_user_id: "your_telegram_user_id"
Step 3: Configure Webhook Access
Now, we need to tell GitHub to notify our Hermes Agent when a code push event occurs.
Get the Hermes Webhook URL: The Hermes Agent's Webhook URL format is:
http://<your_hermes_server_ip>:<port>/v1/webhook/{webhook_id}.webhook_id: You can customize this inconfig.ymlor use the default. We will define a new one here.api_key: Used to verify the source of the request, also set inconfig.yml.
Add the
webhookconfiguration toconfig.yml:# config.yml server: host: "0.0.0.0" port: 8888 api_key: "a_very_secret_api_key" # Please use a strong password webhooks: # Define a dedicated webhook for our DevOps process - id: "github-devops-trigger" # When this webhook is triggered, the Agent will execute this instruction # We leverage the LLM's capability to use the webhook's JSON content as context to call the correct tool prompt: > The following JSON payload was received from a GitHub webhook for the 'hermes-devops-demo' repository. The 'ref' field indicates the branch that was pushed. Based on this information, call the deploy_project tool with the correct project name and branch. Do not ask for confirmation, just execute the tool. Webhook Payload: {payload}Based on this configuration, our Webhook URL is:
http://<your_hermes_server_ip>:8888/v1/webhook/github-devops-trigger.Configure the Webhook in GitHub:
- Open your GitHub repository page and go to
Settings->Webhooks. - Click
Add webhook. - Payload URL: Enter your Hermes Webhook URL.
- Content type: Select
application/json. - Secret: Enter the
api_keyyou set inconfig.yml. - Which events would you like to trigger this webhook?: Select
Just the push event. - Ensure the
Activecheckbox is checked, then clickAdd webhook.
- Open your GitHub repository page and go to
(This is an illustrative guide; please follow the actual UI.)
Step 4: Trigger and Verification
Everything is ready! Let's trigger the entire process.
Restart the Hermes Agent to load the new Skill and configuration.
# In the root directory of the Hermes Agent python main.pyObserve the startup logs to ensure
DevOpsSkillhas been loaded successfully.Modify and push the code: In your locally cloned
hermes-devops-demoproject, make a small change toapp.py.# app.py (modified) @app.route('/') def hello(): version = os.environ.get('APP_VERSION', 'v1.0.0') # Add a new greeting return f"Hello from Hermes DevOps Demo! Version: {version}. Deployment was automated!"Commit and push the code:
git add app.py git commit -m "feat: Update greeting message to test auto-deployment" git push origin mainObserve the Hermes Agent logs: Immediately after the
git pushcommand succeeds, you should see logs similar to the following in the Hermes Agent's console:INFO:hermes_agent.services.http_server:Received webhook request for ID: github-devops-trigger INFO:hermes_agent.agent:Received instruction from webhook 'github-devops-trigger'. Processing... INFO:hermes_agent.models.provider:Calling tool: deploy_project with args: {'project_name': 'hermes-devops-demo', 'branch': 'main'} INFO:skills.devops_skill:Executing deployment script for project 'hermes-devops-demo' from branch 'main'... # ... output from the deploy.sh script ... INFO:skills.devops_skill:Deployment script executed successfully. Output: ====== [ HERMES DEVOPS ] ====== ... ====== [ DEPLOYMENT SUCCESS ] ====== ... INFO:skills.devops_skill:Sent deployment notification to admin user 123456789.Verify the deployment result:
- Run
docker pson your server. You will see a new container running, with a start time corresponding to just now. - Use
curlor a browser to access your application:curl http://localhost:5000. - You should see the updated content, and the version number will be the new Git Commit Hash.
$ curl http://localhost:5000 Hello from Hermes DevOps Demo! Version: a1b2c3d. Deployment was automated!- Run
Check for notifications: Open your Telegram. You should have received a message from your Hermes Bot detailing the successful deployment with logs.
Commands Involved
- Project setup:
mkdir,cd,git init,git add,git commit,git remote add,git push - Permission management:
chmod +x deploy.sh - Docker:
docker build,docker ps,docker stop,docker rm,docker run - Verification:
curl http://localhost:5000
Key Takeaways
- The core of Agent-Driven DevOps is intelligence and interaction: We use the LLM's understanding capabilities with a generic Prompt to parse Webhook content and call the correct tool. This is more extensible than hard-coded
if-elselogic. - Separation of concerns is key: Complex deployment logic should be encapsulated in a separate Shell script (
deploy.sh), while the Hermes Skill is only responsible for triggering, monitoring, and reporting. This decoupling makes both parts easier to maintain. - Webhooks are the bridge to the outside world: By configuring Webhooks, the Hermes Agent can respond to events from external systems, enabling event-driven automation.
- Security is the top priority: Executing Shell commands from a Skill carries potential risks. Always perform strict validation on input parameters (as we did for
branchandproject_name) and ensure that the executed scripts come from a trusted source. In a production environment, consider using a more secure execution sandbox. - A closed feedback loop is crucial: The final step of any automation process should always be reporting. Sending notifications via a message gateway allows us to stay informed of the system's status without logging into the server, truly achieving "unattended operations."
Through this lesson, you have successfully integrated the Hermes Agent into a modern DevOps workflow. This is just the beginning. You can expand on this framework, for example, by:
- Adding a testing phase: Automatically run unit tests before deployment.
- Supporting multi-environment deployment: Decide which environment to deploy to by parsing the branch name (e.g.,
develop,release/*). - Adding a manual approval step: Before deploying to production, the Agent initiates a poll in a group chat and waits for an administrator's confirmation to proceed.
Continue exploring the infinite possibilities of Hermes Agent and march towards true "AI-Native Ops"!