Terraform Plan Quickstart
What is Terraform Plan?
From the official Terraform page:
The terraform plan command creates an execution plan, which lets you preview the changes that Terraform plans to make to your infrastructure.
- Reads the current state of any already-existing remote objects to make sure that the Terraform state is up-to-date
From the StartLeft perspective, the Terraform Plan Processor (slp_tfplan
) leverages the Terraform CLI capabilities
to generate a unique Terraform resource file with the final infrastructure and its configuration.
The slp_tfplan
module
The slp_tfplan
module is the StartLeft Processor responsible for converting an existing Terraform execution plan
(tf-plan
) along with its graphic representation (tf-graph
) into an OTM.
This operation is based on a mapping file that enables the client to define the translations between the Terraform resources and the expected
output in the OTM file.
How does it work?
We rely on the Terraform CLI to deal with the complexity of a Terraform infrastructure deployment, which is summarized in two single files:
- Terraform Plan. It contains all the resources along with its configuration.
- Terraform Graph. It contains the relationships between the resources.
With these two files, we are able to compose a complete architecture diagram by parsing all the components and their relationships.
Once you got familiarized yourself with the basics explained on this page, you will need to know more about how to use and customize the behavior of the processor. To configure your conversions, you should take a look at TFplan mapping page, where you will find all the information you need, from basic to advanced, to build your mapping files.
Apart from this, you may also find interesting the generic usage manuals for the CLI and REST API.
How to use it?
Firstly, it is necessary to generate the tf-plan
and tf-graph
files by the Terraform CLI.
Generating my own Terraform files
Execute the Terraform init (only once):
Generate the Terraform plan file in JSON format:
Generate the Terraform graph file:
Next, you need to have a mapping file to configure the processor mapping behavior.
Terraform Plan Mapping File Example
In the TFplan mapping page you will find all the information you need, from basic to advanced, to build your mapping files.
trustzones:
- type: b61d6911-338d-46a8-9f39-8dcd24abfe91
name: Public Cloud
risk:
trust_rating: 10
$default: true
- type: f0ba7722-39b6-4c81-8290-a30a248bb8d9
name: Internet
risk:
trust_rating: 1
components:
- label: aws_acm_certificate
type: CD-ACM
$singleton: true
- label: aws_cloudwatch_metric_alarm
type: cloudwatch
$singleton: true
- label: aws_dynamodb_table
type: dynamodb
- label: aws_vpc
type: vpc
- label: aws_instance
type: ec2
- label: aws_subnet
type: empty-component
- label: aws_vpc_endpoint
type: empty-component
- label: aws_internet_gateway
type: empty-component
- label: aws_ecs_service
type: elastic-container-service
- label: aws_ecs_task_definition
type: docker-container
- label: ["aws_lb", "aws_elb", "aws_alb"]
type: load-balancer
- label: aws_kms_key
type: kms
$singleton: true
- label: aws_lambda_function
type: aws-lambda-function
- label: aws_cloudwatch_log_group
type: cloudwatch
$singleton: true
- label: ["aws_db_instance", "aws_rds_cluster"]
type: rds
- label: aws_route53_zone
type: route-53
- label: aws_autoscaling_group
type: CD-EC2-AUTO-SCALING
- label: cloudflare_record
type: empty-component
- label: [aws_s3_bucket, aws_s3_bucket_object]
type: s3
- label: aws_secretsmanager_secret
type: CD-SECRETS-MANAGER
$singleton: true
- label: aws_sqs_queue
type: sqs-simple-queue-service
- label: {$regex: ^aws_ssm_\w*$}
type: CD-SYSTEMS-MANAGER
$singleton: true
- label: aws_synthetics_canary
type: empty-component
- label: {$regex: ^aws_api_gateway_\w*$}
type: api-gateway
$singleton: true
- label: {$regex: ^aws_athena_\w*$}
type: athena
$singleton: true
- label: {$regex: ^aws_mq_\w*$}
type: CD-MQ
$singleton: true
- label: {$regex: ^aws_cloudfront_\w*$}
type: cf-cloudfront
$singleton: true
- label: aws_cloudtrail
type: cloudtrail
- label: ["aws_cognito_user_pool", "aws_cognito_identity_pool"]
type: cognito
- label: {$regex: ^aws_config_\w*$}
type: CD-CONFIG
$singleton: true
- label: {$regex: ^aws_ecr_\w*$}
type: elastic-container-registry
$singleton: true
- label: aws_eks_cluster
type: elastic-container-kubernetes
- label: {$regex: ^aws_elasticache_\w*$}
type: elasticache
$singleton: true
- label: {$regex: ^aws_guardduty_\w*$}
type: CD-GUARDDUTY
$singleton: true
- label: {$regex: ^aws_inspector_\w*$}
type: CD-INSPECTOR
$singleton: true
- label: {$regex: ^aws_macie2_\w*$}
type: CD-MACIE
$singleton: true
- label: aws_networkfirewall_firewall
type: CD-AWS-NETWORK-FIREWALL
- label: aws_redshift_cluster
type: redshift
- label: {$regex: ^aws_ses_\w*$}
type: CD-SES
$singleton: true
- label: {$regex: ^aws_sns_\w*$}
type: sns
$singleton: true
- label: {$regex: ^aws_sfn_\w*$}
type: step-functions
- label: {$regex: ^aws_waf(.*)_\w*$}
type: CD-WAF
$singleton: true
- label: {$regex: ^aws_kinesis_analytics_\w*$}
type: kinesis-data-analytics
$singleton: true
- label: {$regex: ^aws_kinesis_stream\w*$}
type: kinesis-data-analytics
$singleton: true
- label: {$regex: ^aws_kinesis_firehose_\w*$}
type: kinesis-data-firehose
$singleton: true
- label: {$regex: ^aws_iam_\w*$}
type: CD-AWS-IAM
$singleton: true
- label: {$regex: ^aws_cloudwatch_event_\w*$}
type: eventbridge
$singleton: true
- label: {$regex: ^aws_codebuild_\w*$}
type: CD-CODEBUILD
$singleton: true
- label: {$regex: ^aws_codepipeline\w*$}
type: CD-CODEPIPELINE
$singleton: true
- label: aws_ebs_volume
type: elastic-block-store
- label: {$regex: ^aws_shield_\w*$}
type: CD-SHIELD
$singleton: true
- label: {$regex: ^aws_cloudformation_\w*$}
type: CD-CLOUDFORMATION
$singleton: true
- label: aws_glue_job
type: CD-GLUE
- label: aws_glue_registry
type: CD-GLUE-SCHEMA-REGISTRY
- label: aws_efs_file_system
type: elastic-file-system
- label: aws_transfer_server
type: CD-TRANSFER-FML
- label: aws_codecommit_repository
type: CD-CODECOMMIT
- label: aws_globalaccelerator_accelerator
type: CD-GLOBAL-ACC
- label: {$regex: ^aws_dms_\w*$}
type: CD-DMS
$singleton: true
- label: {$regex: ^aws_iot_\w*$}
type: CD-IOT-CORE
$singleton: true
- label: {$regex: ^aws_medialive_\w*$}
type: CD-MEDIALIVE
$singleton: true
- label: {$regex: ^aws_gamelift_\w*$}
type: CD-GAMELIFT
$singleton: true
- label: {$regex: ^aws_directory_service_\w*$}
type: CD-DIR-SERVICE
$singleton: true
- label: {$regex: ^aws_appsync_\w*$}
type: CD-APPSYNC
$singleton: true
- label: {$regex: ^aws_fms_\w*$}
type: firewall-manager
$singleton: true
- label: aws_neptune_cluster
type: CD-NEPTUNE
- label: aws_ec2_transit_gateway
type: CD-AWS-TRANSIT-GW
- label: {$regex: ^aws_batch_\w*$}
type: CD-BATCH
$singleton: true
- label: aws_elastic_beanstalk_application
type: CD-ELASTIC-BEANSTALK
- label: {$regex: ^aws_dx_\w*$}
type: direct-connect
$singleton: true
- label: aws_emr_cluster
type: CD-EMR
- label: aws_msk_cluster
type: CD-MSK
- label: aws_elastictranscoder_pipeline
type: CD-ELASTIC-TRANSCODER
- label: aws_sagemaker_app
type: CD-SAGEMAKER
# AZURE
- label: [ "azurerm_data_share", "azurerm_data_share_account" ]
type: CD-MICROSOFT-AZURE-DATA-SHARE
- label: azurerm_elastic_cloud_elasticsearch
type: CD-MICROSOFT-AZURE-ELASTICSEARCH
- label: [ "azurerm_media_services_account", "azurerm_media_services_account_filter" ]
type: CD-MICROSOFT-AZURE-MEDIA-SERVICES
configuration:
attack_surface:
client: generic-client
trustzone: f0ba7722-39b6-4c81-8290-a30a248bb8d9
# skip:
# - aws_security_group
# - aws_db_subnet_group
# catch_all: empty-component
Now everything is set up. The last step is to execute the commands for IaC TFPLAN
parsing to generate the OTM.
CLI
Note: Before continue, make sure you have StartLeft properly installed in your machine.
Save the files above in your file system with these names:
tf-plan.json
for the Terraform plan file.tf-graph.gv
for the Terraform graph file.ir-mappings.yaml
for the mapping file.
Now we are going to execute StartLeft for these files so that an ec2.otm
file will be generated in our working
directory.
startleft parse \
--iac-type TFPLAN \
--default-mapping-file ir-mappings.yaml \
--output-file output.otm \
--project-id "my-project" \
--project-name "My project" \
tf-plan.json tf-graph.gv
cURL
You can get the same result through the StartLeft REST API. For that, first, we need to set up the server with the command:
Then, execute the following command to retrieve the OTM file:
curl --location --request POST localhost:5000/api/v1/startleft/iac \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form iac_type="TFPLAN" \
--form iac_file=@"./tf-plan.json" \
--form iac_file=@"./tf-graph.gv" \
--form default_mapping_file=@"./ir-mappings.yaml" \
--form id="my-project" \
--form name="My project"
More examples
The infrastructure built with Terraform may be as complex as you want. For that reason StartLeft, through the mapping files, is intended to be configurable, so you can extend or modify its behavior and/or create your mappings on demand.
To help you to walk through more complex situations with larger Terraform and mapping files, you can see all available examples under the Terraform Examples section.