Skip to content
February 3, 2025AI + Cloud6 min read

PromptEngineeringforCloudEngineers:GettingtheBestfromClaudeCode

Claude CodePrompt EngineeringTerraformAWSDevOps

You've started using Claude Code for infrastructure work. You know it can generate Terraform, write CI/CD pipelines, and debug Kubernetes manifests. But are you getting the best output? The difference between a mediocre AI response and a production-ready one often comes down to how you ask.

After months of using Claude Code daily for cloud engineering, I've developed a set of prompt engineering patterns that consistently produce high-quality, secure, and deployable infrastructure code. Here's everything I've learned.

The Foundation: Context is Everything

The single biggest improvement you can make to your Claude Code prompts is providing context. Claude doesn't know your AWS account structure, naming conventions, tagging strategy, or security requirements unless you tell it.

Bad Prompt

Write Terraform for an S3 bucket

Good Prompt

Write a Terraform resource for an S3 bucket with these requirements:
- Environment: production
- Region: us-east-1
- Naming convention: {project}-{env}-{purpose}, project="payments"
- Encryption: AWS KMS with a dedicated key
- Versioning: enabled
- Lifecycle: transition to IA after 30 days, Glacier after 90, expire after 365
- Block all public access
- Enable access logging to a separate logging bucket
- Tags: follow our standard: Environment, Project, ManagedBy=terraform, CostCenter=engineering
- Use variables for project name and environment

The second prompt produces code that's ready for a PR. The first produces a toy example.

Pattern 1: The Architecture Specification Prompt

When generating complex infrastructure, I use this template:

## Context
I'm building [system description] on AWS using Terraform.
Account structure: [details]
Region: [primary and DR regions]
Existing infrastructure: [what already exists]

## Requirements
[Numbered list of specific requirements]

## Constraints
- Security: [compliance requirements]
- Cost: [budget considerations]
- Naming: [conventions]
- Tags: [required tags]

## Expected Output
- Terraform resources with variables and outputs
- Follows [module structure/file organization]
- Include comments explaining design decisions

This pattern works because it mirrors how an experienced engineer would brief a colleague. Claude excels when given the same context a human would need.

Pattern 2: The Security-First Prompt

For IAM and security resources, I always include these elements:

Generate an IAM policy for [role/service] that:

ALLOWED ACTIONS:
- [specific actions, not wildcards]

RESOURCES:
- [specific ARNs with account ID variables]

CONDITIONS:
- [IP restrictions, VPC endpoint requirements, MFA requirements]

DENIED ACTIONS:
- [explicit denies for sensitive operations]

REQUIREMENTS:
- No wildcard (*) actions or resources
- Use aws:PrincipalOrgID condition where applicable
- Include resource-level permissions, not service-level
- Add RequestedRegion condition to restrict to approved regions
- Output the policy as both JSON and Terraform aws_iam_policy_document

By explicitly requesting "no wildcards" and "specific ARNs," you steer Claude toward secure-by-default output.

Pattern 3: The Debugging Prompt

When troubleshooting, provide the complete error context:

I'm getting this error deploying a Terraform configuration:

ERROR:
[paste exact error message]

TERRAFORM RESOURCE:
[paste the relevant resource block]

PROVIDER VERSION:
[terraform and provider versions]

WHAT I'VE TRIED:
[list troubleshooting steps already taken]

AWS ENVIRONMENT:
[relevant details: account type, organization setup, etc.]

Please:
1. Explain why this error occurs
2. Provide the corrected resource block
3. Explain what changed and why
4. Suggest how to prevent this in the future

The "what I've tried" section is crucial -- it prevents Claude from suggesting things you've already done and steers it toward deeper analysis.

Pattern 4: The Module Refactoring Prompt

For improving existing code:

Refactor this Terraform module to follow best practices:

CURRENT CODE:
[paste existing code]

ISSUES I'VE IDENTIFIED:
- [known problems]

REFACTORING GOALS:
- Make it reusable across environments (dev/staging/prod)
- Add input validation with variable validations
- Add meaningful outputs
- Implement proper state management considerations
- Add lifecycle rules where appropriate
- Follow HashiCorp's module structure guidelines

CONSTRAINTS:
- Must be backward-compatible with existing state
- Don't change resource names (would force recreation)

The backward-compatibility constraint is critical in production environments. Claude respects these constraints when explicitly stated.

Pattern 5: The CI/CD Pipeline Prompt

For generating pipelines:

Generate a GitHub Actions workflow for deploying Terraform with:

TRIGGER: Pull request to main branch
ENVIRONMENTS: dev -> staging -> prod (with manual approval for prod)

STEPS PER ENVIRONMENT:
1. Checkout code
2. Setup Terraform with version pinning
3. Configure AWS credentials via OIDC (not access keys)
4. terraform init with S3 backend (bucket per environment)
5. terraform validate
6. terraform plan (save plan file)
7. Post plan output as PR comment
8. terraform apply (only on merge to main)

SECURITY:
- Use OIDC for AWS auth, not static credentials
- Pin all action versions to SHA, not tags
- Run checkov/tfsec for security scanning
- Require plan approval before apply

NOTIFICATIONS:
- Slack notification on success/failure

Include the required IAM trust policy for the OIDC provider.

Advanced Technique: Chain of Thought Prompting

For complex architectural decisions, I ask Claude to think step-by-step:

I need to design a disaster recovery strategy for our ECS-based
microservices application. Before writing any Terraform, please:

1. Analyze the trade-offs between pilot light, warm standby,
   and multi-site active-active for our use case
2. Recommend an approach based on our RTO of 15 minutes
   and RPO of 5 minutes
3. List all AWS services needed for the chosen strategy
4. Identify potential failure modes and how to handle each
5. Then generate the Terraform implementation

Our current setup: [describe architecture]
Our budget constraint: [budget]
Compliance requirements: [requirements]

By asking Claude to reason before coding, you get better architectural decisions and more thoughtful implementations.

Building a Prompt Library

I maintain a library of reusable prompt templates organized by category:

  • Networking: VPC, subnets, security groups, transit gateway
  • Compute: ECS, EKS, Lambda, EC2 auto-scaling
  • Data: RDS, DynamoDB, ElastiCache, S3
  • Security: IAM, SCPs, Config rules, GuardDuty
  • CI/CD: GitHub Actions, Jenkins, CodePipeline
  • Monitoring: CloudWatch, alarms, dashboards, SNS

Each template includes the standard context sections, security requirements, and output format specifications. New team members can start producing quality IaC output on day one by using these templates.

Common Mistakes to Avoid

  1. Being too vague: "Make it secure" vs. "Enforce encryption at rest with KMS, restrict to VPC endpoint, require MFA for delete operations"
  2. Forgetting state implications: Always mention if resources already exist in state
  3. Not specifying versions: Pin Terraform and provider versions in your prompts
  4. Ignoring cost: Ask Claude to consider cost implications and suggest reserved/spot options
  5. Skipping validation: Always run terraform validate, tflint, and security scanners on AI-generated code

Conclusion

Prompt engineering for cloud infrastructure is a skill that compounds over time. Every prompt template you refine, every pattern you discover, makes your AI-assisted workflow faster and more reliable. The engineers who master this skill will have a massive productivity advantage in the years ahead.

Start building your prompt library today. Your future self -- and your on-call rotation -- will thank you.

Want to learn more about AI-powered cloud engineering? Check out my other posts on building self-healing infrastructure and automating operations controls.