What is infrastructure as code?
Learning Objectives
Infrastructure as Code (IaC) is the practice of managing and provisioning your cloud resources through code, rather than manual operations or one-off scripts. Essentially, it lets you script your infrastructure, the same way you script your application code. In doing so, IaC allows you to apply the principles of software development, such as version control and continuous integration, to your infrastructure.
Why is IaC Needed?
- Consistency: IaC allows for a consistent and standardized environment, which reduces errors that can occur when infrastructure is set up manually.
- Scalability: IaC makes it easier to scale infrastructure up or down in response to demand.
- Version Control: Infrastructure can be treated like any other codebase, enabling you to use version control systems to track changes and rollback if needed.
- Collaboration: Developers and operations can work together more seamlessly. Infrastructure becomes part of the application development process.
- Cost-Efficiency: By automating repetitive tasks, you save both time and resources, thus reducing operational costs.
The Evolution from Manual Operations to IaC
- Manual Operations: Initially, system administrators would manually configure servers and other resources. This was time-consuming and error-prone.
- Scripting: Automating configurations through scripts improved the speed but still lacked standardization and could be hard to manage for complex systems.
- Configuration Management Tools: Tools like Ansible, Chef, and Puppet brought more structure but were often specific to certain types of operations.
- Infrastructure as Code: IaC brings a holistic approach, where the entire environment is coded, versioned, and automated.
Introduction to Terraform
Learning Objectives
Terraform is an open-source tool created by HashiCorp that allows you to define and provide infrastructure as code (IaC). It uses its own domain-specific language known as HashiCorp Configuration Language (HCL) and can manage infrastructure across multiple cloud service providers.
Why Choose Terraform?
Provider Agnostic: Terraform isn’t limited to a single cloud. With extensive provider support, you can manage a multi-cloud setup using one framework.
Immutable Infrastructure: Terraform encourages the creation of unchangeable infrastructure. If updates are needed, the current resources are replaced, ensuring consistency and reducing potential drift.
Declarative Syntax: Describe what you want with Terraform’s declarative configuration, and let it handle how to achieve that state.
State Management: Terraform uses a state file to map real-world resources to your configuration, ensuring resources are managed correctly.
Core Concepts in Terraform
Resource: The primary component in a Terraform configuration. A resource represents an infrastructure object, such as a VM or network.
Provider: These are plugins that Terraform uses to interact with cloud service APIs, allowing it to manage resources in those clouds.
Variables: Parameterize your configurations using variables, making your IaC modular and reusable.
State: Terraform’s state maps configurations to real-world resources, tracking the resources it manages.
How does terraform work?
Learning Objectives
Terraform has a structured workflow:
- Initialization: Prepare a Terraform working directory with necessary providers using the
terraform init
command. - Planning: Preview infrastructure changes with
terraform plan
to ensure alignment with your goals. - Applying: Implement the desired infrastructure state using
terraform apply
. - Destroy: To dismantle the infrastructure, use
terraform destroy
.
For further details, dive into Terraform’s official documentation to enhance your understanding and capabilities.
Writing Basic Infrastructure Code
Learning Objectives
Now that you understand the basics of Terraform and the need for Infrastructure as Code, let’s try an exercise that doesn’t interact with any cloud providers. We’ll use the null_resource
for demonstration and learning purposes.
Example: Using null_resource
This example uses Terraform’s null_resource.
resource "null_resource" "example" {
provisioner "local-exec" {
command = "echo Hello, World"
}
}
In this example, we define a null_resource
with the name example
. The local-exec
provisioner will run the command specified (echo Hello, World
) on your local machine when you apply this Terraform configuration.
exercise
- Initialize the Terraform Project: Navigate to a new directory and run
terraform init
. - Write the Code: Create a file named
main.tf
and copy the example code into it. - Plan the Infrastructure: Run
terraform plan
to preview what changes will be made. - Apply the Infrastructure: Run
terraform apply
and confirm by typingyes
.
After completing these steps, you should see the message “Hello, World” printed in your terminal, confirming that the null_resource
was successfully applied.
What Are Terraform Modules
Learning Objectives
What Are Terraform Modules?
Terraform modules encapsulate a piece of Terraform configuration into a reusable, shareable unit. This allows for better organization and abstraction of Terraform code. More details can be found in the Terraform Modules Documentation.
Why Are Terraform Modules Needed?
- Reuse of Code: Avoid repetition of similar blocks of code in different parts of the project.
- Simplified Configuration: Hide the complexity of your setup by exposing only the most relevant variables.
- Version Control: Modules can be versioned, and you can specify which version to use in your main configuration.
Why Are Modules Good?
- Modularity: As the name suggests, Terraform modules bring modularity to your infrastructure. You can encapsulate a whole set of functionalities and features into one module.
- Reusability: Once you’ve written a module for a specific piece of infrastructure, you can reuse it across multiple environments or even multiple projects.
- Maintainability: Using modules makes your Terraform configuration easier to maintain. If a change is needed for a specific piece of infrastructure, you can make the change in just one place.
For best practices on writing modules, check the Terraform Module Best Practices.
Structure of a Terraform Module
A typical module directory structure looks like this:
my_terraform_module/
|-- main.tf
|-- variables.tf
|-- outputs.tf
|-- README.md
main.tf
contains the core resource declarations.variables.tf
contains any input variables that the module accepts.outputs.tf
contains any output variables that the module will produce.README.md
contains documentation for the module.
Example: An AWS S3 Bucket Module
To help you understand how a Terraform module works, let’s create an example of an AWS S3 bucket module. The example includes two parts:
- The code for the module itself.
- How to use the module in a Terraform script.
Code for the Module
First, let’s define the module. Create a new directory for the module and inside it, create a main.tf
file with the following content:
provider "aws" {
region = "eu-west-1"
}
resource "aws_s3_bucket" "this" {
bucket = var.bucket_name
acl = "private"
tags = {
Name = var.bucket_name
Environment = var.environment
}
}
output "bucket_arn" {
value = aws_s3_bucket.this.arn
}
Create a variables.tf
file to declare the input variables:
variable "bucket_name" {
description = "The name of the bucket"
type = string
}
variable "environment" {
description = "The environment this bucket will be part of"
type = string
default = "dev"
}
Using the Module
To use this module in a Terraform script, create a main.tf
in a different directory and refer to the module like this:
module "s3_bucket" {
source = "./path/to/module/directory"
bucket_name = "my-new-bucket"
environment = "prod"
}
output "new_bucket_arn" {
value = module.s3_bucket.bucket_arn
}
Run terraform init
and terraform apply
to create the S3 bucket using your module.
This example should give you a good understanding of how to create a basic Terraform module and how to use it. For more detailed information, you can refer to the Terraform AWS S3 Bucket Documentation and Terraform Modules Documentation.
Terraform State Management and Backends
Learning Objectives
What is Terraform State?
Terraform uses a state file to keep track of the current status of your infrastructure. This state file maps the resources in your configuration to real-world resources, providing a way to store attributes and manage resource properties. It is crucial to understand how Terraform handles this state, especially as you work on larger projects.
Local vs. Remote State
By default, Terraform stores the state file in the local filesystem. However, for any significant project or team-based work, a remote backend is recommended. Remote backends like AWS S3, Azure Blob Storage, or Google Cloud Storage allow you to store the Terraform state in a centralized, shared, and secure location.
Locking State
State locking prevents others from acquiring the lock and ensures that multiple users can’t make conflicting changes. Locking is automatically handled in some backends like AWS S3 when used in conjunction with a DynamoDB table.
AWS S3 as a Backend with DynamoDB Locking
Here is a basic example of how you can set up AWS S3 as a backend for storing your Terraform state file, and use AWS DynamoDB for state locking:
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "terraform.tfstate"
region = "eu-west-1"
dynamodb_table = "my-lock-table"
}
}
This configuration tells Terraform to use an S3 bucket named my-terraform-state-bucket and a DynamoDB table named my-lock-table for state locking.
For more details on various aspects of Terraform state management, you can read the following sections from the official Terraform documentation:
These resources will give you a comprehensive understanding of how to manage Terraform state effectively, including using remote backends like AWS S3 and state locking mechanisms like DynamoDB.
Backlog
Learning Objectives
In software development, we break down complex projects into smaller, manageable parts, which we work on for a week or two. These periods are called “sprints.”
A sprint backlog is like a to-do list. It lists what the team has decided to work on this sprint. It’s chosen from a larger list, usually called the “product backlog,” which holds the entire project to-do list.
The backlog is a set of work designed to build understanding beyond the concepts introduced in the course prep. For your course, we have prepared a backlog of mandatory work for each sprint. You will copy these tasks into your own backlog. You can also add any other tickets you want to work on to your backlog, and schedule all of the tasks according to your own goals and capacity. Use your planning board to do this.
You will find the backlog in the Backlog view on every sprint.
Copy the tickets you are working on to your own backlog. Organise your tickets on your board and move them to the right column as you work through them. Here’s a flowchart showing the stages a ticket goes through:
activity
- Find the sprint backlog
- Copy your tickets to your own backlog
- Organise your tickets on your board