Overview

Purpose

The upgrade_fortios/ toolset upgrades the FortiOS version on a FortiGate autoscale group running in AWS. It reads the existing terraform.tfstate file to discover the deployment automatically — no manual resource identification is required.


Entry Points

The toolset has two separate entry points — one for each strategy. Run discover.py first for both strategies to build the inventory file.

In-Place:

cd upgrade_fortios
bash state/refresh.sh
python3 scripts/discover.py --state state/autoscale_template.tfstate \
  --target-version 7.6.2 --output state/blue_inventory.json
python3 scripts/inplace_upgrade.py --inventory state/blue_inventory.json

Blue-Green:

cd upgrade_fortios
bash state/refresh.sh
python3 scripts/discover.py --state state/autoscale_template.tfstate \
  --vpc-state state/existing_vpc_resources.tfstate \
  --target-version 7.6.2 --output state/blue_inventory.json
# Then follow the six-phase blue-green procedure

When to Use Each Strategy

In-Place Upgrade

Use in-place when:

  • Upgrading within the same major version (e.g., 7.2.8 → 7.2.13)
  • The deployment is healthy — no known config or licensing issues
  • Brief per-instance restart is acceptable
  • You want the simplest possible upgrade path

Avoid in-place for:

  • Cross-major-version upgrades (e.g., 7.4.x → 7.6.x) — native config sync does not work across major versions; use Path C or blue-green instead
  • Deployments with misconfigured alarms, license sync issues, or other known problems

Blue-Green Upgrade

Use blue-green when:

  • Upgrading across major versions (e.g., 7.4 → 7.6)
  • The existing deployment has known configuration problems (broken alarms, license issues)
  • You need full rollback capability — Blue stays live as a fallback until you confirm cleanup
  • You want to validate the new version under real traffic before committing
Info

Blue-green requires approximately 2x license capacity during the monitoring window (Phase 5) while both Blue and Green ASGs are running simultaneously.


Strategy Comparison

In-Place (Path B)Blue-Green
FortiOS versionsSame major (e.g., 7.2.x)Any (7.4 → 7.6)
Config sync during upgradeRequiredNot required
Traffic gapNone (rolling)None (route flip)
RollbackManual LT revertSingle script, < 60 seconds
CostNormal2x licenses during monitoring window
Terraform stateUnchangedNew Green state added
Typical duration~30 minLonger (full stack deploy + 24–48h monitoring)

Prerequisites

Software

  • Python 3.8 or later
  • boto3 library: pip3 install boto3
  • AWS CLI configured with credentials for the target account

AWS Permissions

The operator’s IAM role or user requires:

ServicePermissions
EC2DescribeInstances, DescribeImages, CreateLaunchTemplateVersion, ModifyLaunchTemplate, DescribeNetworkInterfaces
AutoScalingDescribeAutoScalingGroups, DescribeAutoScalingInstances, UpdateAutoScalingGroup, SuspendProcesses, ResumeProcesses, TerminateInstanceInAutoScalingGroup
ELBv2DescribeTargetHealth, DescribeLoadBalancers, DescribeTargetGroups
EC2 Transit GatewayDescribeTransitGatewayRouteTables, SearchTransitGatewayRoutes, ReplaceTransitGatewayRoute (blue-green only)
CloudWatchDescribeAlarms
LambdaGetFunction
DynamoDBDescribeTable

State Files

The scripts read terraform.tfstate to discover the Blue environment. Get the state file into the upgrade_fortios/state/ directory before running any scripts:

# Refresh from local Terraform working directories
bash upgrade_fortios/state/refresh.sh

# Or for remote S3 backend, pull state manually
cd terraform/autoscale_template
terraform state pull > ../../upgrade_fortios/state/autoscale_template.tfstate
Warning

Always use a fresh state file. An outdated state file can produce incorrect inventory results and cause the upgrade scripts to target the wrong resources.


Toolset Architecture

upgrade_fortios/
├── scripts/
│   ├── discover.py          ← Parse terraform.tfstate → blue_inventory.json
│   ├── inplace_upgrade.py   ← In-place upgrade: Paths A, B, C
│   ├── cutover.py           ← TGW route flip + NAT GW EIP migration
│   ├── rollback.py          ← Revert TGW routes to Blue + EIP rollback
│   └── watch_lambda.sh      ← Stream Lambda CloudWatch logs during upgrade
├── state/
│   ├── refresh.sh                          ← Copy fresh tfstate from terraform/ dirs
│   ├── autoscale_template.tfstate          (Blue autoscale state)
│   ├── existing_vpc_resources.tfstate      (VPC/TGW topology)
│   ├── blue_inventory.json                 (output of discover.py)
│   ├── blue_primary_config.conf            (FortiGate backup — Phase 1)
│   ├── green.tfstate                       (Green stack state — blue-green only)
│   └── cutover_progress.json              (written by cutover.py — used by rollback.py)

Data Flow

autoscale_template.tfstate ──┐
existing_vpc_resources.tfstate─┤
                          discover.py
                      blue_inventory.json
           ┌───────────────────┤
           │                   │
           ▼                   ▼
  inplace_upgrade.py     cutover.py ──→ cutover_progress.json
  (Paths A / B / C)           │                │
                               └───────────────▼
                                          rollback.py

  Blue-Green Phase 2:
  terraform apply (green_inspection_stack) ──→ green.tfstate
  (cutover.py reads green.tfstate outputs for Green attachment ID + NAT GW info)

Operator Confirmation Gates

Both strategies require explicit operator confirmation at each significant step. The scripts will not proceed automatically past a gate — they print the current state, describe the next action, and wait for [y/N] confirmation.

This is intentional: upgrades affect production traffic and should not proceed unattended past checkpoints.


Next Steps