Terraform Theory

Mizan FirdausiMizan Firdausi
7 min read

1. What is Terraform and how it is different from other IaC tools?

  • Terraform is a Business Source License infrastructure as a code software tool created by HashiCorp. Users define and provide data center infrastructure using a declarative configuration language known as HashiCorp Configuration Language (HCL), or optionally JSON.

  • It uses a declarative configuration language.

  • Supports multi-cloud environments (AWS, Azure, GCP, etc.).

  • Manages infrastructure state.

  • Promotes modularity and reusability.

  • Boasts a large ecosystem of modules and providers.

  • Favors immutable infrastructure practices.

  • Efficient parallel resource provisioning.

  • Differs from imperative IaC tools like Ansible and Puppet.

2. How do you call a "main.tf" module?

  • Calling a main.tf module in Terraform isn't a standard practice since main.tf is typically the entry point for your Terraform configuration. Instead, you typically create separate .tf files for different modules and use those within your main configuration.

  • Here's how to call/reference a module from your main.tf:

# Initialize your module with source and any required variables
module "example" {
  source = "./my_module"  # This path should be relative to your main configuration
  variable1 = "value1"    # Replace with actual variable values
  variable2 = "value2"
}

# You can reference outputs from the module if it defines any
output "module_output" {
  value = module.example.output_variable_name
}
  • In this example:

  • module "example" initializes the module and specifies its source (the path to the module). Adjust the source path according to your project structure.

  • You can pass values to the module's variables within the block.

  • If the module defines outputs, you can reference them using the module.example.output_variable_name.

3. What exactly is Sentinel? Can you provide few examples that we can use for Sentinel policies?

  • Sentinel is an open-source policy as a code framework from HashiCorp. It allows you to define policies that can be enforced against many different types of services, including Terraform.

Terraform (IaC) Policies:

  • Enforce access control for who can manage infrastructure.

  • Ensure resource names follow a specific convention.

  • Enforce tagging for tracking and security.

  • Implement resource quotas.

Vault Access and Secrets Policies:

  • Define who can authenticate to Vault.

  • Enforce fine-grained access controls on secrets.

  • Ensure encryption of sensitive data.

Consul Network Security:

  • Control which services can communicate.

  • Segment data centers to prevent cross-data-center access.

Compliance and Security:

  • Define policies for regulatory compliance (HIPAA, GDPR, etc.).

  • Enforce security best practices (encryption, access controls).

Cost Management:

  • Set budget controls to limit spending on cloud resources.

  • Automate resource cleanup to reduce costs.

Custom Business Policies:

  • Create policies tailored to specific business requirements (e.g., library usage).

4. You have a Terraform configuration file that defines an infrastructure deployment. However, there are multiple instances of the same resource that need to be created. How would you modify the configuration file to achieve this?

  • To create multiple instances of the same resource in Terraform, you can use resource "count" or resource "for_each" depending on your specific use case. The choice between "count" and "for_each" depends on whether you want to dynamically manage the lifecycle of each resource.

  • "count" is used to create multiple instances of a resource that are identical in configuration, but independent in lifecycle. For example, you might use "count" to create multiple EC2 instances that are identical in configuration, but you want to be able to manage them independently (e.g., destroy one instance without destroying the others).

  • "for_each" is used to create multiple instances of a resource that are identical in configuration and dependent in lifecycle. For example, you might use "for_each" to create multiple IAM users that are identical in configuration and you want to manage them as a group (e.g., destroy all users at once).

  • Here's an example of using "count" to create multiple EC2 instances:

resource "aws_instance" "example" {
  count = 3

  ami           = "ami-a1b2c3d4"
  instance_type = "t2.micro"
}
  • Here's an example of using "for_each" to create multiple IAM users:
variable "users" {
  type = list(string)
  default = [
    "user1",
    "user2",
    "user3",
  ]
}

5. The below command will destroy everything that is being created in the infrastructure. Tell us how would you save any particular resource while destroying the complete infrastructure.

terraform destroy

