A Terraform provider for Dokploy
Plugin-framework provider covering projects, environments, applications, Compose stacks, managed databases, domains, mounts, ports, redirects, basic auth, registries, SSH keys, certificates and backup destinations, over Dokploy's tRPC-over-REST API. The shim package exposes the provider to other Go modules, which is how pulumi-dokploy bridges it.
This commit is contained in:
314
.agents/skills/terraform-style-guide/SKILL.md
Normal file
314
.agents/skills/terraform-style-guide/SKILL.md
Normal file
@@ -0,0 +1,314 @@
|
||||
---
|
||||
name: terraform-style-guide
|
||||
description: Generate Terraform HCL code following HashiCorp's official style conventions and best practices. Use when writing, reviewing, or generating Terraform configurations.
|
||||
---
|
||||
|
||||
# Terraform Style Guide
|
||||
|
||||
Generate and maintain Terraform code following HashiCorp's official style conventions and best practices.
|
||||
|
||||
**Reference:** [HashiCorp Terraform Style Guide](https://developer.hashicorp.com/terraform/language/style)
|
||||
|
||||
## Code Generation Strategy
|
||||
|
||||
When generating Terraform code:
|
||||
|
||||
1. Start with provider configuration and version constraints
|
||||
2. Create data sources before dependent resources
|
||||
3. Build resources in dependency order
|
||||
4. Add outputs for key resource attributes
|
||||
5. Use variables for all configurable values
|
||||
|
||||
## File Organization
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `terraform.tf` | Terraform and provider version requirements |
|
||||
| `providers.tf` | Provider configurations |
|
||||
| `main.tf` | Primary resources and data sources |
|
||||
| `variables.tf` | Input variable declarations (alphabetical) |
|
||||
| `outputs.tf` | Output value declarations (alphabetical) |
|
||||
| `locals.tf` | Local value declarations |
|
||||
|
||||
### Example Structure
|
||||
|
||||
```hcl
|
||||
# terraform.tf
|
||||
terraform {
|
||||
required_version = ">= 1.14"
|
||||
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 6.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# variables.tf
|
||||
variable "environment" {
|
||||
description = "Target deployment environment"
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = contains(["dev", "staging", "prod"], var.environment)
|
||||
error_message = "Environment must be dev, staging, or prod."
|
||||
}
|
||||
}
|
||||
|
||||
# locals.tf
|
||||
locals {
|
||||
common_tags = {
|
||||
Environment = var.environment
|
||||
ManagedBy = "Terraform"
|
||||
}
|
||||
}
|
||||
|
||||
# main.tf
|
||||
resource "aws_vpc" "main" {
|
||||
cidr_block = var.vpc_cidr
|
||||
enable_dns_hostnames = true
|
||||
|
||||
tags = merge(local.common_tags, {
|
||||
Name = "${var.project_name}-${var.environment}-vpc"
|
||||
})
|
||||
}
|
||||
|
||||
# outputs.tf
|
||||
output "vpc_id" {
|
||||
description = "ID of the created VPC"
|
||||
value = aws_vpc.main.id
|
||||
}
|
||||
```
|
||||
|
||||
## Code Formatting
|
||||
|
||||
### Indentation and Alignment
|
||||
|
||||
- Use **two spaces** per nesting level (no tabs)
|
||||
- Align equals signs for consecutive arguments
|
||||
|
||||
```hcl
|
||||
resource "aws_instance" "web" {
|
||||
ami = "ami-0c55b159cbfafe1f0"
|
||||
instance_type = "t2.micro"
|
||||
subnet_id = "subnet-12345678"
|
||||
|
||||
tags = {
|
||||
Name = "web-server"
|
||||
Environment = "production"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Block Organization
|
||||
|
||||
Arguments precede blocks, with meta-arguments first:
|
||||
|
||||
```hcl
|
||||
resource "aws_instance" "example" {
|
||||
# Meta-arguments
|
||||
count = 3
|
||||
|
||||
# Arguments
|
||||
ami = "ami-0c55b159cbfafe1f0"
|
||||
instance_type = "t2.micro"
|
||||
|
||||
# Blocks
|
||||
root_block_device {
|
||||
volume_size = 20
|
||||
}
|
||||
|
||||
# Lifecycle last
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
- Use **lowercase with underscores** for all names
|
||||
- Use **descriptive nouns** excluding the resource type
|
||||
- Be specific and meaningful
|
||||
- Resource names must be singular, not plural
|
||||
- Default to `main` for resources where a specific descriptive name is redundant or unavailable, provided only one instance exists
|
||||
|
||||
```hcl
|
||||
# Bad
|
||||
resource "aws_instance" "webAPI-aws-instance" {}
|
||||
resource "aws_instance" "web_apis" {}
|
||||
variable "name" {}
|
||||
|
||||
# Good
|
||||
resource "aws_instance" "web_api" {}
|
||||
resource "aws_vpc" "main" {}
|
||||
variable "application_name" {}
|
||||
```
|
||||
|
||||
## Variables
|
||||
|
||||
Every variable must include `type` and `description`:
|
||||
|
||||
```hcl
|
||||
variable "instance_type" {
|
||||
description = "EC2 instance type for the web server"
|
||||
type = string
|
||||
default = "t2.micro"
|
||||
|
||||
validation {
|
||||
condition = contains(["t2.micro", "t2.small", "t2.medium"], var.instance_type)
|
||||
error_message = "Instance type must be t2.micro, t2.small, or t2.medium."
|
||||
}
|
||||
}
|
||||
|
||||
variable "database_password" {
|
||||
description = "Password for the database admin user"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
```
|
||||
|
||||
## Outputs
|
||||
|
||||
Every output must include `description`:
|
||||
|
||||
```hcl
|
||||
output "instance_id" {
|
||||
description = "ID of the EC2 instance"
|
||||
value = aws_instance.web.id
|
||||
}
|
||||
|
||||
output "database_password" {
|
||||
description = "Database administrator password"
|
||||
value = aws_db_instance.main.password
|
||||
sensitive = true
|
||||
}
|
||||
```
|
||||
|
||||
## Dynamic Resource Creation
|
||||
|
||||
### Prefer for_each over count
|
||||
|
||||
```hcl
|
||||
# Bad - count for multiple resources
|
||||
resource "aws_instance" "web" {
|
||||
count = var.instance_count
|
||||
tags = { Name = "web-${count.index}" }
|
||||
}
|
||||
|
||||
# Good - for_each with named instances
|
||||
variable "instance_names" {
|
||||
type = set(string)
|
||||
default = ["web-1", "web-2", "web-3"]
|
||||
}
|
||||
|
||||
resource "aws_instance" "web" {
|
||||
for_each = var.instance_names
|
||||
tags = { Name = each.key }
|
||||
}
|
||||
```
|
||||
|
||||
### count for Conditional Creation
|
||||
|
||||
```hcl
|
||||
resource "aws_cloudwatch_metric_alarm" "cpu" {
|
||||
count = var.enable_monitoring ? 1 : 0
|
||||
|
||||
alarm_name = "high-cpu-usage"
|
||||
threshold = 80
|
||||
}
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
Refer to SECURITY.md. It includes guidance on encrypting resources,
|
||||
preventing sensitive data in state, and secure configurations.
|
||||
|
||||
## Version Pinning
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
required_version = ">= 1.14"
|
||||
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 6.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use the latest major version of each provider and the latest minor version of
|
||||
Terraform, unless otherwise constrained by a dependency lock file or by other
|
||||
modules used by the configuration.
|
||||
|
||||
**Version constraint operators:**
|
||||
- `= 1.0.0` - Exact version
|
||||
- `>= 1.0.0` - Greater than or equal
|
||||
- `~> 1.0` - Allow rightmost component to increment
|
||||
- `>= 1.0, < 2.0` - Version range
|
||||
|
||||
## Provider Configuration
|
||||
|
||||
```hcl
|
||||
provider "aws" {
|
||||
region = "us-west-2"
|
||||
|
||||
default_tags {
|
||||
tags = {
|
||||
ManagedBy = "Terraform"
|
||||
Project = var.project_name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Aliased provider for multi-region
|
||||
provider "aws" {
|
||||
alias = "east"
|
||||
region = "us-east-1"
|
||||
}
|
||||
```
|
||||
|
||||
## Version Control
|
||||
|
||||
**Never commit:**
|
||||
- `terraform.tfstate`, `terraform.tfstate.backup`
|
||||
- `.terraform/` directory
|
||||
- `*.tfplan`
|
||||
- `.tfvars` files with sensitive data
|
||||
|
||||
**Always commit:**
|
||||
- All `.tf` configuration files
|
||||
- `.terraform.lock.hcl` (dependency lock file)
|
||||
|
||||
## Validation Tools
|
||||
|
||||
Run before committing:
|
||||
|
||||
```bash
|
||||
terraform fmt -recursive
|
||||
terraform validate
|
||||
```
|
||||
|
||||
Additional tools:
|
||||
- `tflint` - Linting and best practices
|
||||
- `checkov` / `tfsec` - Security scanning
|
||||
|
||||
## Code Review Checklist
|
||||
|
||||
- [ ] Code formatted with `terraform fmt`
|
||||
- [ ] Configuration validated with `terraform validate`
|
||||
- [ ] Files organized according to standard structure
|
||||
- [ ] All variables have type and description
|
||||
- [ ] All outputs have descriptions
|
||||
- [ ] Resource names use descriptive nouns with underscores
|
||||
- [ ] Version constraints pinned explicitly
|
||||
- [ ] Sensitive values marked with `sensitive = true`
|
||||
- [ ] No hardcoded credentials or secrets
|
||||
- [ ] Security best practices applied
|
||||
|
||||
---
|
||||
|
||||
*Based on: [HashiCorp Terraform Style Guide](https://developer.hashicorp.com/terraform/language/style)*
|
||||
Reference in New Issue
Block a user