<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: José Vitor</title>
    <description>The latest articles on DEV Community by José Vitor (@jsvitor).</description>
    <link>https://dev.to/jsvitor</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2336824%2Fb181ad49-07c7-4201-821e-b3b8cc1b8983.jpg</url>
      <title>DEV Community: José Vitor</title>
      <link>https://dev.to/jsvitor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jsvitor"/>
    <language>en</language>
    <item>
      <title>Terraform Quick Reference Guide</title>
      <dc:creator>José Vitor</dc:creator>
      <pubDate>Wed, 13 Nov 2024 03:16:38 +0000</pubDate>
      <link>https://dev.to/jsvitor/terraform-quick-reference-guide-10gd</link>
      <guid>https://dev.to/jsvitor/terraform-quick-reference-guide-10gd</guid>
      <description>&lt;p&gt;This comprehensive guide serves as a practical reference for Terraform, covering everything from core architecture and essential commands to syntax patterns and industry best practices. Whether you're new to Infrastructure as Code (IaC) or an experienced practitioner, you'll find valuable snippets, real-world examples, and curated learning resources to enhance your Terraform skills.&lt;/p&gt;

&lt;p&gt;While not intended as a complete tutorial, this guide complements the official &lt;a href="https://www.terraform.io/docs/index.html" rel="noopener noreferrer"&gt;Terraform Documentation&lt;/a&gt; by providing a focused overview of key concepts and practical implementations. Each section includes references to detailed resources for deeper learning.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Terraform?
&lt;/h3&gt;

&lt;p&gt;For short, Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. So you can develop all your infrastructure as code (IaC) and manage it through Terraform (without the need to manually provision and configure resources). It's amazing!&lt;/p&gt;

&lt;p&gt;I recommend you to access the &lt;a href="https://roadmap.sh/terraform" rel="noopener noreferrer"&gt;Terraform Roadmap&lt;/a&gt; to see the steps to become a Terraform expert.&lt;/p&gt;

&lt;h2&gt;
  
  
  Terraform architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7zfrxvsdeec6g1pgk1a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7zfrxvsdeec6g1pgk1a.png" alt="Terraform Architecture image by the author" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Terraform architecture consists in a set of components that work together to manage infrastructure. This components are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CLI&lt;/strong&gt;: The command line interface for Terraform. It is used to interact with the Terraform runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration files&lt;/strong&gt;: The configuration is the code that describes the infrastructure that you want to manage. It is written in Terraform Configuration Language (HCL). Which is a declarative language that describes the infrastructure in a human readable format. So you can focus on the what and not the how.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State&lt;/strong&gt;: The state is an important component of Terraform. It is a file that stores the details of the managed infrastructure. The state is used to track the details of the infrastructure and to ensure that the desired state is achieved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime&lt;/strong&gt;: The runtime is responsible for executing the Terraform code and managing the state of the infrastructure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plugins&lt;/strong&gt;: Plugins are the way Terraform interacts with the infrastructure. They are responsible for executing the Terraform code and managing the state of the infrastructure.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Providers&lt;/strong&gt;: Providers are plugins that allow Terraform to manage infrastructure. For example, the AWS provider allows Terraform to manage AWS infrastructure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provisioners&lt;/strong&gt;: Provisioners are plugins used to execute scripts or commands on the remote resource after it is created. For example, the AWS provider has a provisioner that allows you to execute a script on the remote resource after it is created.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Modules&lt;/strong&gt;: Modules are not a component, but a way to package and reuse infrastructure code. They are a fundamental concept in Terraform that allow you to create reusable, modular, and maintainable infrastructure. Some providers have their own modules in the &lt;a href="https://registry.terraform.io/" rel="noopener noreferrer"&gt;Terraform Registry&lt;/a&gt;. For example:

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://registry.terraform.io/namespaces/terraform-google-modules" rel="noopener noreferrer"&gt;Terraform Registry - Google Cloud Modules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://registry.terraform.io/namespaces/terraform-aws-modules" rel="noopener noreferrer"&gt;Terraform Registry - AWS Modules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://registry.terraform.io/namespaces/Azure" rel="noopener noreferrer"&gt;Terraform Registry - Azure Modules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Basic Commands
&lt;/h2&gt;