The terraform destroy command's significance can be summarized in simple points:

    1. Infrastructure Termination: It dismantles and removes all the infrastructure created by Terraform.
    1. Dependency Handling: Destroys resources in the correct order based on dependencies.
    1. State File Update: Updates the Terraform state file to reflect the destroyed resources.
    1. Interactive Confirmation: Asks for confirmation to prevent accidental deletions.
    1. Resource De-Provisioning: Communicates with cloud providers to remove resources.
    1. Cost Savings: Ensures you're not paying for resources you no longer need.
    1. Safety Precautions: Use with care, as it permanently deletes resources, and always have backups.

6. Which module is used to store the .tfstate file in S3?

  • The module used to store the Terraform .tfstate file in an Amazon S3 bucket is typically provided by the Terraform block within your Terraform configuration. You can specify the backend configuration, including the S3 bucket settings, within this block.

  • Here's an example of how you can configure your Terraform to store the state file in an S3 bucket:

terraform {
  backend "s3" {
    bucket         = "your-s3-bucket-name"
    key            = "path/to/your/terraform.tfstate"
    region         = "us-east-1"  # Your desired region
    encrypt        = true         # Enable encryption of the state file
    dynamodb_table = "terraform-lock"  # Optional: For state locking
  }
}
  • In this configuration:

  • backend "s3" specifies that you want to use the S3 backend for storing the state file.

  • bucket is the name of your S3 bucket.

  • key is the path to your state file within the bucket.

  • region is the AWS region where your S3 bucket is located.

  • encrypt is set to true to enable encryption of the state file.

  • dynamodb_table is an optional configuration for state locking using Amazon DynamoDB. State locking is helpful when you have multiple users or automated processes that might concurrently modify the state file.

7. How do you manage sensitive data in Terraform, such as API keys or passwords?

Certainly, here are three key points for managing sensitive data in Terraform:

  1. Use Environment Variables: Store sensitive data, like API keys or passwords, as environment variables and reference them in your Terraform configuration. This ensures that sensitive information is kept separate from your code.
provider "aws" {
  region = "us-east-1"
  access_key = var.AWS_ACCESS_KEY
  secret_key = var.AWS_SECRET_KEY
}
  1. Utilize Secrets Management Tools: Consider using secrets management tools like HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault to securely store and retrieve sensitive data. These tools provide encryption and access control.

  2. Secure CI/CD Pipelines: Ensure that your CI/CD pipeline handles sensitive data securely. Use secrets management within your pipeline to store and pass sensitive information to your Terraform scripts, and maintain strict access controls.

8. You are working on a Terraform project that needs to provision an S3 bucket, and a user with read and write access to the bucket. What resources would you use to accomplish this, and how would you configure them?

  • Use the aws_s3_bucket resource to create the S3 bucket.

    • -> Specify bucket name, region, and access control list (ACL).
  • Use the aws_iam_user resource to create an IAM user.

    • -> Optionally, create an access key for programmatic access.
  • Create an IAM policy for S3 access, and attach it to the user.

    • -> Define actions and resources for S3 operations in a policy.

9. Who maintains Terraform providers?

  • In summary, Terraform providers can be maintained by:

  • HashiCorp: Maintainer of official Terraform providers.

  • Third-Party Organizations: Some providers are maintained by the organizations offering the services being managed.

  • Open-Source Communities: Community contributors and open-source communities may maintain providers for less common services or niche use cases.

10. How can we export data from one module to another?

To export data from one Terraform module to another:

Source Module (Where Data Is Defined):

  1. In the source module, define the data you want to share using the output block in the module's configuration file (e.g., outputs.tf).

  2. When you run terraform apply, Terraform captures this data in its state.

Target Module (Where Data Is Consumed):

  1. In the target module, fetch the exported data using the data block and terraform_remote_state. Use module.<MODULE_NAME>.<OUTPUT_NAME> to reference the data.

  2. You can then assign this fetched data to a variable in the target module.

This way, you can pass data from one module to another in your Terraform configuration. It's like sharing a value from one module to another so that they can work together effectively.

0
Subscribe to my newsletter

Read articles from Mizan Firdausi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mizan Firdausi
Mizan Firdausi