Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,10 @@ coverage/
# Logs
*.log
logs/

# Terraform
**/.terraform/*
*.tfstate
*.tfstate.*
*.tfvars
.terraform.lock.hcl
221 changes: 221 additions & 0 deletions terraform/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
# Terraform Infrastructure as Code

This directory contains Terraform configurations for deploying the Quote App to different environments.

## Structure

```
terraform/
├── modules/
│ ├── docker/ # Docker module (containers, images, networks)
│ └── kubernetes/ # Kubernetes module (pods, services, HPA)
├── environments/
│ ├── dev/ # Development environment (Docker)
│ └── prod/ # Production environment (Kubernetes)
└── main.tf # Root configuration
```

## Prerequisites

- Terraform >= 1.0
- Docker (for dev environment)
- kubectl and Minikube (for prod environment)

## Usage

### Development Environment (Docker)

```bash
cd environments/dev

# Initialize Terraform
terraform init

# Preview changes
terraform plan

# Apply configuration
terraform apply

# Access application
curl http://localhost:3000/health

# Destroy resources
terraform destroy
```

### Production Environment (Kubernetes)

```bash
cd environments/prod

# Ensure Minikube is running
minikube status

# Initialize Terraform
terraform init

# Preview changes
terraform plan

# Apply configuration
terraform apply

# Check deployment
kubectl get all -n quote-app

# Access application
minikube service quote-app-service -n quote-app --url

# Destroy resources
terraform destroy
```

## Modules

### Docker Module

Manages Docker resources:
- Docker images
- Docker containers
- Docker networks
- Health checks

**Variables:**
- `image_name` - Docker image name
- `image_tag` - Image tag (default: latest)
- `container_name` - Container name
- `internal_port` - Container port (default: 3000)
- `external_port` - Host port (default: 3000)
- `environment_vars` - Environment variables (map)
- `restart_policy` - Restart policy (default: unless-stopped)

**Outputs:**
- `container_id` - Container ID
- `container_name` - Container name
- `network_name` - Network name
- `access_url` - Application URL

### Kubernetes Module

Manages Kubernetes resources:
- Namespace
- ConfigMap
- Deployment
- Service (NodePort)
- Horizontal Pod Autoscaler

**Variables:**
- `namespace` - Kubernetes namespace
- `app_name` - Application name
- `image` - Docker image
- `replicas` - Number of replicas (default: 3)
- `container_port` - Container port (default: 3000)
- `service_port` - Service port (default: 80)
- `node_port` - NodePort (default: 30080)
- `environment_vars` - Environment variables (map)
- `cpu_request` - CPU request (default: 100m)
- `cpu_limit` - CPU limit (default: 500m)
- `memory_request` - Memory request (default: 128Mi)
- `memory_limit` - Memory limit (default: 256Mi)
- `hpa_enabled` - Enable HPA (default: true)
- `hpa_min_replicas` - Min replicas (default: 2)
- `hpa_max_replicas` - Max replicas (default: 10)
- `hpa_cpu_threshold` - CPU threshold % (default: 70)

**Outputs:**
- `namespace` - Namespace name
- `deployment_name` - Deployment name
- `service_name` - Service name
- `service_port` - Service port
- `node_port` - NodePort

## Common Commands

```bash
# Initialize
terraform init

# Format code
terraform fmt -recursive

# Validate configuration
terraform validate

# Plan changes
terraform plan

# Apply changes
terraform apply

# Show current state
terraform show

# List resources
terraform state list

# Show outputs
terraform output

# Destroy resources
terraform destroy
```

## State Management

Terraform stores state in `terraform.tfstate` file. This file contains:
- Current infrastructure state
- Resource dependencies
- Metadata

**Important:**
- Never edit state files manually
- Keep state files secure (contain sensitive data)
- For production, use remote state (S3, Terraform Cloud)

## Best Practices

1. **Use modules** for reusable configurations
2. **Separate environments** (dev, staging, prod)
3. **Use variables** for configurable values
4. **Output important values** for easy access
5. **Version control** all Terraform files
6. **Use remote state** for production
7. **Plan before apply** to review changes
8. **Use workspaces** for environment isolation

## Troubleshooting

### Issue: Provider authentication failed

```bash
# For Docker
docker ps # Verify Docker is running

# For Kubernetes
kubectl cluster-info # Verify cluster access
```

### Issue: Resource already exists

```bash
# Import existing resource
terraform import module.quote_app_k8s.kubernetes_namespace.app quote-app

# Or destroy and recreate
terraform destroy
terraform apply
```

### Issue: State lock

```bash
# Force unlock (use with caution)
terraform force-unlock <lock-id>
```

## Additional Resources

- [Terraform Documentation](https://www.terraform.io/docs)
- [Docker Provider](https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs)
- [Kubernetes Provider](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs)
49 changes: 49 additions & 0 deletions terraform/environments/dev/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
terraform {
required_version = ">= 1.0"

required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0"
}
}
}

provider "docker" {
host = "unix:///var/run/docker.sock"
}

module "quote_app_docker" {
source = "../../modules/docker"

image_name = "adityajareda/quote-app"
image_tag = "latest"
container_name = "quote-app-dev"
internal_port = 3000
external_port = 3000

environment_vars = {
NODE_ENV = "development"
PORT = "3000"
APP_NAME = "Quote App"
APP_VERSION = "1.0.0"
LOG_LEVEL = "debug"
}

restart_policy = "unless-stopped"
}

output "container_id" {
description = "Docker container ID"
value = module.quote_app_docker.container_id
}

output "access_url" {
description = "Application access URL"
value = module.quote_app_docker.access_url
}

output "container_name" {
description = "Container name"
value = module.quote_app_docker.container_name
}
5 changes: 5 additions & 0 deletions terraform/environments/dev/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
variable "docker_host" {
description = "Docker daemon host"
type = string
default = "unix:///var/run/docker.sock"
}
64 changes: 64 additions & 0 deletions terraform/environments/prod/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
terraform {
required_version = ">= 1.0"

required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.24"
}
}
}

provider "kubernetes" {
config_path = "~/.kube/config"
}

module "quote_app_k8s" {
source = "../../modules/kubernetes"

namespace = "quote-app"
app_name = "quote-app"
image = "adityajareda/quote-app:latest"
replicas = 3
container_port = 3000
service_port = 80
node_port = 30080

environment_vars = {
NODE_ENV = "production"
PORT = "3000"
APP_NAME = "Quote App"
APP_VERSION = "1.0.0"
LOG_LEVEL = "info"
}

cpu_request = "100m"
cpu_limit = "500m"
memory_request = "128Mi"
memory_limit = "256Mi"

hpa_enabled = true
hpa_min_replicas = 2
hpa_max_replicas = 10
hpa_cpu_threshold = 70
}

output "namespace" {
description = "Kubernetes namespace"
value = module.quote_app_k8s.namespace
}

output "deployment_name" {
description = "Deployment name"
value = module.quote_app_k8s.deployment_name
}

output "service_name" {
description = "Service name"
value = module.quote_app_k8s.service_name
}

output "access_port" {
description = "NodePort for external access"
value = module.quote_app_k8s.node_port
}
5 changes: 5 additions & 0 deletions terraform/environments/prod/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
variable "kubeconfig_path" {
description = "Path to kubeconfig file"
type = string
default = "~/.kube/config"
}
31 changes: 31 additions & 0 deletions terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# ============================================
# ROOT TERRAFORM CONFIGURATION
# ============================================
# This is the main entry point for Terraform

terraform {
required_version = ">= 1.0"
}

# ============================================
# INSTRUCTIONS
# ============================================
#
# To use this Terraform configuration:
#
# 1. For Development (Docker):
# cd environments/dev
# terraform init
# terraform plan
# terraform apply
#
# 2. For Production (Kubernetes):
# cd environments/prod
# terraform init
# terraform plan
# terraform apply
#
# 3. To destroy:
# terraform destroy
#
# ============================================
Loading
Loading