&lt;p&gt;Now let's see some basic commands to get you started with Terraform. Also you can find a awesome cheat sheet for Terraform commands and syntax &lt;a href="https://cheat-sheets.nicwortel.nl/terraform-cheat-sheet.pdf" rel="noopener noreferrer"&gt;here&lt;/a&gt; from &lt;a href="https://nicwortel.nl" rel="noopener noreferrer"&gt;Nic Wortel&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# The first step is to initialize the Terraform working directory where the state will be stored, the plugins will be downloaded and the backend will be configured through the terraform configuration files `*.tf`.&lt;/span&gt;
terraform init

&lt;span class="c"&gt;# Preview changes&lt;/span&gt;
terraform plan &lt;span class="nt"&gt;-out&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tfplan

&lt;span class="c"&gt;# Apply changes&lt;/span&gt;
terraform apply &lt;span class="s2"&gt;"tfplan"&lt;/span&gt;

&lt;span class="c"&gt;# Taint a resource, this is useful when you need to force a replacement of the resource&lt;/span&gt;
terraform taint aws_instance.example &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; terraform apply &lt;span class="s2"&gt;"tfplan"&lt;/span&gt;

&lt;span class="c"&gt;# Destroy infrastructure&lt;/span&gt;
terraform destroy

&lt;span class="c"&gt;# Format code&lt;/span&gt;
terraform &lt;span class="nb"&gt;fmt&lt;/span&gt;

&lt;span class="c"&gt;# Validate configuration&lt;/span&gt;
terraform validate

&lt;span class="c"&gt;# Show current state&lt;/span&gt;
terraform show

&lt;span class="c"&gt;# Import existing infrastructure&lt;/span&gt;
terraform import aws_instance.example i-1234567890abcdef0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Basic Syntax
&lt;/h2&gt;

&lt;p&gt;As mentioned before, Terraform Configuration Language (HCL) is a declarative language that describes the infrastructure in a human readable format. So you can focus on the what and not the how. As programmers we are used to write imperative code, where we tell the computer what to do step by step. But in Terraform we write declarative code, where we tell the computer what we want and the computer figures out how to do it. So let's see some basic syntax for defining a Terraform configuration file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# First we need to configure the provider&lt;/span&gt;
&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-west-2"&lt;/span&gt;
  &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"default"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Then we need to define the resources we want to create&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-123456"&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;

  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"example-instance"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Then we can use data sources to get information about the infrastructure from the provider.&lt;/span&gt;
&lt;span class="c1"&gt;# In this example we are fetching the latest Ubuntu AMI from the AWS provider.&lt;/span&gt;
&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="s2"&gt;"aws_ami"&lt;/span&gt; &lt;span class="s2"&gt;"ubuntu"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;most_recent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

  &lt;span class="nx"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"name"&lt;/span&gt;
    &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Variables&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"environment"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dev"&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Environment name"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Outputs&lt;/span&gt;
&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"instance_ip"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;public_ip&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Local values, these are useful when you need to define a value that is used in multiple resources.&lt;/span&gt;
&lt;span class="nx"&gt;locals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;common_tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Environment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;
    &lt;span class="nx"&gt;Project&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"MyProject"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✔️ To see more about Terraform configuration language, access the &lt;a href="https://developer.hashicorp.com/terraform/tutorials/configuration-language" rel="noopener noreferrer"&gt;Write Terraform Configuration&lt;/a&gt; tutorials in the Terraform documentation. This is a great resource to learn through practical examples and use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Variables and References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You can specify descriptions, default values, types and constraints, validation rules, and sensitive values.&lt;/li&gt;
