<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Working in the UI - FortiGate Terraform Web UI</title><link>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/index.html</link><description>Developer guide for extending and customizing the Terraform Configuration Web UI.</description><generator>Hugo</generator><language>en-US</language><atom:link href="https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/index.xml" rel="self" type="application/rss+xml"/><item><title>Annotation Reference</title><link>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_1_annotations.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_1_annotations.html</guid><description>The UI dynamically generates configuration forms by reading @ui- annotations in terraform.tfvars.example files. The scaffold generator auto-creates these annotations from variables.tf metadata; users enrich them for better UI presentation.
Annotation Format Add @ui- annotation comments directly above each variable assignment:
# @ui-label AWS Region # @ui-description Select the AWS region for deployment # @ui-type select # @ui-options us-east-1|us-west-2|eu-west-1 # @ui-default us-west-2 # @ui-group Region Configuration aws_region = "us-west-2" Supported Tags Core Tags Tag Description Example @ui-label Display name in the form # @ui-label AWS Region @ui-description Help text below the field # @ui-description Select the deployment region @ui-type Input control type # @ui-type select @ui-options Values for select (pipe-separated) # @ui-options dev|staging|prod @ui-default Pre-filled value # @ui-default us-west-2 @ui-required Field must be filled # @ui-required true @ui-group Groups related fields # @ui-group Network Settings @ui-show-if Conditional visibility # @ui-show-if enable_tgw=true @ui-source Dynamic data source # @ui-source aws-regions Resource Discovery Tags Used with @ui-source aws-fortinet-resource for tag-based resource lookup:</description></item><item><title>Registering Templates</title><link>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_2_porting_templates.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_2_porting_templates.html</guid><description>How to add Terraform templates to the UI via the template registry.
Overview The UI uses a template registry to manage templates. Instead of placing templates in a local directory, you register a git repository URL and the backend clones it, parses variables.tf, and generates a scaffold tfvars.ui file with UI annotations.
Step 1: Prepare Your Template Your template repository must contain at minimum:
my-template/ ├── main.tf # Required - Terraform configuration ├── variables.tf # Required - Variable definitions (parsed for scaffold) ├── outputs.tf # Optional └── terraform.tfvars.example # Recommended - Pre-annotated defaults The scaffold generator reads variables.tf for variable names, types, defaults, and descriptions. If terraform.tfvars.example exists, its @ui- annotations are merged into the scaffold.</description></item><item><title>Backend APIs</title><link>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_3_backend_apis.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_3_backend_apis.html</guid><description>The backend provides three API routers for template management, configuration, and terraform execution.
API Structure app/api/ ├── templates.py # Template registry CRUD ├── tfvars_ui.py # Scaffold, export/import, drift detection ├── template_terraform.py # Plan/apply/destroy against cloned repos ├── terraform.py # Shared utilities (run_command_stream) ├── aws.py # AWS resource discovery └── gcp.py # GCP resource discovery Template Registry (/api/templates/) CRUD operations for registered templates.
Endpoint Method Description /api/templates/ GET List all registered templates /api/templates/{id} GET Get single template by ID /api/templates/ POST Register new template (clones repo, scans files) /api/templates/{id} PUT Update template (re-clones if URL/branch changes) /api/templates/{id} DELETE Delete template and clean up clone Register a Template curl -X POST http://127.0.0.1:8000/api/templates/ \ -H "Content-Type: application/json" \ -d '{ "name": "My Template", "repo_url": "https://github.com/org/repo.git", "branch": "main", "repo_path": "terraform/aws/my_template" }' Response: Template object with id, name, repo_url, branch, repo_path, created_date, updated_date.</description></item><item><title>Parsers &amp; Services</title><link>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_4_parsers.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_4_parsers.html</guid><description>The backend uses a service layer for parsing, hashing, scaffolding, and drift detection.
Service Layer app/services/ ├── __init__.py # Central exports ├── hcl_parser.py # Parse variables.tf ├── tfvars_example_parser.py # Parse terraform.tfvars.example annotations ├── scaffold_generator.py # Generate tfvars.ui from parsed data ├── git_service.py # Clone/pull git repositories ├── file_hash_service.py # SHA-256 file scanning └── drift_service.py # Drift detection between stored and current hashes HCL Parser (hcl_parser.py) Parses variables.tf to extract variable definitions.
from app.services import parse_variables, HCLVariable variables: list[HCLVariable] = parse_variables(content) Each HCLVariable contains:</description></item><item><title>Cloud Provider APIs</title><link>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_5_cloud_providers.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_5_cloud_providers.html</guid><description>Integrating AWS, Azure, and GCP APIs for dynamic dropdowns.
AWS Provider Integration Location: backend/providers/aws.py
The AWS provider uses boto3 to query AWS resources for dynamic dropdowns.
Adding a New AWS API Example: Adding VPC discovery:
import boto3 def get_vpcs(region: str, credentials: dict) -&gt; List[dict]: """Get VPCs in a region.""" ec2 = boto3.client( 'ec2', region_name=region, aws_access_key_id=credentials.get('access_key'), aws_secret_access_key=credentials.get('secret_key'), aws_session_token=credentials.get('session_token') ) response = ec2.describe_vpcs() return [ { "id": vpc['VpcId'], "cidr": vpc['CidrBlock'], "name": get_tag_value(vpc.get('Tags', []), 'Name') } for vpc in response['Vpcs'] ] Exposing via API Endpoint @router.get("/api/aws/vpcs") async def list_vpcs(region: str): """List VPCs in the specified region.""" credentials = get_current_credentials() if not credentials: raise HTTPException(status_code=401, detail="AWS credentials not configured") vpcs = get_vpcs(region, credentials) return {"vpcs": vpcs} Adding a New Cloud Provider To add support for Azure or GCP:</description></item><item><title>Frontend Development</title><link>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_6_frontend.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_6_frontend.html</guid><description>React components and API client development.
Component Structure frontend/src/ ├── components/ │ ├── TerraformConfig.jsx # Main UI: template selector, form, build controls │ ├── TemplateRegistration.jsx # Modal: register new template from git repo │ ├── DriftResolution.jsx # Modal: side-by-side drift resolution │ └── FormField.jsx # Individual field renderer (text, select, etc.) ├── services/ │ └── api.js # Backend API client └── App.jsx Key Components TerraformConfig.jsx The main UI component. Manages:</description></item><item><title>Testing</title><link>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_7_testing.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_7_testing.html</guid><description>Backend and frontend testing.
Backend Tests The backend has 250+ pytest tests covering all services, database operations, and API endpoints.
cd ui/backend uv run python -m pytest tests/ -v Test Files Test File Coverage test_db.py SQLite CRUD operations (TemplateDB, FileHashDB) test_git_service.py Git clone/pull, cleanup, error handling test_file_hash_service.py SHA-256 scanning, hard-stop classification test_drift_service.py Drift detection logic, status escalation test_hcl_parser.py variables.tf parsing (types, defaults, validation) test_tfvars_example_parser.py Annotation extraction, value parsing test_scaffold_generator.py tfvars.ui generation, annotation merging test_templates_api.py Template registry CRUD endpoints test_tfvars_ui_api.py Scaffold, export, import, drift endpoints test_template_terraform_api.py Terraform plan/apply/destroy endpoints Running Specific Tests # Run a single test file uv run python -m pytest tests/test_drift_service.py -v # Run tests matching a pattern uv run python -m pytest tests/ -k "test_scaffold" -v # Run with coverage uv run python -m pytest tests/ --cov=app --cov-report=term-missing Test Configuration Tests use asyncio_mode = "auto" in pyproject.toml, so no @pytest.mark.asyncio decorators are needed. API tests use httpx.AsyncClient with the FastAPI test client.</description></item><item><title>Troubleshooting</title><link>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_8_troubleshooting.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fortinetcloudcse.github.io/fortinet-ui-terraform/2_getting_started/2_1_working_in_the_ui/2_1_8_troubleshooting.html</guid><description>Common issues and fixes for UI development.
Backend Issues ModuleNotFoundError cd ui/backend uv sync Port Already in Use lsof -i :8000 kill -9 &lt;PID&gt; Database Errors If the SQLite database is corrupted or schema is outdated:
# Delete and recreate (data will be lost) rm -f ui/backend/data/registry.db # Restart backend — tables are auto-created on startup Git Clone Failures If template registration fails with a git error:</description></item></channel></rss>