AWS LAB / CPU EDITION

From CloudShell
to FortiAIGate.

A clear path to your first deployment.
Copy the commands. Check the results. Keep moving.

Ubuntu 22.04FortiAIGate 8.0.2Build 0055
KEEP A LOCAL COPY

Your lab toolkit.

Public editions
  • Use your own lab values. Downloads omit personal instance/account identifiers and the original bucket and prefix-list values. Create asks for your S3 bucket and existing managed prefix list; replace the bucket placeholder in the PDF.
  • Run a downloaded script: in CloudShell, choose Actions → Upload file, upload the .sh file, then run bash create_fortiaigate_vpc.sh or bash destroy_fortiaigate_vpc.sh.
  • Choose one path. Use the prepared lab launcher below, or the downloaded scripts configured for your own AWS environment. Both require AWS permissions; the downloads do not grant access.
PLAN YOUR LAB BUDGET

About ten cents an hour.

CPU lab · USD

One t3a.large instance, 150 GiB gp3 storage and one public IPv4 address in us-east-1.

Per hour
$0.097
1 hour running
Per day
$2.32
24 hours running
Per week
$16.24
7 days running
Per month
$70.55
730 hours running
  • On-Demand estimate, checked 30 Oct 2026. Linux, shared tenancy and Standard CPU credits. Storage is allocated across 730 hours for these comparisons; actual calendar-month billing varies.
  • Additional costs: FortiAIGate licensing, model-provider usage, S3 storage/requests, data transfer, snapshots, optional logging and taxes. Credits and discounts are not included.
  • When you stop the instance, compute charges stop. The 150 GiB disk still costs about $12/month until deleted. Use step 11 when you are finished with the lab.
What is included?+
Base infrastructure estimate in US dollars
ResourceRate730-hour month
EC2 t3a.large$0.0752/hour$54.90
150 GiB gp3$0.08/GiB-month$12.00
1 public IPv4$0.005/hour$3.65

gp3 includes 3,000 IOPS and 125 MiB/s at this storage rate.

BEFORE YOU START

Right place. Complete block.

  • Steps 1 & 11 → CloudShell. Steps 2–9 run on the Ubuntu EC2 instance in Session Manager.
  • Copy one block at a time. The copy button includes every line and the Bash wrapper.
  • Wait for the expected result. If you see STOP, resolve the error before continuing.
01
AWS CloudShell

Launch your AWS lab

#

Start here, in the AWS console.

  • Sign in to the intended AWS account and select US East (N. Virginia) / us-east-1.
  • Open CloudShell using the terminal icon in the AWS console, then paste this complete block.
  • Choose 1 = Create and enter your name prefix. Wait for the script to finish and note the created instance.
  • Use 2 = Destroy only when removing a lab. It previews resources before deletion; shared IAM resources are retained while still used elsewhere.
CloudShell launcher
aws s3 cp "s3://wrady-fortiaigate-lab/scripts/fortiaigate_launcher.sh" \
  "$HOME/fortiaigate_launcher.sh" \
  --region us-east-1 --only-show-errors && \
bash "$HOME/fortiaigate_launcher.sh"
Look forThe launcher shows Create, Destroy and Exit. Choose Create for a new lab.
Good to knowThis prepared lab uses private S3 scripts and an existing managed prefix list. Your AWS identity needs access to those resources and permission to provision the lab. The public guide does not grant AWS access.
02
EC2 · Session Manager

Connect and check the host

#

Switch from CloudShell to your Ubuntu instance.

  • In EC2, select the instance created for your name prefix. Choose Connect → Session Manager → Connect.
  • Run this block inside that instance. Keep using Session Manager for steps 2–9.
  • Check for Ubuntu 22.04, x86_64, enough disk space, and passwordless sudo.
Host checks
/bin/bash <<'FORTI_SCRIPT' || printf 'STOP: block failed.\n' >&2
set -euo pipefail
sudo -n true
cat /etc/os-release
uname -m
nproc
free -h
df -h /
printf 'PASS: host checks completed; review sizing above.\n'
FORTI_SCRIPT
Look forHost details and PASS: host checks completed. Review the reported CPU, RAM and disk.
Good to knowThe supplied Create script uses t3a.large (2 vCPU / 8 GiB). The bundled installer recommends 8+ CPU cores and 32 GB RAM. Review sizing before deployment; a warning is not proof the full stack will run reliably.
03
EC2 · Session Manager