&lt;li&gt;Also you can use variables to reference other variables, locals, and data sources.&lt;/li&gt;
&lt;li&gt;Variables can be passed in at runtime, from a file, from environment variables, or from a remote secrets management service.&lt;/li&gt;
&lt;li&gt;Variables types can be &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;bool&lt;/code&gt;, &lt;code&gt;list&lt;/code&gt; (or &lt;code&gt;tuple&lt;/code&gt;), &lt;code&gt;set&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt; (or &lt;code&gt;object&lt;/code&gt;), one special type that has no type: &lt;code&gt;null&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;see more at &lt;a href="https://developer.hashicorp.com/terraform/language/expressions/types" rel="noopener noreferrer"&gt;Types and Values&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Variable types&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"ports"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"settings"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"key1"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"value1"&lt;/span&gt;
    &lt;span class="s2"&gt;"key2"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"value2"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Variable references&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# Local references, these are useful when you need to reference a value that is defined in a local block.&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;common_tags&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ways to populate variables
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Hardcoded values&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;From a file, &lt;code&gt;terraform.tfvars&lt;/code&gt; or &lt;code&gt;*.auto.tfvars&lt;/code&gt; or &lt;code&gt;*.tfvars.json&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From command line, &lt;code&gt;terraform plan -var="environment=prod"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;From command line, &lt;code&gt;terraform plan -var-file="terraform.tfvars"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tfvars&lt;/code&gt; example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"prod"&lt;/span&gt;
&lt;span class="nx"&gt;region&lt;/span&gt;      &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-west-2"&lt;/span&gt;
&lt;span class="nx"&gt;zone&lt;/span&gt;        &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-west-2a"&lt;/span&gt;
&lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;&lt;p&gt;From environment variables, &lt;code&gt;TF_VAR_environment&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;From a remote secrets management service like AWS Secrets Manager, Google Secrets Manager, or HashiCorp Vault&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Functions
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Variable types&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"ports"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"settings"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"key1"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"value1"&lt;/span&gt;
    &lt;span class="s2"&gt;"key2"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"value2"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Variable references&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;common_tags&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conditional Expressions
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Ternary operator&lt;/span&gt;
&lt;span class="nx"&gt;condition&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;true_val&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;false_val&lt;/span&gt;

&lt;span class="c1"&gt;# Dynamic blocks&lt;/span&gt;
&lt;span class="nx"&gt;dynamic&lt;/span&gt; &lt;span class="s2"&gt;"setting"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;for_each&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;settings&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;setting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;
    &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;setting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Count and For Each
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Count example&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"server"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-123456"&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"server-${count.index}"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# For each example&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_user"&lt;/span&gt; &lt;span class="s2"&gt;"users"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;for_each&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;toset&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"user1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"user2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"user3"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  State Management
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# State commands&lt;/span&gt;
terraform state list
terraform state show aws_instance.example
terraform state &lt;span class="nb"&gt;mv &lt;/span&gt;aws_instance.example aws_instance.new
terraform state &lt;span class="nb"&gt;rm &lt;/span&gt;aws_instance.example
terraform state pull
terraform state push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Workspaces
&lt;/h2&gt;

&lt;p&gt;Workspaces are used to manage multiple environments (dev, prod, staging, etc.) from the same configuration.&lt;br&gt;
See more about &lt;a href="https://developer.hashicorp.com/terraform/cli/workspaces#use-cases" rel="noopener noreferrer"&gt;use cases for workspaces&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Workspace commands&lt;/span&gt;
terraform workspace new dev
terraform workspace &lt;span class="k"&gt;select &lt;/span&gt;prod
terraform workspace list
terraform workspace delete dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Importing Existing Infrastructure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Terraform Import And Outputs&lt;/span&gt;
&lt;span class="c"&gt;# import EC2 instance with id i-abcd1234 into the Terraform resource named "new_ec2_instance" of type "aws_instance"&lt;/span&gt;
terraform import aws_instance.new_ec2_instance i-abcd1234 
&lt;span class="c"&gt;# same as above, imports a real-world resource into an instance of Terraform resource&lt;/span&gt;
terraform import &lt;span class="s1"&gt;'aws_instance.new_ec2_instance[0]'&lt;/span&gt; i-abcd1234
&lt;span class="c"&gt;# List all outputs as stated in code&lt;/span&gt;
terraform output
&lt;span class="c"&gt;# List out a specific declared output&lt;/span&gt;
terraform output instance_public_ip
&lt;span class="c"&gt;# List all outputs in JSON format&lt;/span&gt;
terraform output &lt;span class="nt"&gt;-json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Modules
&lt;/h2&gt;

