11 useful terraform commands

  • Init project: terraform init. This command will set up modules, download provider modules, and create the .terraform.lock.hcl lock file.

If there is an error with this command, you can delete .terraform directory and .terraform.lock.hcl and re-run terraform init.

  • Show update plan: terraform plan.
    User -target=<resource> to specify a resource.
  • Confirm and apply the update: terraform apply.
    User -target=<resource> to specify a resource.

When running in a non-interactive environment, use terraform apply -input=false -auto-approve to apply the changes without interactive confirmation.

  • Pull remote state: terraform state pull.
  • Push (overwrite) remote state: terraform push <file path>.
  • Display specific resource state: terraform state show <resource name>.
  • Remove resource: terraform state rm <resource name>.
  • Import resource: terraform import <resource name> <args>. <args> depends on the resource definition.
  • Rename resource: terraform mv <old name> <new name>.
  • Move resource between 2 projects with remote backend:
#!/usr/bin/env bash
set -xEeuo pipefail

src=/home/transang/terraform/project1
dst=/home/transang/terraform/sub/dir/project2/
resources=(
	aws_s3_bucket.bucket1
	aws_iam_role.role2
	aws_iam_user.user1
	aws_s3_bucket.bucket2
	aws_iam_policy.policy2
)

main() {
	cd $src
	terraform state pull >/tmp/source.tfstate
	cd $dst
	terraform state pull >/tmp/target.tfstate
	for resource in "${resources[@]}"; do
		terraform state mv -state=/tmp/source.tfstate -state-out=/tmp/target.tfstate "${resource}" "${resource}"
	done
	terraform state push /tmp/target.tfstate
	cd $src
	terraform state push /tmp/source.tfstate
}

(main)

Note: terraform pull is deprecated from v0.12 (but still works), and terraform push does not work anymore from v0.12.

Important: The terraform push command is deprecated, and only works with the legacy version of Terraform Enterprise. In the current version of Terraform Cloud, you can upload configurations using the API. See the docs about API-driven runs for more details.

Note: there are several resources that are not supported by terraforming, such as certificate, CloudFront, cloudwatch, ... You need to inspect them manually with import then show.

Note: if your resource exists in multiple regions, do not forget to switch the region and re-run the script.

AWS_ACCESS_KEY_ID=<put your key>
AWS_SECRET_ACCESS_KEY=<put your key>
AWS_REGION=<put your region>
sources=(
	alb             # ALB
	asg             # AutoScaling Group
	cwa             # CloudWatch Alarm
	dbpg            # Database Parameter Group
	dbsg            # Database Security Group
	dbsn            # Database Subnet Group
	ddb             # DynamoDB
	ec2             # EC2
	ecc             # ElastiCache Cluster
	ecsn            # ElastiCache Subnet Group
	efs             # EFS File System
	eip             # EIP
	elb             # ELB
	help            # Describe available commands or one specific command
	iamg            # IAM Group
	iamgm           # IAM Group Membership
	iamgp           # IAM Group Policy
	iamip           # IAM Instance Profile
	iamp            # IAM Policy
	iampa           # IAM Policy Attachment
	iamr            # IAM Role
	iamrp           # IAM Role Policy
	iamu            # IAM User
	iamup           # IAM User Policy
	igw             # Internet Gateway
	kmsa            # KMS Key Alias
	kmsk            # KMS Key
	lc              # Launch Configuration
	nacl            # Network ACL
	nat             # NAT Gateway
	nif             # Network Interface
	r53r            # Route53 Record
	r53z            # Route53 Hosted Zone
	rds             # RDS
	rs              # Redshift
	rt              # Route Table
	rta             # Route Table Association
	s3              # S3
	sg              # Security Group
	sn              # Subnet
	snst            # SNS Topic
	snss            # SNS Subscription
	sqs             # SQS
	vgw             # VPN Gateway
	vpc             # VPC
)

mkdir -p imports
for source in "${sources[@]}"; do
	docker run \
		--rm \
		--name terraforming \
		-e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \
		-e AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \
		-e AWS_REGION=xx-yyyy-0 \
		quay.io/dtan4/terraforming:latest \
		terraforming $source \
		> imports/$source.tf
	docker run \
		--rm \
		--name terraforming \
		-e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \
		-e AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \
		-e AWS_REGION=xx-yyyy-0 \
		quay.io/dtan4/terraforming:latest \
		terraforming $source --tfstate \
		> imports/$source.tfstate
done
  • Print a single output for command line substitution: terraform output <output-name>.