Repair the Docker repository

#

Set up the signed Docker package source.

  • Copy the entire block, including the opening /bin/bash line and closing FORTI_SCRIPT line.
  • Existing docker.list and docker.sources files are backed up before replacement.
  • Wait for APT to finish. Key and source-file writes are silent; the final output confirms completion.
Docker repository repair
/bin/bash <<'FORTI_SCRIPT' || printf 'STOP: block failed.\n' >&2
set -euo pipefail
sudo -n true
. /etc/os-release
[ "$ID" = ubuntu ]
[ "$VERSION_ID" = 22.04 ]
[ "$(dpkg --print-architecture)" = amd64 ]
printf 'Repairing Docker repository...\n'
forti_backup=$(sudo mktemp -d /etc/apt/docker-backup.XXXXXX)
for name in docker.list docker.sources; do
  path="/etc/apt/sources.list.d/$name"
  if [ -f "$path" ]; then sudo mv "$path" "$forti_backup/"; fi
done
sudo apt-get update
sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=l \
  apt-get install -y ca-certificates curl unzip
sudo install -m 0755 -d /etc/apt/keyrings
key=/etc/apt/keyrings/docker.asc
sudo curl -fsSL --retry 3 \
  https://download.docker.com/linux/ubuntu/gpg -o "$key"
sudo chmod 0644 "$key"
head -n 1 "$key"
printf '%s\n' \
  'Types: deb' \
  'URIs: https://download.docker.com/linux/ubuntu' \
  'Suites: jammy' \
  'Components: stable' \
  'Architectures: amd64' \
  'Signed-By: /etc/apt/keyrings/docker.asc' \
  | sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null
sudo apt-get update
apt-cache policy docker-ce | sed -n '1,8p'
printf 'Source backup: %s\n' "$forti_backup"
printf 'PASS: repository refresh completed.\n'
FORTI_SCRIPT
Look forThe key starts with BEGIN PGP PUBLIC KEY BLOCK; no signing errors; docker-ce has a real Candidate, not (none).
Good to knowIf another APT source file defines Docker, resolve that duplicate before continuing. Keep APT signature verification enabled.
04
EC2 · Session Manager

Install and verify Docker

#

Install Docker Engine, Buildx and the Compose plugin.

  • Run the block and wait for the test container to finish.
  • Look for Hello from Docker! and a Docker service status of active.
  • Use sudo for Docker commands. No Docker group change is required for this workflow.
Docker installation & smoke test
/bin/bash <<'FORTI_SCRIPT' || printf 'STOP: block failed.\n' >&2
set -euo pipefail
sudo -n true
printf 'Installing Docker Engine and Compose...\n'
sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=l \
  apt-get install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
sudo docker version
sudo docker compose version
sudo docker run --rm hello-world
sudo systemctl is-active docker
forti_docker_root=$(sudo docker info --format '{{.DockerRootDir}}')
df -h "$forti_docker_root" /opt
printf 'PASS: Docker and Compose checks completed.\n'
FORTI_SCRIPT
Look forDocker runs successfully and Compose is 2.23.1 or newer.
Good to knowKeep at least 60 GB free for Docker (120 GB recommended) and 5 GB for assistant state (10 GB recommended). These paths may share the same filesystem.
05
EC2 · Session Manager

Install AWS CLI and verify access

#

Give the Ubuntu host access to the release files.

  • CloudShell already includes AWS CLI; the Ubuntu instance may not. Install the official CLI v2 here.
  • Check that the returned AWS account and assumed role match your lab.
  • Use the instance profile’s temporary credentials. No aws configure or long-lived access keys are needed.
AWS CLI v2 installation
/bin/bash <<'FORTI_SCRIPT' || printf 'STOP: block failed.\n' >&2
set -euo pipefail
sudo -n true
printf 'Downloading and installing AWS CLI v2...\n'
forti_cli_tmp=$(mktemp -d)
trap 'rm -rf -- "$forti_cli_tmp"' EXIT
curl -fsSL --retry 3 \
  https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip \
  -o "$forti_cli_tmp/awscliv2.zip"
