Skip to content
Draft
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
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,14 @@ FodyWeavers.xsd

# JetBrains Rider
*.sln.iml

# Terraform
.terraform/
.terraform.lock.hcl
*.tfstate
*.tfstate.*
*.tfvars
*.tfplan
.terraformrc
terraform.rc

57 changes: 56 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,57 @@
# Docker App

## hahaha
A sample .NET Docker application with infrastructure as code (IaC) templates for Azure deployment.

## Infrastructure Deployment Options

This repository includes infrastructure templates in both **Bicep** and **Terraform** formats for deploying to Azure. Choose the tool that best fits your workflow:

### Bicep (Azure-native)
- Native Azure Resource Manager (ARM) template language
- Tight integration with Azure CLI
- See individual `*.bicep` files in the `azd/` directory

### Terraform (Multi-cloud)
- HashiCorp's infrastructure as code tool
- Works across multiple cloud providers
- See individual `*.tf` files in the `azd/` directory
- **[📖 Terraform Documentation](azd/TERRAFORM.md)**

## Deployment Targets

Both Bicep and Terraform support the following Azure deployment options:

| Option | Description | Bicep Files | Terraform Files |
|--------|-------------|-------------|-----------------|
| **ACA** | Azure Container Apps | `azd/aca/*.bicep` | `azd/aca/*.tf` |
| **ACI** | Azure Container Instance | `azd/aci/*.bicep` | `azd/aci/*.tf` |
| **AKS** | Azure Kubernetes Service | `azd/aks/*.bicep` | `azd/aks/*.tf` |
| **ACR** | Azure Container Registry (module) | `azd/acr/modules/*.bicep` | `azd/acr/modules/*.tf` |

## Quick Start

### Using Bicep
```bash
cd azd/aca
az deployment sub create \
--location eastus \
--template-file main.bicep \
--parameters environmentName=myenv location=eastus
```

### Using Terraform
```bash
cd azd/aca
terraform init
terraform apply -var="environment_name=myenv" -var="location=eastus"
```

For detailed Terraform usage, see **[TERRAFORM.md](azd/TERRAFORM.md)**.

## Application

The application is a .NET Docker app located in the `src/` directory. Build it using:

```bash
docker build -t docker-app .
```
162 changes: 162 additions & 0 deletions azd/TERRAFORM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# Terraform Infrastructure

This directory contains Terraform configurations that are equivalent to the Bicep templates in this repository. You can choose to use either Bicep or Terraform for deploying the infrastructure.

## Structure

Each deployment option has its own directory with Terraform configurations:

- **aca/** - Azure Container Apps deployment
- **aci/** - Azure Container Instance deployment
- **aks/** - Azure Kubernetes Service deployment
- **acr/** - Standalone Azure Container Registry module

## Prerequisites

1. [Terraform](https://www.terraform.io/downloads) >= 1.0
2. [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli)
3. An active Azure subscription

## Authentication

Before running Terraform, authenticate with Azure:

```bash
az login
```

## Usage

### Azure Container Apps (ACA)

```bash
cd azd/aca

# Initialize Terraform
terraform init

# Review the execution plan
terraform plan -var="environment_name=myenv" -var="location=eastus"

# Apply the configuration
terraform apply -var="environment_name=myenv" -var="location=eastus"
```

### Azure Container Instance (ACI)

```bash
cd azd/aci

# Initialize Terraform
terraform init

# Review the execution plan
terraform plan -var="environment_name=myenv" -var="location=eastus"

# Apply the configuration
terraform apply -var="environment_name=myenv" -var="location=eastus"
```

### Azure Kubernetes Service (AKS)

```bash
cd azd/aks

# Initialize Terraform
terraform init

# Review the execution plan
terraform plan -var="environment_name=myenv" -var="location=eastus"

# Apply the configuration
terraform apply -var="environment_name=myenv" -var="location=eastus"
```

## Variables

Each deployment option has configurable variables. Here are the common ones:

### Required Variables

- `environment_name` - Name of the environment (1-64 characters)
- `location` - Azure region (e.g., "eastus", "westus2")

### Optional Variables (ACA)

- `container_image` - Container image to deploy (default: "docker-app")
- `container_port` - Port the container listens on (default: 80)
- `cpu_cores` - CPU cores allocated (default: "0.5")
- `memory_in_gb` - Memory allocated (default: "1Gi")

### Optional Variables (ACI)

- `container_image` - Container image to deploy (default: "mcr.microsoft.com/azuredocs/aci-helloworld")
- `container_port` - Port the container listens on (default: 80)
- `cpu_cores` - CPU cores allocated (default: "1.0")
- `memory_in_gb` - Memory in GB (default: "1.5")

### Optional Variables (AKS)

- `agent_count` - Number of agent nodes (default: 3, range: 1-100)
- `agent_vm_size` - VM size for nodes (default: "Standard_D2s_v3")
- `os_disk_size_gb` - OS disk size in GB (default: 0, range: 0-1023)
- `os_type` - Operating system type (default: "Linux", options: "Linux", "Windows")

## Using Variable Files

You can create a `terraform.tfvars` file to store your variables:

```hcl
environment_name = "myenv"
location = "eastus"
container_image = "myregistry.azurecr.io/myapp"
container_port = 8080
```

Then run:

```bash
terraform apply
```

## Outputs

Each configuration provides outputs that can be used for further automation:

- `AZURE_LOCATION` - The Azure region where resources are deployed
- `AZURE_CONTAINER_REGISTRY_ENDPOINT` - Container registry login server
- `AZURE_CONTAINER_REGISTRY_NAME` - Container registry name
- Additional outputs specific to each deployment type

## Comparison with Bicep

| Feature | Bicep | Terraform |
|---------|-------|-----------|
| Language | ARM Template DSL | HCL (HashiCorp Configuration Language) |
| Provider | Azure-specific | Multi-cloud (Azure, AWS, GCP, etc.) |
| State Management | Server-side (Azure) | Client-side (local or remote backend) |
| Module System | Bicep modules | Terraform modules |
| Validation | `az bicep build` | `terraform validate` |
| Preview Changes | `az deployment what-if` | `terraform plan` |
| Apply Changes | `az deployment create` | `terraform apply` |

## Clean Up

To destroy all resources created by Terraform:

```bash
terraform destroy -var="environment_name=myenv" -var="location=eastus"
```

Or if using a tfvars file:

```bash
terraform destroy
```

## Notes

- The Terraform configurations are functionally equivalent to their Bicep counterparts
- Both Bicep and Terraform files are maintained in this repository for flexibility
- The `.terraform/` directory and state files are git-ignored for security
- Always review the `terraform plan` output before applying changes
95 changes: 95 additions & 0 deletions azd/aca/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.0"
}
}
}

provider "azurerm" {
features {}
}

# Generate a unique resource token
resource "random_string" "resource_token" {
length = 13
special = false
upper = false
numeric = true
}

# Resource Group
resource "azurerm_resource_group" "main" {
name = "rg-${var.environment_name}"
location = var.location

tags = {
"azd-env-name" = var.environment_name
}
}

# Container Registry
resource "azurerm_container_registry" "acr" {
name = "acr${random_string.resource_token.result}"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
sku = "Basic"
admin_enabled = true
}

# Container Apps Environment
resource "azurerm_container_app_environment" "env" {
name = "cae-${random_string.resource_token.result}"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
}

# Container App
resource "azurerm_container_app" "app" {
name = "ca-${random_string.resource_token.result}"
container_app_environment_id = azurerm_container_app_environment.env.id
resource_group_name = azurerm_resource_group.main.name
revision_mode = "Single"

registry {
server = azurerm_container_registry.acr.login_server
username = azurerm_container_registry.acr.admin_username
password_secret_name = "registry-password"
}

secret {
name = "registry-password"
value = azurerm_container_registry.acr.admin_password
}

template {
container {
name = "ca-${random_string.resource_token.result}"
image = var.container_image != "" ? "${azurerm_container_registry.acr.login_server}/${var.container_image}:latest" : "${azurerm_container_registry.acr.login_server}/docker-app:latest"
cpu = var.cpu_cores
memory = var.memory_in_gb
}

min_replicas = 1
max_replicas = 3

http_scale_rule {
name = "http-scale-rule"
concurrent_requests = "10"
}
}

ingress {
external_enabled = true
target_port = var.container_port
traffic_weight {
latest_revision = true
percentage = 100
}
}
}
19 changes: 19 additions & 0 deletions azd/aca/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
output "AZURE_LOCATION" {
value = var.location
description = "Azure location where resources are deployed"
}

output "AZURE_CONTAINER_REGISTRY_ENDPOINT" {
value = azurerm_container_registry.acr.login_server
description = "Container registry login server"
}

output "AZURE_CONTAINER_REGISTRY_NAME" {
value = azurerm_container_registry.acr.name
description = "Container registry name"
}

output "CONTAINER_APP_URL" {
value = "https://${azurerm_container_app.app.latest_revision_fqdn}"
description = "Container App URL"
}
11 changes: 11 additions & 0 deletions azd/aca/terraform.tfvars.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Example Terraform variables for Azure Container Apps deployment
# Copy this file to terraform.tfvars and customize the values

environment_name = "dev"
location = "eastus"

# Optional: Container configuration
# container_image = "docker-app"
# container_port = 80
# cpu_cores = "0.5"
# memory_in_gb = "1Gi"
Loading