{"slug":"terraform-examples","title":"Terraform Examples","description":"Real-world Terraform configurations for common use cases.","section":"Terraform","url":"https://docs.danubedata.ro/terraform-examples","markdown_url":"https://docs.danubedata.ro/terraform-examples.md","breadcrumbs":[{"title":"Terraform","slug":null},{"title":"Examples","slug":"terraform-examples"}],"headings":[{"level":1,"title":"Terraform Examples","id":"terraform-examples"},{"level":2,"title":"Basic VPS with SSH Key","id":"basic-vps-with-ssh-key"},{"level":2,"title":"Web Application Stack","id":"web-application-stack"},{"level":2,"title":"Multi-Environment Setup","id":"multi-environment-setup"},{"level":3,"title":"main.tf","id":"maintf"},{"level":3,"title":"Usage","id":"usage"},{"level":2,"title":"S3-Compatible Storage with Access Keys","id":"s3-compatible-storage-with-access-keys"},{"level":2,"title":"Serverless API with Database","id":"serverless-api-with-database"},{"level":2,"title":"VPS with Firewall","id":"vps-with-firewall"},{"level":2,"title":"Scheduled Snapshots","id":"scheduled-snapshots"},{"level":2,"title":"Database with Replicas (Future)","id":"database-with-replicas-future"},{"level":2,"title":"Full Infrastructure Module","id":"full-infrastructure-module"},{"level":3,"title":"modules/app-stack/main.tf","id":"modulesapp-stackmaintf"},{"level":3,"title":"main.tf (using the module)","id":"maintf-using-the-module"},{"level":2,"title":"CI/CD with GitHub Actions","id":"cicd-with-github-actions"},{"level":3,"title":".github/workflows/terraform.yml","id":"githubworkflowsterraformyml"},{"level":2,"title":"Next Steps","id":"next-steps"}],"format":"markdown","word_count":674,"content":"# Terraform Examples\n\nReal-world Terraform configurations for common use cases.\n\n## Basic VPS with SSH Key\n\nDeploy a simple VPS with SSH key authentication.\n\n```hcl\nterraform {\n  required_providers {\n    danubedata = {\n      source  = \"AdrianSilaghi/danubedata\"\n      version = \"~> 0.1\"\n    }\n  }\n}\n\nprovider \"danubedata\" {}\n\n# Create SSH key\nresource \"danubedata_ssh_key\" \"main\" {\n  name       = \"my-ssh-key\"\n  public_key = file(\"~/.ssh/id_ed25519.pub\")\n}\n\n# Create VPS\nresource \"danubedata_vps\" \"web\" {\n  name             = \"web-server\"\n  image            = \"ubuntu-24.04\"\n  datacenter       = \"fsn1\"\n  resource_profile = \"small_shared\"\n  auth_method      = \"ssh_key\"\n  ssh_key_id       = danubedata_ssh_key.main.id\n}\n\noutput \"public_ip\" {\n  value = danubedata_vps.web.public_ip\n}\n\noutput \"ssh_command\" {\n  value = \"ssh root@${danubedata_vps.web.public_ip}\"\n}\n\noutput \"monthly_cost\" {\n  value = \"${danubedata_vps.web.monthly_cost} EUR/month\"\n}\n```\n\n---\n\n## Web Application Stack\n\nDeploy a complete web application stack with VPS, PostgreSQL database, and Redis cache.\n\n```hcl\nterraform {\n  required_providers {\n    danubedata = {\n      source  = \"AdrianSilaghi/danubedata\"\n      version = \"~> 0.1\"\n    }\n  }\n}\n\nprovider \"danubedata\" {}\n\nvariable \"environment\" {\n  type    = string\n  default = \"production\"\n}\n\nvariable \"datacenter\" {\n  type    = string\n  default = \"fsn1\"\n}\n\n# SSH Key\nresource \"danubedata_ssh_key\" \"deploy\" {\n  name       = \"${var.environment}-deploy-key\"\n  public_key = file(\"~/.ssh/id_ed25519.pub\")\n}\n\n# Application Server\nresource \"danubedata_vps\" \"app\" {\n  name             = \"${var.environment}-app\"\n  image            = \"ubuntu-24.04\"\n  datacenter       = var.datacenter\n  resource_profile = \"medium_shared\"\n  auth_method      = \"ssh_key\"\n  ssh_key_id       = danubedata_ssh_key.deploy.id\n}\n\n# PostgreSQL Database\nresource \"danubedata_database\" \"main\" {\n  name             = \"${var.environment}-db\"\n  database_name    = \"myapp\"\n  engine           = \"postgresql\"\n  version          = \"16\"\n  resource_profile = \"medium\"\n  datacenter       = var.datacenter\n}\n\n# Redis Cache\nresource \"danubedata_cache\" \"sessions\" {\n  name             = \"${var.environment}-cache\"\n  cache_provider   = \"redis\"\n  resource_profile = \"small\"\n  datacenter       = var.datacenter\n}\n\n# Outputs\noutput \"app_ip\" {\n  value = danubedata_vps.app.public_ip\n}\n\noutput \"database_endpoint\" {\n  value = danubedata_database.main.endpoint\n}\n\noutput \"database_port\" {\n  value = danubedata_database.main.port\n}\n\noutput \"cache_endpoint\" {\n  value = danubedata_cache.sessions.endpoint\n}\n\noutput \"total_monthly_cost\" {\n  value = \"${danubedata_vps.app.monthly_cost + danubedata_database.main.monthly_cost + danubedata_cache.sessions.monthly_cost} EUR/month\"\n}\n```\n\n---\n\n## Multi-Environment Setup\n\nManage dev, staging, and production environments with workspaces.\n\n### main.tf\n\n```hcl\nterraform {\n  required_providers {\n    danubedata = {\n      source  = \"AdrianSilaghi/danubedata\"\n      version = \"~> 0.1\"\n    }\n  }\n}\n\nprovider \"danubedata\" {}\n\n# Environment-specific configuration\nlocals {\n  environments = {\n    dev = {\n      vps_profile = \"nano_shared\"\n      db_profile  = \"small\"\n      datacenter  = \"fsn1\"\n    }\n    staging = {\n      vps_profile = \"small_shared\"\n      db_profile  = \"small\"\n      datacenter  = \"fsn1\"\n    }\n    production = {\n      vps_profile = \"medium_shared\"\n      db_profile  = \"medium\"\n      datacenter  = \"fsn1\"\n    }\n  }\n\n  env = local.environments[terraform.workspace]\n}\n\n# SSH Key (shared across environments)\ndata \"danubedata_ssh_keys\" \"existing\" {}\n\n# VPS\nresource \"danubedata_vps\" \"app\" {\n  name             = \"${terraform.workspace}-app\"\n  image            = \"ubuntu-24.04\"\n  datacenter       = local.env.datacenter\n  resource_profile = local.env.vps_profile\n  auth_method      = \"ssh_key\"\n  ssh_key_id       = data.danubedata_ssh_keys.existing.ssh_keys[0].id\n}\n\n# Database\nresource \"danubedata_database\" \"main\" {\n  name             = \"${terraform.workspace}-db\"\n  database_name    = \"app\"\n  engine           = \"postgresql\"\n  resource_profile = local.env.db_profile\n  datacenter       = local.env.datacenter\n}\n\noutput \"environment\" {\n  value = terraform.workspace\n}\n\noutput \"app_ip\" {\n  value = danubedata_vps.app.public_ip\n}\n\noutput \"db_endpoint\" {\n  value = danubedata_database.main.endpoint\n}\n```\n\n### Usage\n\n```bash\n# Create workspaces\nterraform workspace new dev\nterraform workspace new staging\nterraform workspace new production\n\n# Deploy to dev\nterraform workspace select dev\nterraform apply\n\n# Deploy to staging\nterraform workspace select staging\nterraform apply\n\n# Deploy to production\nterraform workspace select production\nterraform apply\n```\n\n---\n\n## S3-Compatible Storage with Access Keys\n\nSet up object storage with access keys for your application.\n\n```hcl\nterraform {\n  required_providers {\n    danubedata = {\n      source  = \"AdrianSilaghi/danubedata\"\n      version = \"~> 0.1\"\n    }\n  }\n}\n\nprovider \"danubedata\" {}\n\n# Storage bucket for uploads\nresource \"danubedata_storage_bucket\" \"uploads\" {\n  name               = \"my-app-uploads\"\n  display_name       = \"Application Uploads\"\n  region             = \"fsn1\"\n  versioning_enabled = true\n  encryption_enabled = true\n}\n\n# Storage bucket for backups\nresource \"danubedata_storage_bucket\" \"backups\" {\n  name               = \"my-app-backups\"\n  display_name       = \"Database Backups\"\n  region             = \"fsn1\"\n  versioning_enabled = true\n  encryption_enabled = true\n  public_access      = false\n}\n\n# Access key for application\nresource \"danubedata_storage_access_key\" \"app\" {\n  name = \"app-storage-key\"\n}\n\n# Access key for backup system (with expiration)\nresource \"danubedata_storage_access_key\" \"backup\" {\n  name       = \"backup-storage-key\"\n  expires_at = \"2025-12-31T23:59:59Z\"\n}\n\n# Outputs for application configuration\noutput \"s3_endpoint\" {\n  value = \"https://s3.danubedata.ro\"\n}\n\noutput \"uploads_bucket\" {\n  value = danubedata_storage_bucket.uploads.minio_bucket_name\n}\n\noutput \"backups_bucket\" {\n  value = danubedata_storage_bucket.backups.minio_bucket_name\n}\n\noutput \"app_access_key\" {\n  value = danubedata_storage_access_key.app.access_key_id\n}\n\noutput \"app_secret_key\" {\n  value     = danubedata_storage_access_key.app.secret_access_key\n  sensitive = true\n}\n\n# AWS CLI configuration helper\noutput \"aws_cli_config\" {\n  value = <<-EOT\n    # Add to ~/.aws/config:\n    [profile danubedata]\n    region = fsn1\n\n    # Add to ~/.aws/credentials:\n    [danubedata]\n    aws_access_key_id = ${danubedata_storage_access_key.app.access_key_id}\n    aws_secret_access_key = <run: terraform output -raw app_secret_key>\n\n    # Usage:\n    aws --profile danubedata --endpoint-url https://s3.danubedata.ro s3 ls\n  EOT\n}\n```\n\n---\n\n## Serverless API with Database\n\nDeploy a serverless container with a connected database.\n\n```hcl\nterraform {\n  required_providers {\n    danubedata = {\n      source  = \"AdrianSilaghi/danubedata\"\n      version = \"~> 0.1\"\n    }\n  }\n}\n\nprovider \"danubedata\" {}\n\n# Database for the API\nresource \"danubedata_database\" \"api_db\" {\n  name             = \"api-database\"\n  database_name    = \"api\"\n  engine           = \"postgresql\"\n  version          = \"16\"\n  resource_profile = \"small\"\n  datacenter       = \"fsn1\"\n}\n\n# Serverless API\nresource \"danubedata_serverless\" \"api\" {\n  name             = \"my-api\"\n  deployment_type  = \"image\"\n  image_url        = \"ghcr.io/myorg/my-api:latest\"\n  resource_profile = \"small\"\n  port             = 8080\n  min_instances    = 0\n  max_instances    = 10\n\n  environment_variables = {\n    NODE_ENV     = \"production\"\n    DATABASE_URL = \"postgresql://${danubedata_database.api_db.username}@${danubedata_database.api_db.endpoint}:${danubedata_database.api_db.port}/${danubedata_database.api_db.database_name}\"\n    LOG_LEVEL    = \"info\"\n  }\n}\n\noutput \"api_url\" {\n  value = danubedata_serverless.api.url\n}\n\noutput \"database_endpoint\" {\n  value = danubedata_database.api_db.endpoint\n}\n```\n\n---\n\n## VPS with Firewall\n\nDeploy a VPS with custom firewall rules.\n\n```hcl\nterraform {\n  required_providers {\n    danubedata = {\n      source  = \"AdrianSilaghi/danubedata\"\n      version = \"~> 0.1\"\n    }\n  }\n}\n\nprovider \"danubedata\" {}\n\nvariable \"allowed_ssh_ips\" {\n  type    = list(string)\n  default = [\"0.0.0.0/0\"]  # Replace with your IP ranges\n}\n\n# SSH Key\nresource \"danubedata_ssh_key\" \"main\" {\n  name       = \"server-key\"\n  public_key = file(\"~/.ssh/id_ed25519.pub\")\n}\n\n# Firewall\nresource \"danubedata_firewall\" \"web\" {\n  name           = \"web-server-firewall\"\n  description    = \"Firewall for web servers\"\n  default_action = \"drop\"\n\n  # Allow SSH from specific IPs\n  rules {\n    name             = \"allow-ssh\"\n    action           = \"allow\"\n    direction        = \"inbound\"\n    protocol         = \"tcp\"\n    port_range_start = 22\n    port_range_end   = 22\n    source_ips       = var.allowed_ssh_ips\n    priority         = 100\n  }\n\n  # Allow HTTP\n  rules {\n    name             = \"allow-http\"\n    action           = \"allow\"\n    direction        = \"inbound\"\n    protocol         = \"tcp\"\n    port_range_start = 80\n    port_range_end   = 80\n    source_ips       = [\"0.0.0.0/0\"]\n    priority         = 200\n  }\n\n  # Allow HTTPS\n  rules {\n    name             = \"allow-https\"\n    action           = \"allow\"\n    direction        = \"inbound\"\n    protocol         = \"tcp\"\n    port_range_start = 443\n    port_range_end   = 443\n    source_ips       = [\"0.0.0.0/0\"]\n    priority         = 300\n  }\n\n  # Allow all outbound\n  rules {\n    name             = \"allow-outbound\"\n    action           = \"allow\"\n    direction        = \"outbound\"\n    protocol         = \"tcp\"\n    port_range_start = 1\n    port_range_end   = 65535\n    source_ips       = [\"0.0.0.0/0\"]\n    priority         = 1000\n  }\n}\n\n# VPS\nresource \"danubedata_vps\" \"web\" {\n  name             = \"web-server\"\n  image            = \"ubuntu-24.04\"\n  datacenter       = \"fsn1\"\n  resource_profile = \"small_shared\"\n  auth_method      = \"ssh_key\"\n  ssh_key_id       = danubedata_ssh_key.main.id\n}\n\noutput \"server_ip\" {\n  value = danubedata_vps.web.public_ip\n}\n```\n\n---\n\n## Scheduled Snapshots\n\nCreate VPS snapshots for backup purposes.\n\n```hcl\nterraform {\n  required_providers {\n    danubedata = {\n      source  = \"AdrianSilaghi/danubedata\"\n      version = \"~> 0.1\"\n    }\n  }\n}\n\nprovider \"danubedata\" {}\n\n# VPS\nresource \"danubedata_vps\" \"production\" {\n  name             = \"production-server\"\n  image            = \"ubuntu-24.04\"\n  datacenter       = \"fsn1\"\n  resource_profile = \"medium_shared\"\n  auth_method      = \"ssh_key\"\n  ssh_key_id       = var.ssh_key_id\n}\n\n# Manual snapshot (create before major changes)\nresource \"danubedata_vps_snapshot\" \"pre_upgrade\" {\n  name            = \"pre-upgrade-${formatdate(\"YYYY-MM-DD\", timestamp())}\"\n  description     = \"Snapshot before system upgrade\"\n  vps_instance_id = danubedata_vps.production.id\n}\n\noutput \"snapshot_id\" {\n  value = danubedata_vps_snapshot.pre_upgrade.id\n}\n```\n\n---\n\n## Database with Replicas (Future)\n\nDeploy a database with read replicas for high availability.\n\n```hcl\nterraform {\n  required_providers {\n    danubedata = {\n      source  = \"AdrianSilaghi/danubedata\"\n      version = \"~> 0.1\"\n    }\n  }\n}\n\nprovider \"danubedata\" {}\n\n# Primary database\nresource \"danubedata_database\" \"primary\" {\n  name             = \"app-primary\"\n  database_name    = \"myapp\"\n  engine           = \"postgresql\"\n  version          = \"16\"\n  resource_profile = \"large\"\n  datacenter       = \"fsn1\"\n}\n\n# Application configuration\noutput \"primary_endpoint\" {\n  value       = danubedata_database.primary.endpoint\n  description = \"Primary database endpoint for writes\"\n}\n\noutput \"primary_port\" {\n  value = danubedata_database.primary.port\n}\n\noutput \"connection_info\" {\n  value = {\n    host     = danubedata_database.primary.endpoint\n    port     = danubedata_database.primary.port\n    database = danubedata_database.primary.database_name\n    username = danubedata_database.primary.username\n  }\n  sensitive = true\n}\n```\n\n---\n\n## Full Infrastructure Module\n\nCreate a reusable module for deploying a complete application stack.\n\n### modules/app-stack/main.tf\n\n```hcl\nvariable \"name\" {\n  type        = string\n  description = \"Application name\"\n}\n\nvariable \"datacenter\" {\n  type    = string\n  default = \"fsn1\"\n}\n\nvariable \"vps_profile\" {\n  type    = string\n  default = \"small_shared\"\n}\n\nvariable \"db_profile\" {\n  type    = string\n  default = \"small\"\n}\n\nvariable \"ssh_key_id\" {\n  type        = string\n  description = \"SSH key ID for VPS access\"\n}\n\n# VPS\nresource \"danubedata_vps\" \"app\" {\n  name             = \"${var.name}-app\"\n  image            = \"ubuntu-24.04\"\n  datacenter       = var.datacenter\n  resource_profile = var.vps_profile\n  auth_method      = \"ssh_key\"\n  ssh_key_id       = var.ssh_key_id\n}\n\n# Database\nresource \"danubedata_database\" \"db\" {\n  name             = \"${var.name}-db\"\n  database_name    = replace(var.name, \"-\", \"_\")\n  engine           = \"postgresql\"\n  version          = \"16\"\n  resource_profile = var.db_profile\n  datacenter       = var.datacenter\n}\n\n# Cache\nresource \"danubedata_cache\" \"cache\" {\n  name             = \"${var.name}-cache\"\n  cache_provider   = \"redis\"\n  resource_profile = \"small\"\n  datacenter       = var.datacenter\n}\n\n# Outputs\noutput \"vps_ip\" {\n  value = danubedata_vps.app.public_ip\n}\n\noutput \"db_endpoint\" {\n  value = danubedata_database.db.endpoint\n}\n\noutput \"cache_endpoint\" {\n  value = danubedata_cache.cache.endpoint\n}\n\noutput \"monthly_cost\" {\n  value = danubedata_vps.app.monthly_cost + danubedata_database.db.monthly_cost + danubedata_cache.cache.monthly_cost\n}\n```\n\n### main.tf (using the module)\n\n```hcl\nterraform {\n  required_providers {\n    danubedata = {\n      source  = \"AdrianSilaghi/danubedata\"\n      version = \"~> 0.1\"\n    }\n  }\n}\n\nprovider \"danubedata\" {}\n\n# SSH Key\nresource \"danubedata_ssh_key\" \"deploy\" {\n  name       = \"deploy-key\"\n  public_key = file(\"~/.ssh/id_ed25519.pub\")\n}\n\n# Deploy multiple applications\nmodule \"frontend\" {\n  source      = \"./modules/app-stack\"\n  name        = \"frontend\"\n  datacenter  = \"fsn1\"\n  vps_profile = \"small_shared\"\n  db_profile  = \"small\"\n  ssh_key_id  = danubedata_ssh_key.deploy.id\n}\n\nmodule \"backend\" {\n  source      = \"./modules/app-stack\"\n  name        = \"backend\"\n  datacenter  = \"fsn1\"\n  vps_profile = \"medium_shared\"\n  db_profile  = \"medium\"\n  ssh_key_id  = danubedata_ssh_key.deploy.id\n}\n\noutput \"frontend\" {\n  value = {\n    ip           = module.frontend.vps_ip\n    db_endpoint  = module.frontend.db_endpoint\n    monthly_cost = module.frontend.monthly_cost\n  }\n}\n\noutput \"backend\" {\n  value = {\n    ip           = module.backend.vps_ip\n    db_endpoint  = module.backend.db_endpoint\n    monthly_cost = module.backend.monthly_cost\n  }\n}\n\noutput \"total_monthly_cost\" {\n  value = \"${module.frontend.monthly_cost + module.backend.monthly_cost} EUR/month\"\n}\n```\n\n---\n\n## CI/CD with GitHub Actions\n\nExample GitHub Actions workflow for Terraform.\n\n### .github/workflows/terraform.yml\n\n```yaml\nname: Terraform\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n\nenv:\n  TF_VERSION: \"1.6.0\"\n\njobs:\n  terraform:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Setup Terraform\n        uses: hashicorp/setup-terraform@v3\n        with:\n          terraform_version: ${{ env.TF_VERSION }}\n\n      - name: Terraform Init\n        run: terraform init\n        env:\n          DANUBEDATA_API_TOKEN: ${{ secrets.DANUBEDATA_API_TOKEN }}\n\n      - name: Terraform Format Check\n        run: terraform fmt -check\n\n      - name: Terraform Validate\n        run: terraform validate\n\n      - name: Terraform Plan\n        run: terraform plan -no-color\n        env:\n          DANUBEDATA_API_TOKEN: ${{ secrets.DANUBEDATA_API_TOKEN }}\n\n      - name: Terraform Apply\n        if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n        run: terraform apply -auto-approve\n        env:\n          DANUBEDATA_API_TOKEN: ${{ secrets.DANUBEDATA_API_TOKEN }}\n```\n\n---\n\n## Next Steps\n\n- [Terraform Overview](https://docs.danubedata.ro/terraform-overview) - Getting started guide\n- [Terraform Resources](https://docs.danubedata.ro/terraform-resources) - Resource documentation\n- [Terraform Data Sources](https://docs.danubedata.ro/terraform-data-sources) - Data source documentation\n- [Terraform Registry](https://registry.terraform.io/providers/AdrianSilaghi/danubedata/latest) - Official provider docs\n","prev":{"title":"Data Sources","slug":"terraform-data-sources","url":"https://docs.danubedata.ro/terraform-data-sources","markdown_url":"https://docs.danubedata.ro/terraform-data-sources.md","json_url":"https://docs.danubedata.ro/terraform-data-sources.json"},"next":{"title":"Infrastructure","slug":"platform-infrastructure","url":"https://docs.danubedata.ro/platform-infrastructure","markdown_url":"https://docs.danubedata.ro/platform-infrastructure.md","json_url":"https://docs.danubedata.ro/platform-infrastructure.json"},"index_url":"https://docs.danubedata.ro/index.json"}