
Develop fluency with terraform through theory, best practices, and exercises. Explore infrastructure as code, HashiCorp configuration language, resource blocks, input variables, locals, outputs, workspaces, modules, state manipulation, and terraform cloud.
Navigate the Terraform course structure by exploring three GitHub repositories, per-section modules, and a rich set of exercises with descriptions, outcomes, and step-by-step guides, plus solution lectures and downloadable slides.
This lecture guides you through the process of registering a new AWS account, verifying your identity, and navigating the initial setup steps to access the AWS Management Console.
We will enhance the security of your new account by enabling Multi-Factor Authentication (MFA) on the root user, adding a critical layer of protection against unauthorized access.
This lecture covers the creation of a dedicated IAM user with administrative privileges and MFA, ensuring you follow best practices by avoiding the use of the root account for daily operations.
Designed for Windows users, this guide demonstrates how to install the Windows Subsystem for Linux (WSL) and Ubuntu to create a powerful Linux-based development environment directly on your machine.
We will explore file system interoperability between Windows and Linux and set up the Remote - WSL extension in VS Code to ensure a seamless workflow between your IDE and the virtual machine.
You will learn how to install the Terraform binary on your local machine using various package managers or manual downloads, followed by a verification step to ensure the tool is ready for use.
This lecture walks through the installation of the AWS Command Line Interface (CLI) version 2, a necessary tool for interacting with AWS services directly from your terminal.
We will generate access keys for your IAM admin user and configure your local environment variables, allowing Terraform and the CLI to securely authenticate and interact with your AWS account.
This brief lecture recommends installing the official HashiCorp Terraform extension for Visual Studio Code to improve your development experience with syntax highlighting and auto-completion.
This lecture explains the concept of provisioning infrastructure through code rather than manual processes, highlighting the limitations of the console approach regarding reproducibility and error tracking.
Dive into the key advantages of adopting IaC, including improved cost management, reliability, drift detection, and the ability to treat infrastructure as a scalable software project.
Set up the practical exercise where you are challenged to manually create a Virtual Private Cloud (VPC) to understand the complexity involved in non-automated setups.
Walk through the AWS Console to manually provision a VPC, subnets, and route tables, demonstrating the tedious and error-prone nature of managing infrastructure without code.
Prepare for the next challenge by reviewing the requirements to recreate your manual networking infrastructure using Terraform's declarative configuration language.
Write your first Terraform configuration to define the VPC and networking components, illustrating the clean syntax and the ease of linking resources compared to the manual approach.
Explore the specific strengths of Terraform, such as its platform-agnostic nature, modularity, state management, and parallel deployment capabilities compared to other tools.
Understand the plugin-based architecture of Terraform, focusing on how Providers enable interaction with remote APIs and how to effectively utilize the Terraform Registry.
Learn the three critical phases of the Terraform workflow (Plan, Apply, and Destroy) and understand how the engine interacts with remote APIs to reach the desired state.
Get ready to execute the Terraform commands yourself in this guided exercise focused on the hands-on lifecycle of your infrastructure project.
Run the full Terraform lifecycle in your terminal, from initializing the project and planning changes to applying the configuration and eventually destroying the resources.
Prepare for the upcoming theory by attempting to write basic HCL blocks yourself, using the provided resources and guides to familiarize yourself with the syntax.
We walk through the fundamental syntax of HCL, covering how to define resources, use data sources to fetch information, declaring input variables, and exposing values through output blocks.
Learn how to configure the Terraform settings block to specify required Terraform versions and pin provider versions using various constraint operators to ensure consistent deployments.
Put your skills to the test by setting up a complete Terraform project that includes provider configuration and resource creation, following the provided specifications.
Build your first complete project from scratch, including setting up the AWS and Random providers, creating an S3 bucket with a unique name, and outputting the result.
Challenge yourself to explore the Terraform Command Line Interface by executing a variety of essential commands beyond just plan and apply.
Master the CLI by exploring commands like fmt for formatting code, validate for syntax checking, state list for inspecting resources, and understanding the nuances of plan and apply flags.
Dive into the critical concept of state in Terraform, learning how it maps configuration to real-world resources, tracks dependencies, and why it contains sensitive data that must be protected.
Inspect a local state file to understand its structure, including how resources and dependencies are stored, and see how file locking works during operations to prevent corruption.
Understand the different types of backends available for storing state, including local files, S3 buckets, and Terraform Cloud, and the benefits of using a remote backend for collaboration.
Apply your knowledge by attempting to migrate your local state to a remote S3 bucket, a crucial step for team-based infrastructure management.
Walk through the process of creating an S3 bucket and configuring the backend block in Terraform to store your state remotely, ensuring security and accessibility.
Experiment with advanced backend setups by attempting to configure separate environments (dev and prod) using partial configurations and CLI arguments.
Learn how to keep your backend configuration flexible by supplying partial details via separate files or CLI flags, allowing you to reuse code across different environments like development and production.
Revisit the concept of providers to understand their role in Terraform's plugin architecture, how they enable interaction with APIs, and how to manage their versions effectively.
Try configuring the AWS provider to deploy resources into multiple regions within the same project, testing your understanding of provider aliases.
See how to define multiple provider instances using aliases, enabling you to deploy resources to different AWS regions (for example, EU and US) within a single Terraform configuration.
In this lecture, we will explore the syntax and structure of Terraform resource blocks, learning how arguments vary by resource type and how providers are selected for provisioning.
In this lecture, we will examine how Terraform automatically calculates implicit dependencies between resources and how you can enforce explicit ordering using the depends_on meta-argument.
In this lecture, we will dive into powerful configuration options available to all resources, such as count, for_each, and lifecycle rules like create_before_destroy and ignore_changes.
In this lecture, we outline the requirements for your first major hands-on project: deploying an Nginx web server on AWS, complete with a custom VPC, public subnet, and appropriate security configurations.
In this lecture, we begin the project by writing the Terraform code to provision a new Virtual Private Cloud (VPC) and a public subnet, laying the networking foundation for our infrastructure.
In this lecture, we expand our networking setup by deploying an Internet Gateway and configuring a route table to ensure our subnet has public internet access.
In this lecture, we refactor our code to reduce duplication by using locals to define common tags and the merge function to apply them consistently across all resources.
In this lecture, we deploy an EC2 instance into our public subnet using Terraform, discussing how to select the correct AMI and instance type while avoiding unnecessary costs.
In this lecture, we analyze the default security group behavior in AWS and understand why our initial instance is unreachable from the public internet despite having a public IP.
In this lecture, we create a dedicated security group with ingress rules allowing HTTP (port 80) and HTTPS (port 443) traffic and attach it to our EC2 instance to enable web access.
In this lecture, we update our EC2 instance to use a Bitnami Nginx AMI, demonstrating how Terraform handles replacing resources when immutable attributes like the AMI ID are changed.
In this lecture, we explore the lifecycle block's ignore_changes argument to handle external modifications and conclude the project by cleanly destroying all resources to prevent future costs.
In this lecture, we outline the project requirements, including creating an S3 bucket, configuring it for static website hosting, and managing file uploads and permissions to serve a simple HTML site.
In this lecture, we start the project by initializing the Terraform providers and creating an S3 bucket with a unique name generated by the random_id resource to avoid naming conflicts.
In this lecture, we configure the S3 bucket's public access settings and define a bucket policy using Terraform's jsonencode function to securely allow public read access to our website files.
In this lecture, we enable the static website hosting feature on our S3 bucket, specifying the index and error documents, and verify the setup by manually uploading HTML files.
In this lecture, we automate the content deployment by using the aws_s3_object resource to upload our HTML files via Terraform and create an output to display the live website URL in the terminal.
In this lecture, we introduce the concept of Data Sources in Terraform, explaining how they allow you to query and use information from external systems or existing infrastructure without managing it directly.
In this lecture, we challenge you to use a Data Source to dynamically fetch the ID of the most recent Ubuntu AMI, replacing the practice of hardcoding IDs in your configuration.
In this lecture, we walk through the solution for querying the AWS API to find specific AMIs using filters like name and owner, and demonstrate how to use the retrieved ID to launch an EC2 instance.
In this lecture, we task you with using Data Sources to retrieve dynamic metadata about your current AWS environment, specifically the account ID and the active region.
In this lecture, we demonstrate how to use the aws_caller_identity and aws_region Data Sources to make your Terraform code adaptable and aware of the context in which it is running.
In this lecture, we set up a scenario where you must create a VPC manually in the console and then write a Terraform configuration to discover and use that existing VPC based on its tags.
In this lecture, we show how to use the aws_vpc Data Source to filter by tags, enabling you to reference resources created outside of Terraform, such as a manually provisioned production VPC.
In this lecture, we explore how to dynamically list available Availability Zones in the current region using the aws_availability_zones Data Source, avoiding the need to hardcode zone names.
In this lecture, we present an exercise to generate a JSON-formatted IAM policy document using a Data Source instead of writing raw JSON or HCL strings manually.
In this lecture, we construct a complex IAM policy using the aws_iam_policy_document Data Source, highlighting the benefits of validation and the ease of generating properly formatted JSON for AWS permissions.
In this lecture, we introduce the concept of input variables, explaining their purpose in creating customizable configurations and covering essential attributes like type, default values, and sensitive flags.
In this lecture, we challenge you to declare and use a variable for the AWS region, highlighting potential pitfalls when configuring providers dynamically.
In this lecture, we walk through the process of defining a region variable and using it in the provider block, demonstrating how to handle type errors and the risks of changing regions without proper state management.
In this lecture, we present an exercise where you must define variables for EC2 instance size and volume configuration, enforcing strict validation rules to ensure only supported values are accepted.
In this lecture, we implement custom validation logic using the validation block and the contains function to restrict input variables to a specific set of allowed instance types, enhancing configuration safety.
In this lecture, we introduce complex variable types, asking you to refactor your volume configuration into an object variable to group related attributes like size and type together.
In this lecture, we demonstrate how to use object and map variable types to structure complex configuration data, explaining the key differences between them and when to use each for better code organization.
In this lecture, we task you with creating and using terraform.tfvars files to manage variable values, testing your understanding of how Terraform automatically loads and applies these configurations.
In this lecture, we explore the use of terraform.tfvars and custom variable files, showing how to load them automatically or explicitly via the CLI to manage different environment configurations.
In this lecture, we guide you through an exercise to use auto.tfvars files, asking you to experiment with file naming conventions and observe how they override default values automatically.
In this lecture, we demonstrate the behavior of .auto.tfvars files, explaining how they take precedence over standard tfvars files and how Terraform processes them in lexical order.
In this lecture, we analyze the complete hierarchy of variable precedence in Terraform, from environment variables to CLI arguments, ensuring you understand exactly which value will be applied in any scenario.
In this lecture, we perform a necessary cleanup of our project files, removing conflicting variable definitions and ensuring a clean state before moving on to the next topic.
In this lecture, we introduce locals by asking you to define common tags and refactor your resources to use these local values, reducing duplication and improving maintainability.
In this lecture, we implement locals to centralize common logic and tag definitions, demonstrating how to reference local values within resources to keep your configuration DRY (Don't Repeat Yourself).
In this lecture, we challenge you to define an output block that exposes the name of your S3 bucket, allowing you to retrieve this information directly from the Terraform CLI.
In this lecture, we show how to create and query outputs, explaining their utility in exposing resource attributes to the CLI or other modules and how to use the -json flag for programmatic access.
In this lecture, we ask you to experiment with the sensitive flag for both input variables and outputs, observing how Terraform handles these values in the console logs.
In this lecture, we dive into the sensitive attribute, demonstrating how it redacts values from the CLI output while clarifying that the data remains visible in the state file, emphasizing the need for proper state security.
In this lecture, we set the stage for understanding Terraform operators, providing a guide and resources for you to practice using mathematical, equality, and logical operators on your own.
In this lecture, we walk through the practical application of operators, demonstrating how to perform calculations and comparisons within locals and outputs to derive values dynamically.
In this lecture, we challenge you to use for expressions to transform lists, creating a list of doubled numbers and filtering for even numbers using conditional logic.
In this lecture, we walk through the syntax of for expressions with lists, demonstrating how to iterate over elements, apply transformations, and use if clauses to filter results effectively.
In this lecture, we task you with using for expressions to manipulate maps, specifically transforming keys and values and filtering entries based on specific conditions.
In this lecture, we explore the nuances of iterating over maps, explaining the key-value syntax required to generate new maps and discussing constraints like unique keys.
In this lecture, we present a complex scenario where you must convert a list of user objects into a map keyed by username, and conversely, extract a list of usernames from a map.
In this lecture, we solve the transformation challenge by combining list and map iterations, showing how to handle grouping with the ellipsis operator ... and how to access nested properties dynamically.
In this lecture, we introduce splat expressions [*], a concise shorthand for extracting a single attribute from a list of objects, and compare its usage with standard for loops.
In this lecture, we provide a high-level overview of Terraform's extensive built-in function library, categorized by type (string, numeric, collection, encoding, and others), and guide you on how to navigate the documentation.
In this lecture, we ask you to experiment with various functions, such as string manipulation and numeric calculations, to get hands-on experience with Terraform's functional capabilities.
In this lecture, we demonstrate practical examples of composing functions, such as chaining string operations and dynamically reading and decoding YAML files using file and yamldecode.
In this lecture, we introduce the concept of creating multiple resources in Terraform using count and for_each, explaining the key differences between them and when to use each approach.
In this lecture, we challenge you to create multiple AWS subnets using the count meta-argument, requiring you to dynamically calculate CIDR blocks to avoid conflicts.
In this lecture, we demonstrate how to use count.index to generate unique names and non-overlapping CIDR blocks for subnets, resolving common errors associated with resource duplication.
In this lecture, we task you with deploying multiple EC2 instances using count and distributing them across different subnets using a round-robin strategy.
In this lecture, we implement the round-robin distribution logic using the modulo operator % and count.index, ensuring instances are evenly spread across available subnets.
In this lecture, we ask you to refactor your configuration to create EC2 instances based on a list of objects defined in a variable, moving away from simple integer counts.
In this lecture, we show how to drive resource creation from a list variable using count and length, and how to access specific object properties like AMI and instance type for each instance.
In this lecture, we challenge you to extend your configuration to support a second AMI type, allowing users to choose between Ubuntu and Nginx images via a variable.
In this lecture, we integrate a data source for the Nginx AMI and update our local lookup map to dynamically select the correct AMI ID based on the user's input string.
In this lecture, we ask you to add robust validation rules to your list variable, ensuring that users can only provide supported instance types and AMIs.
In this lecture, we implement complex validation logic using the alltrue function and for expressions to enforce strict constraints on the list of configuration objects.
In this lecture, we introduce the for_each meta-argument, challenging you to refactor your EC2 deployment to use a map variable for better stability and flexibility.
In this lecture, we demonstrate the advantages of using for_each with maps, explaining how each.key and each.value provide stable identifiers that prevent unnecessary resource recreation when the order changes.
In this lecture, we task you with porting the validation logic from the list variable to the new map variable, ensuring the same constraints apply to the map-based configuration.
In this lecture, we adapt the validation logic to work with maps by using the values() function to iterate over the map's values and check constraints on instance types and AMIs.
In this lecture, we ask you to refactor the subnet creation to use for_each with a map, allowing named subnets, and to add validation to ensure valid CIDR blocks are provided.
In this lecture, we finalize the refactoring by using for_each for subnets and implementing a custom validation rule using the cidrnetmask and can functions to verify IP address formats.
Welcome to Mastering Terraform: From Beginner to Expert! Are you ready to get hands-on with the industry-leading Infrastructure as Code (IaC) tool? This course is designed to take you from a beginner to a proficient practitioner, equipping you with an in-depth understanding of Terraform concepts.
Why Learn Terraform?
Terraform is an incredibly valuable skill to develop, particularly for those working in the field of DevOps, system administration, or cloud architecture. Here are some reasons why:
Infrastructure as Code (IaC): Terraform allows you to manage and provision your infrastructure through code. This means you can apply version control, peer review, and continuous integration/continuous delivery (CI/CD) practices to your infrastructure, just like you would with application code.
Provider Agnostic: Terraform supports a wide range of service providers, not just AWS. This means you can use it to manage a multi-cloud environment, or even to handle on-premises and cloud resources together.
Efficiency and Speed: Terraform can create, modify, and destroy resources in parallel, leading to faster and more efficient infrastructure management.
Modular and Reusable: Terraform configurations can be packaged as modules and reused, reducing duplication and enhancing maintainability.
Community and Market Demand: Terraform is widely used and supported by a large community. In the job market, there is a high demand for skills in Terraform and other IaC tools.
By mastering Terraform, you'll be equipping yourself with a powerful tool that can greatly enhance your career prospects in the tech industry.
Why Should You Choose This Course?
This course is uniquely designed to offer a blend of theoretical knowledge and practical application, providing a comprehensive understanding of Terraform. We understand that learning is not just about absorbing information, but also about applying that information in real-world situations. This belief is reflected in our course structure and content. Here are some key reasons why you should choose this course to master Terraform:
More than 60 practical exercises: We believe in the power of learning by doing. Our course is packed with over 60 exercises to reinforce the concepts you learn and help you gain hands-on experience with Terraform. All the exercises have detailed descriptions so that you can try everything by yourself before checking the solution videos!
Six comprehensive projects: Apply what you learn in real-world scenarios through our five extensive projects. These projects cover a range of applications, from deploying a static website on S3 to managing users on IAM and creating a reusable RDS module!
Expert guidance: Learn from experienced professionals who are passionate about teaching and dedicated to helping you reach your career goals.
Which Skills Will You Acquire During This Course?
When you decide to participate in this enriching course, you'll have the opportunity to gain and develop a comprehensive range of important skills. This includes, but is not limited to:
Comprehensive understanding of Terraform and its benefits
Ability to create and manage infrastructure using AWS Console and Terraform
Proficiency in managing Terraform backends and providers
Expertise in working with HashiCorp Configuration Language (HCL)
Practical experience in deploying a static website on S3, managing users on IAM, and deploying applications on EC2.
Get ready to elevate your career with our Mastering Terraform: From Beginner to Expert course. Let's start this exciting journey together!