Terraform Mutli environment deploy

Introduction: Deploying and managing infrastructure across multiple environments can be a complex task, but with Terraform, the process becomes streamlined and efficient. In this blog post, we'll explore a scenario where we deploy a common infrastructure consisting of 2 EC2 instances, 1 S3 bucket, and 1 DynamoDB table. Subsequently, we'll create three distinct environments – development (dev), staging, and production – each with specific configurations tailored to their needs.

Infrastructure Overview: Our base infrastructure includes:

  • 2 EC2 instances

  • 1 S3 bucket

  • 1 DynamoDB table

resource "aws_instance" "demo_instance" {
  count = 2 
  ami           = var.ami_id
  instance_type = var.instance_type
  key_name      = aws_key_pair.example_key_pairr.key_name
  tags = {
    Name = "${var.env_name}_${var.instance_name}"
  }
}

resource "aws_default_vpc" "default_vpc" {

}

resource "aws_security_group" "allow_sshh" {
  name        = "allow_ssh_securitygroup"
  description = "Allow ssh inbound traffic"

  # using default VPC
  vpc_id      = aws_default_vpc.default_vpc.id
  ingress {
    description = "TLS from VPC"

    # we should allow incoming and outoging
    # TCP packets
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"

    # allow all traffic
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "allow_ssh"
  }
}



# Create key pair
resource "aws_key_pair" "example_key_pairr" {
  key_name = var.key_pair_name
  public_key = file("~/.ssh/terraformm.pub")
}
resource "aws_dynamodb_table" "basic-dynamodb-table" {
  name         = "${var.env_name}_${var.dynamodb_table}"
  billing_mode = "PAY_PER_REQUEST"

  hash_key = "UserId"
  range_key = "RolNo"

  attribute {
    name = "UserId"
    type = "S"
  }

  attribute {
    name = "RolNo"
    type = "N"
  }

  tags = {
    Name        = "dynamodb-table-1"
    Environment = "production"
  }
}
variable "ami_id" {
 type = string
 description = "this is ami based modeule"
}

variable "instance_type" {
  type = string
  description = "this is instance based on env"
}

variable "instance_name" {
  type = string

}

variable "key_pair_name" {
  type    = string
  default = "terraformm"
}

variable "bucket_name" {
  type = string
}

variable "dynamodb_table" {
  type = string
}

variable "env_name" {
  type = string
}
resource "aws_s3_bucket" "my_demo_bucket" {
  bucket = "${var.env_name}_${var.bucket_name}"
  }

template is completed. and

terraform plan

terraform apply

output of this infra:

Environment-specific Configurations:

Use this template for 3 stages: dev, staging, production using module.

Development (Dev) Environment:

In the dev environment, we focus on lightweight resources to facilitate rapid development and testing.

  • EC2 Instances: 2 Linux instances of type t2.micro.

  • S3 Bucket: A dedicated S3 bucket for dev environment storage.

  • DynamoDB Table: A DynamoDB table configured for development use.

Staging Environment:

The staging environment serves as a pre-production environment for thorough testing before deployment.

  • EC2 Instances:

    • 2 EC2 instances with Ubuntu OS (t2.micro).

    • 2 EC2 instances with Red Hat OS (t2.micro).

  • S3 Bucket: A separate S3 bucket to isolate staging environment data.

  • DynamoDB Table: A dedicated DynamoDB table for staging environment requirements.

Production Environment:

The production environment is designed for stability, reliability, and optimal performance.

  • EC2 Instances: Configured for production demands.

  • S3 Bucket: A production-specific S3 bucket for data storage.

  • DynamoDB Table: A robust DynamoDB table optimized for production workloads.

Terraform Configuration: To achieve this multi-environment setup, the Terraform configuration should be organized in a modular and scalable manner. Leverage Terraform modules for EC2 instances, S3 bucket, and DynamoDB table to promote reusability across environments.

Certainly! If you want to organize the demo-app module with its specific files (dynamodb.tf, s3.tf, ec2.tf, and variables.tf) and keep the provider.tf and terraform.tf files outside the module, here's how you can rewrite those lines:

Now ~/terraform-project :-Create a main.tf file where describe for dev, stage and production environment configuration:

# Development Environment
module "dev-demo-app" {
  source          = "./module/demo-app"
  env_name        = "dev"
  instance_type   = "t2.micro"
  ami_id          = "ami-0a2e7efb4257c0907"
  instance_name   = "first-instance-for-dev"
  bucket_name     = "dev_bucket_asddd"
  dynamodb_table  = "dev-table"
}

# Staging Environment
module "staging-demo-app" {
  source          = "./module/demo-app"
  env_name        = "staging"
  instance_type   = "t2.small"
  ami_id          = "ami-0c00c714c7f84b49d"
  instance_name   = "first-instance-for-staging"
  bucket_name     = "staging_bucket_asddd"
  dynamodb_table  = "staging-table"
}

# Production Environment
module "production-demo-app" {
  source          = "./module/demo-app"
  env_name        = "production"
  instance_type   = "t2.medium"
  ami_id          = "ami-0d270005f18b0539a"
  instance_name   = "first-instance-for-production"
  bucket_name     = "production_bucket_asddd"
  dynamodb_table  = "production-table"
}

if destry only dev environment: it will delete S3 bucket of dev env , dynamodb table of dev env and ec2 instance of dev.

terraform destroy --target=module.qa-demo-app

terraform destroy it will destroy entire infrastructure.

I hope this article serves as a valuable resource for your journey in deploying and managing infrastructure using Terraform. Navigating the complexities of multi-environment deployments can be challenging, but with Terraform, the process becomes streamlined and efficient. By exploring a scenario that deploys a common infrastructure comprising EC2 instances, an S3 bucket, and a DynamoDB table, we've demonstrated the power of Terraform's modular and scalable approach. The provided Terraform configurations for development, staging, and production environments, organized using modules, showcase the flexibility and reusability that Terraform offers. Whether you are a seasoned practitioner or new to infrastructure as code, this article aims to provide insights and practical examples to enhance your Terraform experience. If you have any questions or need further clarification, feel free to reach out. Happy Terraforming!