unzip -q "$forti_cli_tmp/awscliv2.zip" -d "$forti_cli_tmp"
if [ -d /usr/local/aws-cli/v2 ]; then
  sudo "$forti_cli_tmp/aws/install" --update
else
  sudo "$forti_cli_tmp/aws/install"
fi
/usr/local/bin/aws --version
/usr/local/bin/aws sts get-caller-identity --region us-east-1 --no-cli-pager
printf 'PASS: AWS CLI v2 and EC2 identity verified.\n'
FORTI_SCRIPT
Look foraws-cli/2… and the expected EC2 assumed-role identity.
Good to knowThe EC2 role needs s3:ListBucket for the release prefix and s3:GetObject for its files. A customer-managed KMS key may also require kms:Decrypt.
06
EC2 · Session Manager

Download the FortiAIGate release

#

Fetch the CPU images and Deployment Assistant.

  • Use the staging bucket provided for this lab. If your bucket differs, change the forti_source URI before running.
  • Keep the case-sensitive Images/ and Installer/ folder names.
  • The block downloads the archives to /opt/fortiaigate and checks all seven image TARs. It does not extract the images.
S3 download & archive checks
/bin/bash <<'FORTI_SCRIPT' || printf 'STOP: block failed.\n' >&2
set -euo pipefail
sudo -n true
forti_source=s3://wrady-fortiaigate-lab/FortiAIGate_8.0.2_CPU/
/usr/local/bin/aws s3 ls "$forti_source" --recursive --region us-east-1
sudo install -d -m 0755 -o "$(id -un)" -g "$(id -gn)" /opt/fortiaigate
/usr/local/bin/aws s3 sync "$forti_source" /opt/fortiaigate/ \
  --exclude "*" --include "Images/*.tar" --include "Installer/*.tar.gz" \
  --region us-east-1
cd /opt/fortiaigate
forti_build=V8.0.2-build0055-FORTINET
for part in api webui llm-gateway guardrail guardrail-scanner \
  license_manager logd; do
  file="Images/FAIG_$part-$forti_build.tar"
  printf 'Checking %s\n' "$file"
  test -s "$file"
  tar -tf "$file" >/dev/null
done
test -s "Installer/FAIG_deploy-docker-compose-cli-$forti_build.tar.gz"
printf 'PASS: seven CPU images and the installer are present.\n'
FORTI_SCRIPT
Look forPASS: seven CPU images and the installer are present.
Good to knowA repeated sync may copy nothing if the files already match. That is normal. Hidden .DS_Store files are excluded.
BEFORE STEP 7 · KNOW YOUR FILES7 images + 1 installer

