Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,36 @@ Migrate workloads from other platforms to [StackGuardian Platform](https://app.s
## Supported platforms for migration

- Terraform Cloud
- Git VCS (GitHub, GitLab) — create workflows directly from Terraform repositories

## Overview

- Extract and transform the workloads from the target platform to StackGuardian Workflows.
- Review the bulk workflow creation payload.
- Run sg-cli with the bulk workflow creation payload.

## Transformers

### Git VCS (GitHub / GitLab)

Create workflows from Terraform repositories without needing Terraform Cloud. See [transformer/git-vcs/README.md](transformer/git-vcs/README.md) for full docs.

```shell
cd transformer/git-vcs
pip install .
sg-git-scan --provider github --token ghp_xxx --org my-org
```

### Terraform Cloud

Migrate workspaces from Terraform Cloud/Enterprise.

## Prerequisites

- An organization on [StackGuardian Platform](https://app.stackguardian.io)
- Optionally, pre-configure VCS, cloud integrations or private runners to use when importing into StackGuardian Platform.
- Terraform
- Terraform (for the Terraform Cloud transformer)
- Python 3.10+ (for the Git VCS transformer)
- [sg-cli](https://github.com/StackGuardian/sg-cli/tree/main/shell)

### Perform terraform login
Expand Down
3 changes: 3 additions & 0 deletions transformer/git-vcs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
sg-payload.json
104 changes: 104 additions & 0 deletions transformer/git-vcs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Git VCS Transformer

Create StackGuardian workflows from Terraform repositories hosted on GitHub or GitLab.

This transformer connects to your VCS provider, discovers all Terraform repositories, and generates an `sg-payload.json` that can be used to bulk-create workflows on the [StackGuardian Platform](https://app.stackguardian.io).

## How it works

1. **Discover** — Lists repositories in your GitHub org or GitLab group via API
2. **Scan** — Fetches the file tree of each repo and detects directories containing `.tf` files
3. **Transform** — Maps each Terraform project to a StackGuardian workflow payload, inferring:
- Terraform version (from `required_version`)
- Cloud provider (from `provider` blocks → `DeploymentPlatformConfig`)
- VCS source config (repo URL, branch, working directory)
- Extra CLI args (when `.tfvars` files are detected)
4. **Output** — Writes `sg-payload.json` for review and bulk import

## Prerequisites

- Python 3.10+
- A GitHub PAT or GitLab PAT with repo read access
- [sg-cli](https://github.com/StackGuardian/sg-cli) for importing workflows

## Install

```bash
cd transformer/git-vcs
pip install .
```

## Usage

```bash
# Scan a GitHub organization
sg-git-scan --provider github --token ghp_xxx --org my-org

# Scan a GitLab group
sg-git-scan --provider gitlab --token glpat-xxx --org my-group

# Limit to 50 repos, custom output path
sg-git-scan --provider github --token ghp_xxx --org my-org --max-repos 50 --output export/sg-payload.json
```

## CLI Options

```
Required:
--provider, -p VCS provider (github or gitlab)
--token, -t VCS access token

Target:
--org, -o Organization (GitHub) or group (GitLab)
--user, -u User whose repos to scan

Filtering:
--max-repos, -m Maximum repositories to scan
--include-archived Include archived repositories
--include-forks Include forked repositories

StackGuardian defaults:
--wfgrp Workflow group name (default: imported-workflows)
--vcs-auth SG VCS integration path (e.g., /integrations/github_com)
--managed-state Enable SG-managed Terraform state

Output:
--output, -O Output file (default: sg-payload.json)
--quiet, -q Minimal output
--verbose, -v Debug output
```

## After generating sg-payload.json

Use the `example_payload.jsonc` file as a reference and edit the `sg-payload.json` to configure:

- `DeploymentPlatformConfig` — Cloud connector (AWS/Azure/GCP integration ID)
- `VCSConfig.customSource.config.auth` — VCS integration for private repos
- `RunnerConstraints` — Shared or private runner
- `Approvers` — Approval emails
- `MiniSteps` — Notifications and workflow chaining
- `EnvironmentVariables` — Env vars for the workflows

### Bulk import workflows to StackGuardian Platform

```bash
export SG_API_TOKEN=<YOUR_SG_API_TOKEN>
sg-cli workflow create --bulk --org "<ORG NAME>" -- sg-payload.json
```

## Output Format

The `sg-payload.json` is a JSON array of workflow definitions. See `example_payload.jsonc` for the full annotated schema.

Each workflow maps:

| SG Field | Source |
|---|---|
| `ResourceName` | Repo name (+ subdir for monorepos) |
| `WfType` | `TERRAFORM` |
| `TerraformConfig.terraformVersion` | Parsed from `required_version` in `.tf` files |
| `VCSConfig.customSource.config.repo` | Repository URL |
| `VCSConfig.customSource.config.ref` | Default branch |
| `VCSConfig.customSource.config.workingDir` | Subdirectory (for monorepos) |
| `DeploymentPlatformConfig` | Inferred from providers (placeholder if unknown) |
| `Tags` | Repo topics + `terraform` |
79 changes: 79 additions & 0 deletions transformer/git-vcs/example_payload.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
// This is an example of a single workflow entry in the sg-payload.json output.
// The transformer generates a JSON array of these objects — one per Terraform project found.

"ResourceName": "my-terraform-vpc", // workflow name — derived from repo name + subdir for monorepos
"Description": "Workflow for acme-org/my-terraform-vpc", // repo description or auto-generated
"Tags": ["migrated", "terraform", "infrastructure"], // config tags + repo topics

"WfType": "TERRAFORM", // always TERRAFORM for this transformer

"TerraformConfig": {
"managedTerraformState": false, // true if --managed-state or config.managed_terraform_state
"terraformVersion": "1.5.0", // inferred from required_version in .tf files, or default 1.5.0
"approvalPreApply": false // true when approvers list is non-empty
// "extraCLIArgs": "-var-file=terraform.tfvars" // added when .tfvars files are detected
},

"DeploymentPlatformConfig": [
{
"kind": "AWS_RBAC", // inferred from providers (aws→AWS_RBAC, azurerm→AZURE_STATIC, google→GCP_STATIC), or from config
"config": {
"integrationId": "/integrations/aws-dev-account", // from config.yaml or PLEASE_CONFIGURE placeholder
"profileName": "default"
}
}
],

"VCSConfig": {
"iacVCSConfig": {
"useMarketplaceTemplate": false,
"customSource": {
"sourceConfigDestKind": "GITHUB_COM", // auto-detected from provider, or config override
"config": {
"repo": "https://github.com/acme-org/my-terraform-vpc", // repository URL
"ref": "main", // default branch
"isPrivate": true, // from repo metadata
"auth": "/integrations/github_com", // from --vcs-auth or config.vcs_auth_integration
"workingDir": "", // subdirectory path for monorepos (e.g., "infra/vpc")
"includeSubModule": false
}
}
},
"iacInputData": {
"schemaType": "RAW_JSON",
"data": {} // Terraform input variables — empty by default, user can fill in
}
},

"RunnerConstraints": {
"type": "shared" // or "private" with "names": ["runner-group"] from config
},

"Approvers": [], // email addresses from config.approvers

"EnvironmentVariables": [], // from config.environment_variables

"MiniSteps": {
"wfChaining": {
"ERRORED": [],
"COMPLETED": []
},
"notifications": {
"email": {
"ERRORED": [],
"COMPLETED": [],
"APPROVAL_REQUIRED": [],
"CANCELLED": []
}
}
},

"UserSchedules": [],

"CLIConfiguration": {
"WorkflowGroup": {
"name": "imported-workflows" // from --wfgrp or config.wfgrp_name
}
}
}
18 changes: 18 additions & 0 deletions transformer/git-vcs/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "sg-git-scan"
version = "0.1.0"
description = "Scan Git repositories for Terraform and generate StackGuardian bulk workflow payloads"
readme = "README.md"
license = {text = "MIT"}
requires-python = ">=3.10"
dependencies = [
"httpx>=0.25.0",
"python-hcl2>=4.3.0",
]

[project.scripts]
sg-git-scan = "sg_git_scan.cli:main"
3 changes: 3 additions & 0 deletions transformer/git-vcs/sg_git_scan/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""StackGuardian Git VCS Transformer — scan Git repos, generate SG workflow payloads."""

__version__ = "0.1.0"
5 changes: 5 additions & 0 deletions transformer/git-vcs/sg_git_scan/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Allow running as: python -m sg_git_scan"""

from sg_git_scan.cli import main

main()
Loading