Architecture & Design

5 minutes  

System Architecture

The GitHub Actions-based Smart Agent deployment system uses a self-hosted runner within your AWS VPC to orchestrate deployments to multiple target hosts via SSH.

High-Level Architecture

graph TB
    subgraph Internet
        GH[GitHub.com<br/>Repository & Actions]
        User[Developer<br/>Local Machine]
    end

    subgraph AWS["AWS VPC (172.31.0.0/16)"]
        subgraph SG["Security Group: smartagent-lab"]
            Runner[Self-hosted Runner<br/>EC2 Instance<br/>172.31.1.x]
            
            subgraph Targets["Target Hosts"]
                T1[Target Host 1<br/>Ubuntu EC2<br/>172.31.1.243]
                T2[Target Host 2<br/>Ubuntu EC2<br/>172.31.1.48]
                T3[Target Host 3<br/>Ubuntu EC2<br/>172.31.1.5]
            end
        end
    end

    User -->|git push| GH
    GH <-->|HTTPS:443<br/>Poll for jobs| Runner
    Runner -->|SSH:22<br/>Private IPs| T1
    Runner -->|SSH:22<br/>Private IPs| T2
    Runner -->|SSH:22<br/>Private IPs| T3

    style GH fill:#24292e,color:#fff
    style User fill:#0366d6,color:#fff
    style Runner fill:#28a745,color:#fff
    style T1 fill:#ffd33d,color:#000
    style T2 fill:#ffd33d,color:#000
    style T3 fill:#ffd33d,color:#000

Network Architecture

All infrastructure runs in a single AWS VPC with a shared security group. The self-hosted runner communicates with target hosts via private IPs.

VPC Layout

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        AWS VPC (172.31.0.0/16)                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚          Security Group: smartagent-lab                   β”‚  β”‚
β”‚  β”‚  Rules:                                                   β”‚  β”‚
β”‚  β”‚  - Inbound: SSH (22) from same security group            β”‚  β”‚
β”‚  β”‚  - Outbound: HTTPS (443) to GitHub                       β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚
β”‚  β”‚ Self-hosted β”‚    β”‚  Target EC2  β”‚    β”‚  Target EC2  β”‚       β”‚
β”‚  β”‚   Runner    β”‚    β”‚              β”‚    β”‚              β”‚       β”‚
β”‚  β”‚             │───▢│ Private IP:  β”‚    β”‚ Private IP:  β”‚       β”‚
β”‚  β”‚ 172.31.1.x  β”‚SSH β”‚ 172.31.1.243 β”‚    β”‚ 172.31.1.48  β”‚       β”‚
β”‚  β”‚             │───▢│              β”‚    β”‚              β”‚       β”‚
β”‚  β”‚ Polls GitHubβ”‚    β”‚ Ubuntu 20.04 β”‚    β”‚ Ubuntu 20.04 β”‚       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚
β”‚         β”‚                    β”‚                    β”‚             β”‚
β”‚         β”‚                    β”‚                    β”‚             β”‚
β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚
β”‚                              β”‚                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β”‚
                               β–Ό
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚   AppDynamics    β”‚
                    β”‚    Controller    β”‚
                    β”‚  (SaaS/On-Prem)  β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Workflow Execution Flow

Complete Deployment Sequence

sequenceDiagram
    participant Dev as Developer
    participant GH as GitHub
    participant Runner as Self-hosted Runner
    participant Target as Target Host(s)

    Dev->>GH: 1. Push code or trigger workflow
    GH->>GH: 2. Workflow event triggered
    Runner->>GH: 3. Poll for jobs (HTTPS:443)
    GH->>Runner: 4. Assign job to runner
    Runner->>Runner: 5. Execute prepare job<br/>(load host matrix)
    
    par Parallel Execution
        Runner->>Target: 6a. SSH to Host 1<br/>(port 22)
        Runner->>Target: 6b. SSH to Host 2<br/>(port 22)
        Runner->>Target: 6c. SSH to Host 3<br/>(port 22)
    end
    
    Target->>Target: 7. Execute commands<br/>(install/uninstall/stop/clean)
    Target-->>Runner: 8. Return results
    Runner-->>GH: 9. Report job status
    GH-->>Dev: 10. Notify completion

Component Details

GitHub Repository

Stores:

  • 11 workflow YAML files
  • Smart Agent installation package
  • Configuration file (config.ini)

Secrets:

  • SSH private key

Variables:

  • Host list (DEPLOYMENT_HOSTS)
  • User/group settings (optional)

Self-hosted Runner

Location:

  • AWS VPC (same as targets)
  • Private network access

Responsibilities:

  • Poll GitHub for workflow jobs
  • Execute workflow steps
  • SSH to target hosts
  • File transfers (SCP)
  • Parallel execution
  • Error collection

Requirements:

  • Ubuntu/Amazon Linux 2
  • Outbound HTTPS (443) to GitHub
  • Outbound SSH (22) to target hosts
  • SSH key authentication

Access:

  • Outbound HTTPS (443) to GitHub
  • Outbound SSH (22) to target hosts
  • Uses SSH key authentication

