If you're looking to start working with AWS and dive into the world of Terraform, this article is your comprehensive guide. We'll walk you through setting up your Terraform project to work seamlessly with AWS and share essential best practices for a smooth transition.
Section 1: Getting Started with AWS
1.1 Create Your AWS Account
We begin by creating your AWS account, which is your gateway to AWS services. Follow our step-by-step guide to set up your AWS account quickly and efficiently.
1.2 Configure Users
Learn how to configure user accounts in AWS, ensuring proper access control for your team members
1.3 Set Up the AWS CLI
Discover how to install and configure the AWS CLI (Command Line Interface) for managing AWS resources from your local environment.
We have to Configure AWS CLI credentials. In this article I will use Long-term credentials option. But it would be better if you use AWS IAM Identity Center (SSO). This is more secure. However you have to use your root user credentials or an IAM user with sufficient permissions to enable AWS SSO to setup this.
Let’s start with Long-term credentials options first.
Go to the AWS Portal, choice user account then Security Credentials
Scrolling to the Access Key
Click to the Create access key button
Choice the first option (Command line Interface – CLI)
Tick to the confirmation checkbox and Click to the Next button.
Because the Secret key only available for the first time so please note that we should copy the value of secret to some where or download csv file before closing the tab.
Section 2: AWS CLI and Terraform
2.1 Installing AWS CLI
Get hands-on with the AWS CLI installation process. Check your installation with aws --version.
2.2 Configure AWS CLI Credentials
Explore different options for configuring AWS CLI credentials, including long-term credentials and more secure AWS IAM Identity Center (SSO) configurations.
Filling the value corresponding to aws configure command
Now, we are going to create a resource group, that helps us to manage resources better via Tags management.
It will show you the result
Section 3: Setting Up Remote State Storage
3.1 Using AWS S3 for Remote State
Secure Remote Backends: Store the Terraform state in secure remote backends such as AWS S3.
In AWS, the Services should be enabled tagging the tag. That can help us to manage services better. It is also the tagged the service into the resource group
After creating the S3 bucket, we can see it on the AWS portal.
Go to the Resource group and check. Awesome, they look as expected.
Section 4: DynamoDB for State Locking
4.1 Understanding State Locking
As you know that, using DynamoDB for state locking enhances the reliability and scalability of Terraform workflows, especially in environments with multiple users or automation processes working concurrently. It helps ensure that infrastructure changes are applied safely and consistently while preventing conflicts and data corruption.
Terraform uses state files to keep track of resource information and dependencies. When multiple users or automation processes work with Terraform concurrently, there's a risk of conflicts and data corruption. DynamoDB provides built-in concurrency control mechanisms, ensuring that only one process can acquire a lock for a particular state file at a given time. This prevents conflicts and ensures consistent state management.
Terraform provides built-in support for using DynamoDB as a backend for state locking. Configuring Terraform to use DynamoDB is straightforward, and it seamlessly integrates with the Terraform CLI.
So, we are going to create Dynamo table
4.2 Creating a DynamoDB Table
Step-by-step instructions on creating a DynamoDB table to serve as the state locking mechanism
It should be also tagged then it will show in the resource group
Awesome, now let’s start write Terraform code
Section 5: Writing Terraform Modules
5.1 Terraform Configuration
Setting up your Terraform project with the required providers, including AWS and optional Kubernetes configurations.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.16.2"#"~> 4.16"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = ">= 2.16.1"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-east-1"
}
terraform {
backend "s3" {
bucket = "s3-terraform-state-use1"
key = "terraform.tfstate" # State file name
region = "us-east-1" # Use your desired AWS region
encrypt = true # Optionally, enable server-side encryption
dynamodb_table = "ddb-statelock-table" # Optional, use a DynamoDB table for state locking
}
}
5.2 Creating a Resource Group
Learn how to define a Terraform resource group to organize AWS resources based on tags.
resource "aws_resourcegroups_group" "rg" {
name = join("-", [var.resource_type, var.application, var.application_environment, var.region_short])
resource_query {
query = <<JSON
{
"ResourceTypeFilters": [
"AWS::AllSupported"
],
"TagFilters": [
{
"Key": "Environment",
"Values": ["${var.workload_environments}"]
},
{
"Key": "ApplicationEnvironment",
"Values": ["${var.application_environment}"]
},
{
"Key": "OpsTeam",
"Values": ["${var.ops_team}"]
},
{
"Key": "Owner",
"Values": ["${var.owner}"]
},{
"Key": "Criticality",
"Values": ["${var.business_criticality}"]
},{
"Key": "OpsCommitment",
"Values": ["${var.ops_commitment}"]
},{
"Key": "ApplicationName",
"Values": ["${upper(var.application)}"]
}
]
}
JSON
}
}
5.3 Configuring S3 Buckets
Create S3 buckets for your infrastructure components, making them public and configuring website settings.
resource "aws_s3_bucket" "s3" {
bucket = join("-", [var.resource_type, var.application, var.application_environment, var.region_short]) #"s3-static-website-bucket" # Make the bucket public
tags = {
Environment = var.workload_environments
ApplicationEnvironment = var.application_environment
OpsTeam = var.ops_team
Owner = var.owner
Criticality = var.business_criticality
OpsCommitment = var.ops_commitment
ApplicationName = upper(var.application)
}
depends_on = [ var.resource_group]
}
resource "aws_s3_bucket_website_configuration" "s3_website" {
bucket = aws_s3_bucket.s3.id
index_document {
suffix = "index.html"
}
error_document {
key = "error.html"
}
routing_rule {
condition {
key_prefix_equals = "docs/"
}
redirect {
replace_key_prefix_with = "documents/"
}
}
depends_on = [ var.resource_group]
}
Section 6: Module Integration in Main Configuration
6.1 Integrating the Resource Group Module
See how to call and configure the resource group module in your
main configuration.
module "rg" {
for_each = var.application_environments
source = "./modules/resource-group"
resource_type = "rg"
application = var.organization
workload_environments = var.workload_environments
application_environment = each.value #var.application_environment#
region = var.region
region_short = var.region_short
ops_team = var.ops_team
owner = var.owner
business_criticality = var.business_criticality
ops_commitment = var.ops_commitment
}
6.2 Integrating the S3 Bucket Module
Integrate the S3 bucket module into your main configuration and link it to your resource group.
module "s3" {
for_each = var.application_environments
source = "./modules/bucket"
resource_type = "s3"
application = var.organization
workload_environments = var.workload_environments
application_environment = each.value #var.application_environment#
region = var.region
region_short = var.region_short
ops_team = var.ops_team
owner = var.owner
business_criticality = var.business_criticality
ops_commitment = var.ops_commitment
resource_group = module.rg[each.value]
resource_group_id = module.rg[each.value].resource_group_id
resource_group_arn = module.rg[each.value].resource_group_arn
}
Source code: https://github.com/namphuongtran/aws-infrastructure
By the end of this article, you'll have a firm grasp of setting up AWS and Terraform for your infrastructure needs. The included best practices will ensure you're working efficiently and effectively in your new AWS environment.
Top comments (0)