What did we just download?

  • An image is a packaged component. Each .tar contains ready-built FortiAIGate software and its dependencies. Importing it makes the image available to Docker; it does not start the application.
  • The installer is separate. Installer/*.tar.gz contains the Deployment Assistant and its user guide. In step 7, you extract and test this assistant.
01

apiManagement backend

Handles the management requests behind the interface and the application’s configuration.

02

webuiBrowser interface

Provides the screens for setup, policies, monitoring and licensing.

03

llm-gatewayAI request gateway

Handles requests between your applications and configured model providers, calling guardrails for inspection.

04

guardrailContent checks

Coordinates checks, including CPU regex screening, and sends eligible checks to scanner backends.

05

guardrail-scannerScanner backend

Supplies the backend used by policy-guard. Model-based policy checks remain disabled in this CPU deployment.

06

license_managerLicensing service

Provides the licensing services used by the FortiAIGate runtime.

07

logdActivity logging

Handles application logs so you can review activity and investigate problems.

Same release, different componentsFAIG_<component>-V8.0.2-build0055-FORTINET.tarReplace <component> with one of the seven names above. All seven files live in Images/.

Component roles follow the bundled 8.0.2 Deployment Assistant. More about Docker images ↗

07
EC2 · Session Manager

Extract and test the installer

#

Validate the Deployment Assistant before opening the wizard.

  • Extract only deploy-docker-compose.sh and USER-GUIDE.md from the installer archive.
  • Run the shell syntax check and built-in self-test.
  • Stay signed in as your non-root SSM user. The assistant invokes sudo when it needs Docker access.
Installer extraction & self-test
/bin/bash <<'FORTI_SCRIPT' || printf 'STOP: block failed.\n' >&2
set -euo pipefail
sudo -n true
cd /opt/fortiaigate/Installer
forti_installer=FAIG_deploy-docker-compose-cli-V8.0.2-build0055-FORTINET.tar.gz
tar -tzf "$forti_installer"
tar -xzf "$forti_installer" deploy-docker-compose.sh USER-GUIDE.md
chmod 755 deploy-docker-compose.sh
bash -n deploy-docker-compose.sh
./deploy-docker-compose.sh --self-test
FORTI_SCRIPT
Look forThe archive lists both expected files and the assistant prints Self-test passed.
BEFORE STEP 8 · HOW IT FITS TOGETHERDocker Compose

One application. Several containers.

IMAGEThe package

Software saved in the TAR files you downloaded.

CONTAINERA running component

Docker runs an instance of an image as a container.

COMPOSEThe coordinator

A tool that reads a configuration and runs the connected services together.

  • The assistant creates the plan. Your wizard answers become a Compose configuration describing images, ports, connections and storage. You do not need to write the YAML file yourself.
  • Then you import and deploy. Import loads the seven images into Docker. Deploy uses Compose to start the stack with your settings.
  • The stack has supporting services too. PostgreSQL stores application data, Redis holds shared runtime data, and nginx routes HTTPS traffic. Their images come from Docker Hub, or must already be loaded locally; they are not part of the seven FortiAIGate TARs.
CPU lab scopeThis guide covers management and regex guardrails. Model-based DLP and natural-language policy checks need the additional GPU deployment components. Seven image archives do not necessarily mean seven running containers.

How Docker Compose works ↗

08
EC2 · Session Manager

Configure and deploy the stack

#

Open the interactive wizard, then import and deploy.

  • Launch the assistant with this separate interactive command; it keeps terminal input available for your answers.
  • Resolve every prerequisite FAIL. Review CPU and RAM warnings before continuing.
  • Use the CPU lab selections below for Deployment Assistant 0.6.3.
Interactive Deployment Assistant
/bin/bash -c '
cd /opt/fortiaigate/Installer &&
exec /bin/bash ./deploy-docker-compose.sh
'
Look forThe assistant completes its prerequisite checks and opens the setup wizard.

Your wizard selections

Image source
1 · Release archive folder
Image directory
/opt/fortiaigate/Images
Target release
Select 8.0.2-build0055 by number
HTTPS / HTTP redirect
443 / 8081; loopback-only: 1 = Yes
GPU content inspection
2 = No
Gateway memory / log budget
Enter 4 GB / 8 GB explicitly
Deployment namespace
fortiaigate
FortiCare proxy
2 = No if direct HTTPS access works

Import the images

  • In the main menu, choose 5 → 1 to import and verify target images.
  • Expect Imported 7 image archive(s) and PASS for all seven CPU components.
  • Choose 7 to return.

Deploy

  • Choose main menu 3. Confirm the release and ports.
  • Choose 1 = Yes for the recovery archive, record its protected path, then type APPLY.
  • Wait for startup checks and Compose validation. Use 4 → 1 for status and health.
  • Allow outbound HTTPS to fds1.fortinet.com and Docker Hub for third-party images.
09
EC2 · Session Manager

Verify containers and the WebUI

#

Check the running application before onboarding.

  • Run the status and local HTTPS check after deployment completes.
  • Check that PostgreSQL and Redis are healthy and application containers remain up without restart loops.
  • A logd-api-ready helper that finishes with Exited (0) is normal.
Container status & local WebUI
/bin/bash <<'FORTI_SCRIPT' || printf 'STOP: block failed.\n' >&2
set -euo pipefail
sudo -n true
cd /opt/fortiaigate/Installer/faig_deployment_assistant_data/deployment
sudo ./compose.sh ps -a
forti_http=$(curl -ksS --max-time 15 -o /dev/null -w '%{http_code}' \
  https://127.0.0.1/ui)
printf 'WebUI HTTP %s\n' "$forti_http"
test "$forti_http" = 200
printf 'PASS: local WebUI returned HTTP 200.\n'
FORTI_SCRIPT
Look forWebUI HTTP 200 and PASS: local WebUI returned HTTP 200.
Good to knowThe local curl check allows the installer’s self-signed certificate. If it fails, use assistant 5 → 3 for logs, or compose.sh logs --tail 200.
10
Browser → EC2

Onboard, license and finish

#

Complete the initial setup, then verify real requests.

  • Allow HTTPS 443 in the instance security group from your current public IP /32.
  • In your browser, open https://<public-ip>/ui. Verify you reached your instance before accepting its self-signed certificate.
  • Create the administrator and organization. Set the external URL to https://<public-ip>, without /ui.
  • Upload a valid FortiAIGate .lic file under Settings → License and verify it is Active.
  • Return to EC2 Session Manager and run the API restart below. Recheck readiness in assistant 4 → 1.
API restart after onboarding
/bin/bash <<'FORTI_SCRIPT' || printf 'STOP: block failed.\n' >&2
set -euo pipefail
sudo -n true
cd /opt/fortiaigate/Installer/faig_deployment_assistant_data/deployment
sudo ./compose.sh restart api
sudo ./compose.sh ps -a
printf 'PASS: API restart command completed; review status.\n'
FORTI_SCRIPT
Look forVerify login, Active license, healthy containers and a successful gateway request.

Final checks

  • For CPU regex protection, send a synthetic matching test string. Confirm the request is denied and logged.
  • CPU mode supports management and regex guardrails. Triton DLP/model inspection and vLLM natural-language evaluation require GPU deployment.
  • Keep generated state and the recovery archive secure.
11
AWS CloudShell

Destroy the lab when finished

#

Return to CloudShell when you are ready to remove this lab.

  • Leave the instance’s Session Manager session and open AWS CloudShell in the intended account, in us-east-1.
  • Run the same launcher below, then choose 2 = Destroy.
  • Enter your name prefix, full VPC name or VPC ID. Names are matched without regard to letter case.
  • Review the account, selected VPC and deletion inventory. Choosing 1 or pressing Enter confirms permanent deletion of the listed resources. No snapshots are created.
CloudShell launcher · choose 2 to destroy
aws s3 cp "s3://wrady-fortiaigate-lab/scripts/fortiaigate_launcher.sh" \
  "$HOME/fortiaigate_launcher.sh" \
  --region us-east-1 --only-show-errors && \
bash "$HOME/fortiaigate_launcher.sh"
Look forThe script confirms the VPC and inventoried resources were deleted, or reports what remains and why.
Good to knowShared IAM roles, instance profiles and their policies are retained while used outside the selected lab. The source S3 bucket and existing managed prefix list are retained.
WHEN SOMETHING NEEDS A FIX

A quick way forward.

Docker says NO_PUBKEY or “no installation candidate”+
  • Return to step 3 and run the complete repository repair block.
  • Check for duplicate Docker APT sources. Keep signature verification enabled.
The shell shows pipefail errors or joined commands+
  • Press Ctrl+C to cancel an incomplete paste.
  • Use the Copy button again, including the first and last lines. Press Enter after the closing line if needed.
  • Setup blocks start their own Bash process; do not paste only their middle lines into sh.
AWS CLI is missing, or S3 returns AccessDenied+
  • Install AWS CLI on the instance using step 5; commands use /usr/local/bin/aws.
  • Check the instance profile’s ListBucket/GetObject permissions and any required KMS permissions.
  • For the launcher, check that your CloudShell identity can read the scripts bucket.
The WebUI returns 502 or containers keep restarting+
  • Open assistant 4 → 1 for health and 5 → 3 for logs.
  • Check CPU/RAM sizing and available disk space. Then repeat step 9.
How do I remove the lab?+
  • Run the CloudShell launcher in step 11, choose 2 = Destroy, then enter your name prefix or VPC ID.
  • Review the deletion plan carefully. Choosing 1 or pressing Enter permanently deletes the listed resources; no snapshots are created.
  • IAM resources still used by another instance or Auto Scaling group are retained. A VPC can be deleted while shared IAM resources remain.