Target Hosts

Pre-requisites:

  • Ubuntu 20.04+
  • SSH server running
  • User with sudo access
  • Authorized SSH key

Post-deployment:

/opt/appdynamics/
└── appdsmartagent/
    β”œβ”€β”€ smartagentctl
    β”œβ”€β”€ config.ini
    └── agents/
        β”œβ”€β”€ machine/
        β”œβ”€β”€ java/
        β”œβ”€β”€ node/
        └── db/

Security Architecture

Security Layers

  1. AWS VPC Isolation

    • Private subnet for hosts
    • No direct internet access required
    • VPC flow logs enabled
  2. Security Groups

    • SSH (22) within same security group only
    • HTTPS (443) outbound for GitHub access
    • Stateful firewall rules
  3. SSH Key Authentication

    • No password authentication
    • Keys stored in GitHub Secrets
    • Temporary key files on runner
    • Keys removed after workflow
  4. GitHub Security

    • Repository access controls
    • Branch protection rules
    • Secrets never exposed in logs
    • Environment variable masking
  5. Network Security

    • Private IP communication only
    • No public IPs required
    • Runner in same VPC as targets

Workflow Categories

The system includes 11 workflows organized into 4 categories:

GitHub Actions Workflows (11 Total)
β”œβ”€β”€ Deployment (1 workflow)
β”‚   └── Deploy Smart Agent (Batched)
β”œβ”€β”€ Agent Installation (4 workflows)
β”‚   β”œβ”€β”€ Install Node Agent (Batched)
β”‚   β”œβ”€β”€ Install Machine Agent (Batched)
β”‚   β”œβ”€β”€ Install DB Agent (Batched)
β”‚   └── Install Java Agent (Batched)
β”œβ”€β”€ Agent Uninstallation (4 workflows)
β”‚   β”œβ”€β”€ Uninstall Node Agent (Batched)
β”‚   β”œβ”€β”€ Uninstall Machine Agent (Batched)
β”‚   β”œβ”€β”€ Uninstall DB Agent (Batched)
β”‚   └── Uninstall Java Agent (Batched)
└── Smart Agent Management (2 workflows)
    β”œβ”€β”€ Stop and Clean Smart Agent (Batched)
    └── Cleanup All Agents (Batched)

Batching Strategy

All workflows use automatic batching to support deployments at any scale.

How Batching Works

HOST LIST (1000 hosts)              BATCH_SIZE = 256

Host 001: 172.31.1.1                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
Host 002: 172.31.1.2      ────────▢ β”‚   BATCH 1        β”‚
    ...                              β”‚   Hosts 1-256    β”‚ ───┐
Host 256: 172.31.1.256               β”‚   Sequential     β”‚    β”‚
                                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
Host 257: 172.31.1.257               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
Host 258: 172.31.1.258   ────────▢  β”‚   BATCH 2        β”‚    β”‚ SEQUENTIAL
    ...                              β”‚   Hosts 257-512  β”‚    β”‚ EXECUTION
Host 512: 172.31.1.512               β”‚   Sequential     β”‚    β”‚
                                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
Host 513: 172.31.1.513               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
    ...                              β”‚   BATCH 3        β”‚    β”‚
Host 768: 172.31.1.768   ────────▢  β”‚   Hosts 513-768  β”‚ β”€β”€β”€β”˜
                                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Host 769: 172.31.1.769               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    ...                              β”‚   BATCH 4        β”‚
Host 1000: 172.31.2.232  ────────▢  β”‚   Hosts 769-1000 β”‚
                                     β”‚   (232 hosts)    β”‚
                                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

WITHIN EACH BATCH:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  All hosts deploy in PARALLEL          β”‚
β”‚                                        β”‚
β”‚  Host 1 ──┐                           β”‚
β”‚  Host 2 ───                           β”‚
β”‚  Host 3 ──┼─▢ Background processes (&)β”‚
β”‚    ...    β”‚                           β”‚
β”‚  Host 256β”€β”˜   └─▢ wait command        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Why Sequential Batches?

Resource Management:

  • Prevents overwhelming the self-hosted runner
  • Each batch opens 256 parallel SSH connections
  • Sequential processing ensures stable performance

Configurable:

  • Default batch size: 256 (GitHub Actions matrix limit)
  • Adjustable via workflow input for smaller batches
  • Balance between speed and resource usage

Scaling Characteristics

Deployment Speed (default BATCH_SIZE=256):

  • 10 hosts β†’ 1 batch β†’ ~2 minutes
  • 100 hosts β†’ 1 batch β†’ ~3 minutes
  • 500 hosts β†’ 2 batches β†’ ~6 minutes
  • 1,000 hosts β†’ 4 batches β†’ ~12 minutes
  • 5,000 hosts β†’ 20 batches β†’ ~60 minutes

Factors affecting speed:

  • Network bandwidth (19MB package per host)
  • SSH connection overhead (~1s per host)
  • Target host CPU/disk speed
  • Runner resources (CPU/memory)

Next Steps

Now that you understand the architecture, let’s move on to setting up GitHub and configuring the self-hosted runner.