Automation & Scripting
JSON templates, jq pipelines, idempotent scripts, bulk operations, and GitHub Actions workflows for Megaport CLI automation
Prerequisites
- Megaport CLI installed and configured
- Basic shell scripting (bash)
- jq installed
The Megaport CLI is designed for automation. JSON input mode, structured JSON/CSV output, and consistent exit codes make it composable with shell scripts, CI/CD pipelines, and infrastructure-as-code tooling.
JSON template pattern
Store resource configurations as JSON files in version control. Use environment variables for values that differ between environments.
templates/port-template.json:
{
"name": "${PORT_NAME}",
"locationId": ${LOCATION_ID},
"portSpeed": ${PORT_SPEED},
"term": 12,
"marketPlaceVisibility": false,
"costCentre": "${ENVIRONMENT}"
}
Render and apply:
export PORT_NAME="Sydney Primary"
export LOCATION_ID=3
export PORT_SPEED=10000
export ENVIRONMENT=production
envsubst < templates/port-template.json > /tmp/port-config.json
megaport-cli ports buy --json-file /tmp/port-config.json
For more complex templating (conditionals, loops), use jq to transform a base template:
# Inject a dynamic value into a fixed template
jq --arg name "Sydney Primary" '.name = $name' base-port.json > port.json
megaport-cli ports buy --json-file port.json
Export existing resources as templates
The --export flag on any get command outputs a recreatable JSON config — ready to use with buy --json. This is a fast way to clone resources or build templates from existing infrastructure.
# Export an existing port's config
megaport-cli ports get <PORT-UID> --export > port-template.json
# Modify and create a new port from the template
jq '.name = "Sydney Secondary"' port-template.json > new-port.json
megaport-cli ports buy --json-file new-port.json
Works with all resource types:
megaport-cli mcr get <MCR-UID> --export > mcr-template.json
megaport-cli mve get <MVE-UID> --export > mve-template.json
Scripting flags
Two flags make buy commands script-friendly:
--yes/-y— skip the confirmation prompt (no interactive "are you sure?" question)--no-wait— return immediately after submitting the order instead of waiting for provisioning to complete
# Non-interactive provisioning for CI/CD
megaport-cli ports buy --json-file port.json --yes --no-wait
Chain operations with jq
Parse JSON output from one command and feed it into the next.
# Create a port, then look up its UID to use in subsequent commands
megaport-cli ports buy --json-file port.json
PORT_UID=$(megaport-cli ports list --output json | jq -r '.[] | select(.name == "Sydney Primary") | .uid')
echo "Port created: $PORT_UID"
megaport-cli vxc buy \
--name "Sydney to AWS" \
--a-end-uid "$PORT_UID" \
--a-end-vlan 100 \
--rate-limit 1000 \
--term 12 \
--b-end-partner-config '{"connectType":"AWS","ownerAccount":"123456789012","type":"private"}'
Extract specific fields:
# Get all LIVE port UIDs
megaport-cli ports list --output json | jq -r '.[] | select(.status == "LIVE") | .uid'
# Get port names and speeds as a table
megaport-cli ports list --output json | jq -r '.[] | [.name, (.speed | tostring)] | @tsv'
# Count resources by status
megaport-cli ports list --output json | jq 'group_by(.status) | map({status: .[0].status, count: length})'
Idempotency — check before creating
Avoid creating duplicate resources by checking if they already exist:
check_or_create_port() {
local name="$1"
local config_file="$2"
EXISTING=$(megaport-cli ports list --output json | \
jq -r --arg name "$name" '.[] | select(.name == $name) | .uid')
if [ -n "$EXISTING" ]; then
echo "Port '$name' already exists: $EXISTING"
echo "$EXISTING"
else
echo "Creating port '$name'..."
megaport-cli ports buy --json-file "$config_file"
megaport-cli ports list --output json | \
jq -r --arg name "$name" '.[] | select(.name == $name) | .uid'
fi
}
PORT_UID=$(check_or_create_port "Sydney Primary" port.json)
Error handling
#!/bin/bash
set -euo pipefail
# set -e → exit on error
# set -u → exit on undefined variable
# set -o pipefail → catch failures in pipes
# Validate prerequisites
command -v jq >/dev/null 2>&1 || { echo "jq is required but not installed" >&2; exit 1; }
command -v megaport-cli >/dev/null 2>&1 || { echo "megaport-cli is required but not installed" >&2; exit 1; }
# Trap errors for cleanup
cleanup() {
echo "Script failed — check resources for partial provisioning" >&2
}
trap cleanup ERR
# Test credentials before starting
megaport-cli locations list --output json > /dev/null || {
echo "Authentication failed — check MEGAPORT_ACCESS_KEY and MEGAPORT_SECRET_KEY" >&2
exit 1
}
Bulk operations
Tag all LIVE ports
megaport-cli ports list --output json | \
jq -r '.[] | select(.status == "LIVE") | .uid' | \
while IFS= read -r uid; do
echo "Tagging port: $uid"
megaport-cli ports update-tags "$uid" \
--json '{"env":"production","managed-by":"automation"}'
done
Bulk update cost centres
# Apply cost centre to all ports matching a name pattern
megaport-cli ports list --output json | \
jq -r '.[] | select(.name | startswith("SYD")) | .uid' | \
while IFS= read -r uid; do
megaport-cli ports update "$uid" --cost-centre "AU-INFRA-001"
done
Export all resources to CSV report
#!/bin/bash
DATE=$(date +%Y-%m-%d)
REPORT="megaport-report-${DATE}"
megaport-cli ports list --output csv > "${REPORT}-ports.csv"
megaport-cli mcr list --output csv > "${REPORT}-mcrs.csv"
megaport-cli mve list --output csv > "${REPORT}-mves.csv"
megaport-cli vxc list --output csv > "${REPORT}-vxcs.csv"
echo "Reports generated:"
ls -lh "${REPORT}"*.csv
Health checks and monitoring
# Find any non-LIVE resources (potential issues)
echo "=== Non-LIVE ports ==="
megaport-cli ports list --output json | \
jq '.[] | select(.status != "LIVE") | {name, status, uid}'
echo "=== Non-LIVE VXCs ==="
megaport-cli vxc list --output json | \
jq '.[] | select(.status != "LIVE") | {name, status, uid}'
# Count resources by type
echo "Ports: $(megaport-cli ports list --output json | jq length)"
echo "VXCs: $(megaport-cli vxc list --output json | jq length)"
echo "MCRs: $(megaport-cli mcr list --output json | jq length)"
GitHub Actions workflow
Automate provisioning on push to main. Secrets are injected as environment variables — credentials never touch the codebase.
.github/workflows/provision-network.yml:
name: Provision Megaport Network
on:
push:
branches: [main]
paths:
- 'infrastructure/megaport/**'
workflow_dispatch:
jobs:
provision:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.21'
- name: Install Megaport CLI
run: go install github.com/megaport/megaport-cli@latest
- name: Verify credentials
env:
MEGAPORT_ACCESS_KEY: ${{ secrets.MEGAPORT_ACCESS_KEY }}
MEGAPORT_SECRET_KEY: ${{ secrets.MEGAPORT_SECRET_KEY }}
MEGAPORT_ENVIRONMENT: production
run: megaport-cli locations list --output json > /dev/null
- name: Provision infrastructure
env:
MEGAPORT_ACCESS_KEY: ${{ secrets.MEGAPORT_ACCESS_KEY }}
MEGAPORT_SECRET_KEY: ${{ secrets.MEGAPORT_SECRET_KEY }}
MEGAPORT_ENVIRONMENT: production
run: ./infrastructure/megaport/provision.sh
- name: Export resource report
env:
MEGAPORT_ACCESS_KEY: ${{ secrets.MEGAPORT_ACCESS_KEY }}
MEGAPORT_SECRET_KEY: ${{ secrets.MEGAPORT_SECRET_KEY }}
MEGAPORT_ENVIRONMENT: production
run: |
megaport-cli ports list --output json | jq '.' > artifacts/ports.json
megaport-cli vxc list --output json | jq '.' > artifacts/vxcs.json
- uses: actions/upload-artifact@v4
with:
name: megaport-state
path: artifacts/
Store credentials as GitHub Secrets
Add MEGAPORT_ACCESS_KEY and MEGAPORT_SECRET_KEY under Settings → Secrets and variables → Actions in your repository. Never put credentials in workflow files or commit them to the repo.
Team config management
Onboard new team members and share environment configurations without sharing credentials.
# Export current config — credentials appear as [REDACTED]
megaport-cli config export --file team-config-template.json
# Commit team-config-template.json to your repo
# New team member: import the template, then fill in their credentials
megaport-cli config import --file team-config-template.json
megaport-cli config update-profile production \
--access-key their_access_key \
--secret-key their_secret_key
# Verify
megaport-cli config view
Standardise output format across the team:
# Set in team config template before exporting
megaport-cli config set-default output json
What's next?
- Multi-Cloud Connectivity — a complete automation script building a three-cloud architecture
- Port Lifecycle — the operations you'll automate most often
- Config Profiles — managing profiles for multiple environments