&lt;p&gt;Terraform modules are a way to package and reuse infrastructure code. They are a fundamental concept in Terraform that allow you to create reusable, modular, and maintainable infrastructure.&lt;/p&gt;

&lt;p&gt;In Terraform you can use modules from the &lt;a href="https://registry.terraform.io/" rel="noopener noreferrer"&gt;Terraform Registry&lt;/a&gt; or you can create your own modules. But I highly recommend using modules from the registry as they are tested and maintained by the Terraform team. So you can focus on building your infrastructure without worrying about the underlying details of the module.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.terraform.io/docs/language/modules/index.html" rel="noopener noreferrer"&gt;Terraform Modules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://registry.terraform.io/modules" rel="noopener noreferrer"&gt;Terraform Module Registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://registry.terraform.io/marketplace" rel="noopener noreferrer"&gt;Terraform Module Marketplace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://registry.terraform.io/browse/modules" rel="noopener noreferrer"&gt;Terraform Module Snippets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.terraform.io/docs/modules/development.html" rel="noopener noreferrer"&gt;Terraform Module Development&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.terraform.io/docs/modules/create.html#module-structure" rel="noopener noreferrer"&gt;Terraform Module Structure&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use consistent naming conventions&lt;/li&gt;
&lt;li&gt;Organize code into modules&lt;/li&gt;
&lt;li&gt;Version control your Terraform code&lt;/li&gt;
&lt;li&gt;Use remote state storage&lt;/li&gt;
&lt;li&gt;Lock state files when working in teams&lt;/li&gt;
&lt;li&gt;Use data sources instead of hardcoding values&lt;/li&gt;
&lt;li&gt;Implement proper variable validation&lt;/li&gt;
&lt;li&gt;Use terragrunt for keeping your code DRY&lt;/li&gt;
&lt;li&gt;Always use version constraints for providers and modules. This ensures that the module is compatible with the provider version.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember to always run &lt;code&gt;terraform plan -out=tfplan&lt;/code&gt; before applying changes and maintain proper documentation for your infrastructure code!&lt;/p&gt;

&lt;h2&gt;
  
  
  📖 References and additional learning resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.terraform.io/docs/index.html" rel="noopener noreferrer"&gt;Terraform Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://registry.terraform.io/" rel="noopener noreferrer"&gt;Terraform Registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.hashicorp.com/terraform" rel="noopener noreferrer"&gt;Terraform Course&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pluralsight.com/resources/blog/cloud/the-ultimate-terraform-cheatsheet" rel="noopener noreferrer"&gt;The Ultimate Terraform Cheatsheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/docs/terraform" rel="noopener noreferrer"&gt;Terraform on Google Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=nvV6yobU710&amp;amp;list=PLpZQVidZ65jO_wtOpLv-HmC9uJgTRB8GT&amp;amp;index=1" rel="noopener noreferrer"&gt;Terraform on Google Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=l5k1ai_GBDE" rel="noopener noreferrer"&gt;Terraform explained in 15 mins | Terraform Tutorial for Beginners&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://spacelift.io/blog/terraform-commands-cheat-sheet" rel="noopener noreferrer"&gt;Terraform Commands Cheat Sheet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>terraform</category>
      <category>infrastructureascode</category>
    </item>
  </channel>
</rss>
