Export PingOne resources to Terraform configuration with automatic dependency resolution and import block generation.
- Complete DaVinci Export: Export PingOne environments, DaVinci flows, variables, connector instances, applications, and flow policies
- Multiple Output Formats: Supports Terraform HCL (
.tf) or Terraform JSON (.tf.json) output - Automatic Dependency Resolution: Generates Terraform references between resources
- Import Block Generation: Terraform import blocks to manage existing resources (Terraform 1.5+)
- Module Structure: Generates reusable Terraform modules with proper variable scaffolding
- Dual Mode Operation: Works as standalone CLI or Ping CLI plugin
- Two-Environment Authentication: Isolate credentials from exported resources
Download from GitHub Releases.
brew install pingidentity/tap/pingcli-plugin-terraformer# Debian/Ubuntu
sudo dpkg -i pingcli-terraformer_*.deb
# RHEL/CentOS/Fedora
sudo rpm -i pingcli-terraformer_*.rpm
# Alpine
sudo apk add pingcli-terraformer_*.apkdocker run --rm \
-e PINGCLI_PINGONE_ENVIRONMENT_ID="..." \
-e PINGCLI_PINGONE_CLIENT_CREDENTIALS_CLIENT_ID="..." \
-e PINGCLI_PINGONE_CLIENT_CREDENTIALS_CLIENT_SECRET="..." \
-v $(pwd)/output:/output \
ghcr.io/pingidentity/pingcli-plugin-terraformer:latest \
export --out /outputgit clone https://github.com/pingidentity/pingcli-plugin-terraformer.git
cd pingcli-plugin-terraformer
make build- PingOne environment with DaVinci
- PingOne worker application with DaVinci API Read access
- Terraform 1.5+ (for import blocks)
| Variable | Description |
|---|---|
PINGCLI_PINGONE_ENVIRONMENT_ID |
Worker environment ID (authentication) |
PINGCLI_PINGONE_EXPORT_ENVIRONMENT_ID |
Target environment to export (optional, defaults to worker env) |
PINGCLI_PINGONE_CLIENT_CREDENTIALS_CLIENT_ID |
OAuth2 client ID |
PINGCLI_PINGONE_CLIENT_CREDENTIALS_CLIENT_SECRET |
OAuth2 client secret |
PINGCLI_PINGONE_REGION_CODE |
Region code: NA, EU, AP, CA, AU |
Export resources from a different environment than where the worker app is configured:
pingcli-terraformer export \
--pingone-worker-environment-id <auth-env-uuid> \
--pingone-export-environment-id <target-env-uuid> \
--pingone-worker-client-id <client-id> \
--pingone-worker-client-secret <secret> \
--pingone-region-code NA \
--out ./outputpingcli-terraformer export \
--pingone-worker-environment-id <uuid> \
--pingone-worker-client-id <client-id> \
--pingone-worker-client-secret <secret> \
--pingone-region-code NA \
--out ./outputpingcli-terraformer export \
--output-format tfjson \
--out ./outputexport PINGCLI_PINGONE_ENVIRONMENT_ID="..."
export PINGCLI_PINGONE_CLIENT_CREDENTIALS_CLIENT_ID="..."
export PINGCLI_PINGONE_CLIENT_CREDENTIALS_CLIENT_SECRET="..."
export PINGCLI_PINGONE_REGION_CODE="NA"
pingcli-terraformer export --out ./output| Flag | Default | Description |
|---|---|---|
--pingone-worker-environment-id |
- | Worker environment ID |
--pingone-export-environment-id |
Worker env | Target environment ID |
--pingone-worker-client-id |
- | OAuth2 client ID |
--pingone-worker-client-secret |
- | OAuth2 client secret |
--pingone-region-code |
NA |
Region: NA, EU, AP, CA, AU |
--out / -o |
stdout | Output directory path |
--output-format |
hcl |
Output format: hcl or tfjson |
--module-name |
ping-export |
Module name prefix |
--module-dir |
ping-export-module |
Child module directory name |
--include-values |
false |
Populate variable values from API |
--include-imports |
false |
Generate import blocks in root module |
--skip-imports |
false |
Skip generating import blocks |
--skip-dependencies |
false |
Use hardcoded UUIDs instead of references |
--include-resources |
- | Include resources matching glob/regex pattern (repeatable) |
--exclude-resources |
- | Exclude resources matching glob/regex pattern (repeatable) |
--include-upstream |
false |
Include upstream dependencies of filtered resources |
--list-resources |
false |
List resource addresses and exit |
| Format | Flag Value | File Extension | Description |
|---|---|---|---|
| HCL | hcl |
.tf |
Standard Terraform HCL syntax (default) |
| Terraform JSON | tfjson |
.tf.json |
Terraform JSON configuration syntax |
| Resource | Terraform Type |
|---|---|
| DaVinci Flow | pingone_davinci_flow |
| DaVinci Variable | pingone_davinci_variable |
| DaVinci Connector Instance | pingone_davinci_connector_instance |
| DaVinci Application | pingone_davinci_application |
| DaVinci Flow Policy | pingone_davinci_application_flow_policy |
Export only specific resources using glob or regex patterns:
| Flag | Description |
|---|---|
--include-resources <pattern> |
Include resources matching pattern(s). Repeatable. Patterns match resource_type.terraform_label (case-insensitive). Use regex: prefix for regex. |
--exclude-resources <pattern> |
Exclude resources matching pattern(s). Repeatable. Same matching rules as include. |
--include-upstream |
Automatically include upstream dependencies of matched resources. Transitive — dependencies of dependencies are also included. |
--list-resources |
List available resource addresses (resource_type.terraform_label) and exit. Useful for discovering exact addresses to filter. |
-
Glob (default):
*matches any characters,?matches single characterpingone_davinci_flow.*— all flowspingone_davinci_variable.dev*— variables starting with "dev"
-
Regex: Prefix pattern with
regex:, uses Go regexp syntaxregex:pingone_davinci_(flow|variable)\..*— flows or variablesregex:^pingone_davinci_flow\.(login|logout)— specific flow names
-
Multiple patterns combine via OR (union)
-
No filters = export all resources (backwards compatible)
Use --include-upstream with --include-resources to automatically pull in resources that matched resources depend on. This follows the dependency graph transitively:
- A flow depends on its connector instances
- A flow_deploy depends on its flow
- A flow_policy depends on its application and flow
- A variable depends on its referenced flow
For example, exporting a single flow with --include-upstream also exports all connector instances used by that flow. Exporting a flow_deploy with --include-upstream exports the deploy, its flow, and all connector instances used by the flow.
Explicit --exclude-resources patterns always take priority over upstream expansion. If an upstream dependency is explicitly excluded, it will not be included and a Terraform variable will be generated as a placeholder.
List all available resource addresses:
pingcli-terraformer export --list-resourcesExport only DaVinci flows and variables:
pingcli-terraformer export \
--include-resources "pingone_davinci_flow.*" \
--include-resources "pingone_davinci_variable.*" \
--out ./outputExport everything except flow policies:
pingcli-terraformer export \
--exclude-resources "pingone_davinci_application_flow_policy.*" \
--out ./outputExport flows with specific name patterns using regex:
pingcli-terraformer export \
--include-resources "regex:pingone_davinci_flow\.(login|mfa|consent)" \
--out ./outputCombine include and exclude (exclude takes precedence for overlaps):
pingcli-terraformer export \
--include-resources "pingone_davinci*" \
--exclude-resources "pingone_davinci_application_flow_policy.*" \
--out ./outputExport a specific flow and all its upstream dependencies:
pingcli-terraformer export \
--include-resources "pingone_davinci_flow.pingcli__My-0020-Flow" \
--include-upstream \
--out ./outputExport flow policies with full dependency chain (policies → apps → flows → connectors):
pingcli-terraformer export \
--include-resources "pingone_davinci_application_flow_policy.*" \
--include-upstream \
--out ./outputExport a flow with upstream, but exclude specific connectors:
pingcli-terraformer export \
--include-resources "pingone_davinci_flow.*" \
--include-upstream \
--exclude-resources "pingone_davinci_connector_instance.pingcli__Http" \
--out ./outputSee CONTRIBUTING.md for development guides, architecture documentation, and how to add new resources.
Apache License 2.0 - see LICENSE.