Skip to content

Infrastructure as Code Using Cursor

Your application works perfectly on your laptop. Now it needs to run in production: load-balanced across multiple regions, with a managed database, a CDN for static assets, environment-specific configuration, and automated rollbacks. The infrastructure engineer who set up the last project left the company, and nobody is sure which Terraform files are actually in use versus leftover experiments. You need to define your infrastructure as code, and you need it to be correct the first time — because a misconfigured security group or an open S3 bucket is one deployment away from a headline.

Cursor Agent is surprisingly effective at infrastructure as code because IaC is fundamentally a code generation problem. Terraform modules, Docker configurations, and Kubernetes manifests follow well-defined schemas, which means the AI can generate syntactically correct, logically sound configurations when given the right context.

  • Prompts for generating Terraform modules for common infrastructure patterns
  • A workflow for iterating on Docker configurations with multi-stage builds
  • Techniques for generating Kubernetes manifests from existing Docker setups
  • Project rules that keep Cursor aware of your cloud provider, naming conventions, and security policies
  • A strategy for validating generated infrastructure code before applying it

Before generating any infrastructure code, encode your environment constraints. This prevents Agent from generating AWS resources when you use GCP, or suggesting open security groups in a compliance-regulated environment.

.cursor/rules/infrastructure.md
# Infrastructure Conventions
## Cloud Provider
- Primary: AWS (us-east-1, eu-west-1)
- Terraform version: 1.7+
- AWS provider version: ~> 5.0
- State backend: S3 bucket "myapp-tf-state" with DynamoDB locking
## Naming Convention
- Resources: {env}-{service}-{resource} (e.g., prod-api-alb)
- Tags required on all resources: Environment, Service, Team, ManagedBy=terraform
## Security Policies
- No public S3 buckets
- No security groups with 0.0.0.0/0 ingress (except ALB on 80/443)
- All RDS instances must have encryption at rest enabled
- All EC2 instances must use IMDSv2
- No hardcoded credentials in any configuration file
- SSL/TLS required for all public endpoints
## Module Structure
- Reusable modules in modules/
- Environment configs in environments/{env}/
- Shared variables in variables.tf, outputs in outputs.tf
- Use terraform-docs for documentation

The most common IaC task is creating a new module for a specific infrastructure component. Cursor excels at this because Terraform’s HCL syntax has clear patterns.

After generation, validate the module before applying:

Terminal window
cd infrastructure/modules/api-service
terraform init
terraform validate
terraform plan -var-file=../../environments/staging/terraform.tfvars

You can do this validation inside Cursor’s terminal, and if terraform validate fails, paste the error back into Agent mode for a fix.

Terraform errors are often cryptic. When terraform plan fails, use Ask mode to diagnose:

terraform plan failed with:
Error: Invalid reference
on main.tf line 23, in resource "aws_ecs_service" "api":
23: cluster = aws_ecs_cluster.main.arn
The aws_ecs_cluster.main resource is not defined in this module.
It's in the networking module. How do I reference it?
@infrastructure/modules/networking/outputs.tf

Ask mode will explain that you need to pass the cluster ARN as a variable from the networking module’s outputs, and show you exactly how to wire it up.

Docker is another domain where Agent generates strong configurations because Dockerfiles follow predictable patterns. The key is giving Agent your application context.

If your deployment target is Kubernetes, Cursor can generate manifests from your Docker configuration:

@Dockerfile @infrastructure/modules/api-service
Generate Kubernetes manifests at k8s/ for deploying this application:
1. Deployment:
- 3 replicas with rolling update strategy
- Resource limits: 256Mi memory, 250m CPU
- Resource requests: 128Mi memory, 100m CPU
- Liveness probe on /health (HTTP, every 10s)
- Readiness probe on /ready (HTTP, every 5s)
- Environment variables from ConfigMap and Secrets
2. Service:
- ClusterIP service on port 80 targeting container port 8080
3. Ingress:
- NGINX ingress with TLS termination
- Host: api.myapp.com
- Rate limiting annotations
4. HorizontalPodAutoscaler:
- Min 3, max 15 replicas
- Target CPU utilization: 70%
5. ConfigMap and Secret templates:
- ConfigMap for non-sensitive env vars
- External Secrets Operator for sensitive values from AWS Secrets Manager
Use Kustomize structure with base/ and overlays/staging/ and overlays/production/.

One of the trickiest parts of IaC is managing differences between environments. Agent can help you create a DRY configuration that varies only where needed.

@infrastructure/environments/staging @infrastructure/environments/production
Our staging and production environments share the same Terraform modules
but differ in:
- Instance sizes (staging: t3.small, production: t3.large)
- Replica counts (staging: 1, production: 3)
- Database size (staging: db.t3.micro, production: db.r6g.large)
- Domain names (staging: staging.myapp.com, production: myapp.com)
- Monitoring thresholds (staging: relaxed, production: strict)
Create a terraform.tfvars file for each environment that:
1. Defines only the values that differ between environments
2. Uses the same variable names (defined in the module's variables.tf)
3. Includes comments explaining why each value differs
4. Follows our naming convention: {env}-{service}-{resource}
@infrastructure/modules/api-service/main.tf
Add secret management to our ECS service:
1. Store secrets in AWS Secrets Manager (not SSM Parameter Store)
2. Reference secrets in the ECS task definition as secrets, not environment
3. IAM policy: task role can only read secrets with prefix "myapp/{env}/"
4. Rotate database credentials automatically using Secrets Manager rotation
5. Application reads secrets from environment variables at runtime
Do NOT include any actual secret values. Use placeholder references only.
Show me how to create the initial secrets using AWS CLI (one-time setup).

Agent generates invalid HCL syntax. Terraform’s HCL has subtle syntax rules (like trailing commas not being allowed in certain places). Always run terraform validate after generation. If it fails, paste the full error into Agent mode — it usually fixes HCL syntax on the first try.

Security groups are too permissive. Agent defaults to convenience over security. It will generate 0.0.0.0/0 ingress rules unless your project rules explicitly prohibit this. The infrastructure rules at the top of this article prevent this, but always review security group rules manually.

Generated resources conflict with existing state. If you ask Agent to create a resource that already exists in your Terraform state, applying will fail. Use Ask mode first: “Given our existing infrastructure, what resources do I already have and what do I need to add?” Reference your state file or existing modules.

Docker builds are too large. Agent sometimes copies unnecessary files into the image. Check that the .dockerignore excludes tests, docs, and source files. Multi-stage builds should copy only the compiled output and production dependencies.

Environment configs drift apart. When you update a module, you need to update all environment configs. Ask Agent: “I changed the api-service module to add a new variable ‘enable_waf’. Update all environment tfvars files to include this variable with appropriate values.”