Top 10 Interview Questions On AWS Infrastructure as Code (IaC)
Back to Blog
Interview questions

Top 10 Interview Questions On AWS Infrastructure as Code (IaC)

Sam
May 31, 2025
18 min read

Welcome back to our AWS Cloud Engineer Interview Series! In [url=https://career-central.com/blog-page/aws-cloud-engineer-interview-questions-1748367750096x216225674221322240]Part 1[/url], we walked through advanced scenario-based and behavioral questions—covering topics like VPC architecture, security best practices, and troubleshooting strategies to showcase your big-picture cloud design thinking. In [url=https://career-central.com/blog-page/top-10-interview-questions-on-aws-fundamentals-1748369210428x357463418304987140]Part 2[/url], we drilled into AWS Fundamentals with ten questions on Compute (EC2 instance types, pricing models, Auto Scaling), Storage (S3, EBS, EFS, Glacier), and Databases (RDS, DynamoDB, Aurora), complete with answer frameworks and real-world examples. Then, in [url=https://career-central.com/blog-page/top-10-interview-questions-on-aws-aws-networking--security-fundamentals-1748689514978x274048999219265540]Part 3[/url], we shifted focus to Networking & Security—exploring VPC/subnet design, route tables, NAT gateways, Security Groups vs. NACLs, and IAM (users, groups, roles, policies, and best practices).

Now, in this Part 4 installment, we turn to Infrastructure as Code—an essential skill for any AWS Cloud Engineer. You’ll find ten targeted questions on CloudFormation vs. Terraform (pros and cons, modules vs. stacks) and Templates & State Management (drift detection, rollbacks, version control). Each question includes clear guidance on how to structure your answer in an interview, real-world tie-ins from production environments, and tips for demonstrating that you can deploy, manage, and maintain AWS resources reliably and at scale. Let’s dive into IaC best practices and get you ready to ace those IaC interview questions!

[b]1. “Compare CloudFormation and Terraform in terms of language, ecosystem support, and learning curve.”[/b] [b]How to Answer:[/b] [ml][ul][li indent=0 align=left][b]Language & Syntax:[/b][/li][ul data=1][li indent=1 align=left][i]CloudFormation:[/i] JSON or YAML—nested syntax that can become verbose.[/li][li indent=1 align=left][i]Terraform:[/i] HashiCorp Configuration Language (HCL)—more concise, human-readable.[/li][/ul][li indent=0 align=left][b]Ecosystem & Provider Support:[/b][/li][ul data=1][li indent=1 align=left][i]CloudFormation:[/i] AWS-native, full coverage of AWS services as soon as they’re released. Lacks first-class support for non-AWS resources.[/li][li indent=1 align=left][i]Terraform:[/i] Multi-cloud (AWS, Azure, GCP, Kubernetes, VMware, etc.) via provider plugins. Often lags by a few weeks or months in supporting brand-new AWS services, but community modules can bridge gaps.[/li][/ul][li indent=0 align=left][b]Learning Curve:[/b][/li][ul data=1][li indent=1 align=left][i]CloudFormation:[/i] Steeper at first because you must learn Attribute references (e.g., !Ref, !GetAtt), intrinsic functions, and nested stacks. AWS-specific terminology can be confusing initially—but if you already know AWS deeply, it feels more “native.”[/li][li indent=1 align=left][i]Terraform:[/i] Easier to pick up—HCL is designed to read like natural language. State files are explicit, so understanding lifecycle and dependencies can be more intuitive for newcomers.[/li][/ul][li indent=0 align=left][b]Real-World Tip:[/b][/li][ul data=1][li indent=1 align=left]If you’ve ever migrated an AWS-only project to Terraform to gain multi-cloud flexibility, mention that: “At my previous company, we standardize on Terraform so that even when we spun up Azure resources for a proof-of-concept, we reused familiar tooling and state management.”[/li][/ul][/ul][/ml] [b]2. “How do you handle dynamic references (e.g., ARNs) differently in CloudFormation vs. Terraform?”[/b] [b]How to Answer:[/b] [ml][ul][li indent=0 align=left][b]CloudFormation:[/b][/li][ul data=1][li indent=1 align=left]Use intrinsic functions like !Ref, !GetAtt, Fn::Sub, and Fn::Join. For example:[/li][/ul][/ul][/ml][code]MyBucketPolicy:   Type: AWS::S3::BucketPolicy   Properties:     Bucket: !Ref MyBucket     PolicyDocument:       Version: '2012-10-17'       Statement:         - Effect: Allow           Action: s3:GetObject           Resource: !Sub arn:aws:s3:::${MyBucket}/* [/code][ml][ul][ul data=1][li indent=1 align=left]Must understand evaluation order: !Ref resolves the logical ID to the physical ID (e.g., bucket name), while !GetAtt pulls attributes (e.g., ARN or endpoint).[/li][/ul][li indent=0 align=left][b]Terraform:[/b][/li][ul data=1][li indent=1 align=left]Interpolation syntax directly references resources by name. For example:[/li][/ul][/ul][/ml][code]resource "aws_s3_bucket" "my_bucket" {   bucket = "my-app-bucket" }

resource "aws_s3_bucket_policy" "bucket_policy" {   bucket = aws_s3_bucket.my_bucket.id   policy = jsonencode({     Version = "2012-10-17"     Statement = [{       Action   = "s3:GetObject"       Effect   = "Allow"       Resource = "${aws_s3_bucket.my_bucket.arn}/"       Principal = ""     }]   }) } [/code][ml][ul][ul data=1][li indent=1 align=left]Terraform automatically tracks dependencies by inspecting these references, ensuring resources are created or destroyed in the correct order.[/li][/ul][li indent=0 align=left][b]Tip:[/b] Emphasize that Terraform’s interpolation is more straightforward and type-safe, whereas CloudFormation’s intrinsic functions require you to mentally map which function to use for ARN vs. ID vs. attribute.[/li][/ul][/ml] [b]3. “What are the main pros and cons of using CloudFormation in large, AWS-only environments?”[/b] [b]How to Answer:[/b] [ml][ul][li indent=0 align=left][b]Pros:[/b][/li][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Deep AWS Integration:[/b] Instantly supports new AWS features and resources—no waiting on a provider update.[/li][li indent=1 align=left][b]Drift Detection:[/b] Built-in “Detect drift” feature to compare deployed stacks against local templates.[/li][li indent=1 align=left][b]Change Sets:[/b] Preview modifications before applying them (e.g., see if a DB replace is needed).[/li][li indent=1 align=left][b]Stack Policies:[/b] Prevent accidental updates to critical resources (e.g., RDS instances).[/li][/ol][/ol][/ml][ml][ul][li indent=0 align=left][b]Cons:[/b][/li][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Steep Verbosity:[/b] Large YAML/JSON files can become difficult to read/maintain, especially with deeply nested resources or complex mappings.[/li][li indent=1 align=left][b]Limited Non-AWS Coverage:[/b] If you need to provision, say, GitHub repositories or DigitalOcean droplets alongside AWS, you’ll need separate tooling or custom resources.[/li][li indent=1 align=left][b]Rollback Behavior:[/b] By default, if any resource fails to create, the entire stack rolls back, which can mask root-cause errors unless you disable rollback to see the broken resource.[/li][/ol][/ol][/ml][ml][ul][li indent=0 align=left][b]Real-World Example:[/b][/li][ul data=1][li indent=1 align=left]“At my last job, we had 300+ microservices each with its own CloudFormation stack. We split templates into nested stacks (e.g., networking, security, compute) and used AWS CodePipeline to orchestrate deployments. This gave us fast access to new AWS features but required strict naming conventions and modularization to avoid template sprawl.”[/li][/ul][li indent=0 align=left][b]Tip:[/b] If you’ve had to work around CloudFormation’s limits (e.g., template size maxed out at 51,200 bytes), mention how you refactored resources into nested stacks or used S3 to host larger templates.[/li][/ul][/ml] [b]4. “Why might an organization choose Terraform over CloudFormation, even if they’re exclusively on AWS?”[/b] [b]How to Answer:[/b] [ml][ul][li indent=0 align=left][b]Modular Reuse:[/b][/li][ul data=1][li indent=1 align=left]Terraform’s module registry and ability to version modules (e.g., in a private module registry or GitHub) often makes sharing and reusing patterns easier than CloudFormation’s nested stacks.[/li][/ul][li indent=0 align=left][b]Multi-Cloud Possibility:[/b][/li][ul data=1][li indent=1 align=left]Even if currently AWS-only, Terraform future-proofs your infrastructure if you plan to explore other clouds (e.g., GCP, Azure) or hybrid paths (e.g., provisioning VMware on-prem).[/li][/ul][li indent=0 align=left][b]State Management Flexibility:[/b][/li][ul data=1][li indent=1 align=left]Terraform allows remote state backends (e.g., S3 with DynamoDB for locking, or Terraform Cloud), giving granular control over state locking, versioning, and access. CloudFormation’s “state” is effectively the stack itself, which can be harder to audit or compare across environments.[/li][/ul][li indent=0 align=left][b]HCL Readability & Tooling:[/b][/li][ul data=1][li indent=1 align=left]Many engineers find HCL simpler to read and write. Terraform also has terraform fmt, terraform validate, and terraform graph CLI commands that help enforce style, catch syntax errors, and visualize resource graphs.[/li][/ul][li indent=0 align=left][b]Real-World Tie-in:[/b][/li][ul data=1][li indent=1 align=left]“Our team standardized on Terraform because we had one project on Azure and one on AWS. Even for AWS microservices, we used Terraform modules to encapsulate VPC + common security settings—then versioned those modules in a private registry. This consistency reduced onboarding time for new engineers.”[/li][/ul][li indent=0 align=left][b]Tip:[/b] Acknowledge that CloudFormation is battle-tested for AWS, but Terraform’s flexibility often outweighs that if an org values multi-cloud or wants a single, unified IaC toolchain.[/li][/ul][/ml] [b]5. “Explain the concepts of ‘modules’ in Terraform vs. ‘stacks’ (or nested stacks) in CloudFormation. When would you use each?”[/b] [b]How to Answer:[/b] [ml][ul][li indent=0 align=left][b]Terraform Modules:[/b][/li][ul data=1][li indent=1 align=left]A module is a directory containing Terraform configuration (e.g., main.tf, variables.tf, outputs.tf). You can call it from other configs via module "name" { source = "<path-or-registry>" }.[/li][li indent=1 align=left][b]Use Cases:[/b][/li][ul data=2][li indent=2 align=left][i]Encapsulation:[/i] Encapsulate VPC creation, security groups, or ELBs behind a module interface.[/li][li indent=2 align=left][i]Versioning:[/i] Publish modules (e.g., terraform-aws-modules/vpc/aws) with version tags, enabling consumers to pin to a specific version.[/li][li indent=2 align=left][i]Reusability:[/i] Use the same VPC module across dev, staging, and prod by passing different variable values (CIDR blocks, AZ count, etc.).[/li][/ul][/ul][li indent=0 align=left][b]CloudFormation Stacks & Nested Stacks:[/b][/li][ul data=1][li indent=1 align=left]A [b]Stack[/b] is a collection of AWS resources you manage as a single unit via one template.[/li][li indent=1 align=left][b]Nested Stacks:[/b] Use the AWS::CloudFormation::Stack resource type to reference another template stored in S3. The parent stack can pass parameters to the nested one.[/li][li indent=1 align=left][b]Use Cases:[/b][/li][ul data=2][li indent=2 align=left][i]Logical Separation:[/i] Split your template into “networking.yaml,” “security.yaml,” “compute.yaml,” etc., then include them as nested stacks.[/li][li indent=2 align=left][i]Reduce Template Size:[/i] Each nested stack can be under the template size limit (51,200 bytes).[/li][li indent=2 align=left][i]Failure Isolation:[/i] If a nested stack errors, you see precisely which nested stack failed, making debugging easier.[/li][/ul][/ul][li indent=0 align=left][b]When to Use Each:[/b][/li][ul data=1][li indent=1 align=left][b]Terraform Modules:[/b] If you want a portable, versioned, multi-cloud component (e.g., a Docker-EKS cluster module that could work on AWS and scaled variants for Azure or GCP).[/li][li indent=1 align=left][b]CloudFormation Nested Stacks:[/b] When you need deep AWS service coverage immediately upon release, or want to enforce strict AWS-native provisioning pipelines (e.g., integrate directly into CodePipeline).[/li][/ul][li indent=0 align=left][b]Real-World Example:[/b][/li][ul data=1][li indent=1 align=left]“In one project, I created a Terraform module for ‘shared-network’ (VPC, subnets, NAT, IGW) that we reused across multiple services. In CloudFormation, I had a set of nested stacks: a base ‘networking’ stack, a ‘security’ stack (security groups, NACLs), and a ‘compute’ stack (EC2 and ASG). Whenever we updated networking, only the networking nested stack was re-deployed—reducing blast radius.”[/li][/ul][li indent=0 align=left][b]Tip:[/b] Emphasize how modules and nested stacks affect your CI/CD pipeline: Terraform modules are versioned via Git tags or registry versions; CloudFormation nested stacks require you to upload updated templates to S3 (often automated via CI).[/li][/ul][/ml] [b]6. “What is ‘drift’ in the context of Infrastructure as Code, and how do you detect and remediate it in both CloudFormation and Terraform?”[/b] [b]How to Answer:[/b] [ml][ul][li indent=0 align=left][b]Definition of Drift:[/b][/li][ul data=1][li indent=1 align=left]Occurs when the real infrastructure resources no longer match the desired configuration defined in your templates or state files—often because someone made manual console/API changes.[/li][/ul][li indent=0 align=left][b]CloudFormation Drift Detection:[/b][/li][/ul][/ml]1.                      [b]Enable Drift Detection on a Stack:[/b] Via AWS Console, CLI (AWS cloudformation detect-stack-drift --stack-name MyStack), or SDK. 2.                      [b]Review Drift Results:[/b] Run AWS cloudformation describe-stack-resource-drifts to list which resources differ (e.g., a Security Group rule manually added). 3.                      [b]Remediate:[/b] Either manually update the template to match the live configuration or update the live resource to match the template, then run AWS cloudformation detect-stack-drift again to confirm. [ml][ul][li indent=0 align=left][b]Terraform Drift Detection:[/b][/li][/ul][/ml]1.                      [b]Run terraform plan:[/b] Terraform compares actual resource attributes (by reading via API) to the state file and configuration. Any differences show up as “to be updated” or “to be replaced.” 2.                      [b]Example:[/b] If someone manually changed an EC2 instance’s instance_type from t3.medium to t3.large, terraform plan will show that difference. 3.                      [b]Remediate:[/b] Decide whether to accept the change by updating code (e.g., set instance_type = "t3.large") or revert the live resource (e.g., terraform apply to enforce t3.medium). [ml][ul][li indent=0 align=left][b]Real-World Tie-in:[/b][/li][ul data=1][li indent=1 align=left]“At my previous company, we had a ‘snowflake’ web server manually resized during a traffic spike. When I ran terraform plan, it flagged the AWS resource as instance_type different. I updated our Terraform config to match t3.large, which pushed that change to version control. Going forward, developers knew to use code rather than console to adjust instance sizes.”[/li][/ul][li indent=0 align=left][b]Tip:[/b] Emphasize that drift detection should be part of your CI/CD pipeline—e.g., in a daily pipeline job to run terraform plan (with -detailed-exitcode) or a scheduled AWS Lambda to trigger CloudFormation drift detection and alert on any anomalies.[/li][/ul][/ml] [b]7. “How do you perform rollbacks in CloudFormation versus Terraform when a deployment fails or introduces unwanted changes?”[/b] [b]How to Answer:[/b] [ml][ul][li indent=0 align=left][b]CloudFormation Rollbacks:[/b][/li][ul data=1][li indent=1 align=left][b]Automatic Rollback (default):[/b] If any resource creation/update fails, CloudFormation automatically rolls back the entire stack to its previous stable state.[/li][li indent=1 align=left][b]Disable Rollback (for Debugging):[/b] Use --disable-rollback on the CLI or “Retain failed resources” in the console to inspect the broken resource and logs.[/li][li indent=1 align=left][b]Change Sets:[/b] Preview changes before applying. If you spot a destructive update to an RDS or Lambda function, you can cancel before execution.[/li][li indent=1 align=left][b]Manual Rollback:[/b] If you applied a change set that introduced issues, you can:[/li][/ul][/ul][/ml][ml][ol][ol data=2][ol data=2][li indent=2 align=left]Revert the template to the previous version in S3 (or template history).[/li][li indent=2 align=left]Execute an “Update Stack” with the old template.[/li][/ol][/ol][/ol][/ml][ml][ul][li indent=0 align=left][b]Terraform Rollbacks:[/b][/li][ul data=1][li indent=1 align=left]Terraform itself does not automatically roll back mid-apply. If an error occurs during terraform apply, Terraform stops, leaving any successfully created resources intact.[/li][li indent=1 align=left][b]Recommended Approach:[/b][/li][/ul][/ul][/ml][ml][ol][ol data=2][ol data=2][li indent=2 align=left]Write idempotent modules—so applying the “previous version” of code will converge resources back.[/li][li indent=2 align=left]Use terraform state rm to manually remove problematic resources if they block re-apply.[/li][li indent=2 align=left]Use terraform import to reconcile resources that were changed outside of Terraform.[/li][/ol][/ol][/ol][/ml][ml][ul][ul data=1][li indent=1 align=left][b]State File Backups:[/b] Terraform keeps a backup of the last state (terraform.tfstate.backup), so you can restore if state corruption occurs.[/li][/ul][li indent=0 align=left][b]Real-World Example:[/b][/li][ul data=1][li indent=1 align=left]“When we accidentally changed an ALB listener rule in CloudFormation, the stack update failed on a validation error. Because we left auto-rollback enabled, the load balancer stayed intact. We corrected the template (fixing the ARN reference) and re-run the update. In Terraform, a similar scenario left half-created resources; I used a combination of terraform state rm to remove the invalid LB rule and then re-applied the correct code.”[/li][/ul][li indent=0 align=left][b]Tip:[/b] Highlight how you incorporate manual validation (e.g., using terraform plan or CloudFormation Change Sets) to catch potential destructive changes before they go live.[/li][/ul][/ml] [b]8. “Discuss how version control (e.g., Git) fits into managing your IaC templates and state. What branching or tagging strategies do you recommend?”[/b] [b]How to Answer:[/b] [ml][ul][li indent=0 align=left][b]IaC Code in Git Repositories:[/b][/li][ul data=1][li indent=1 align=left]Store all templates/modules in a dedicated Git repo (or a mono-repo).[/li][li indent=1 align=left]Organize directories by environment (e.g., prod/, staging/, dev/), or use environment-specific workspaces (Terraform) or parameter overrides (CloudFormation).[/li][/ul][li indent=0 align=left][b]Branching Strategies:[/b][/li][ul data=1][li indent=1 align=left][b]GitFlow:[/b][/li][ul data=2][li indent=2 align=left]main (protected) contains production-ready IaC.[/li][li indent=2 align=left]develop for integration and QA.[/li][li indent=2 align=left]Feature branches (feature/vpc-modularization) for new stacks or modules.[/li][li indent=2 align=left]Release branches (release/v1.2.0) to prepare for versioned rollouts.[/li][li indent=2 align=left]Hotfix branches (hotfix/fix-broken-lb) to patch critical issues in production.[/li][/ul][li indent=1 align=left][b]Trunk-Based Development:[/b][/li][ul data=2][li indent=2 align=left]Short-lived feature branches or direct commits to main/master, with CI gated checks (e.g., terraform validate, cfn-lint).[/li][/ul][/ul][li indent=0 align=left][b]Tagging & Versioning:[/b][/li][ul data=1][li indent=1 align=left]Tag Git commits that correspond to production deployments (e.g., v2025.06.01).[/li][li indent=1 align=left]For Terraform modules, publish versioned releases (e.g., module/vpc/aws/1.3.0) in a private module registry.[/li][li indent=1 align=left]For CloudFormation nested stacks, store templates in S3 with versioned object keys or use a CI process to automatically upload new templates to a standardized S3 path (e.g., s3://iac-templates/prod/networking/v1.2.0.yaml).[/li][/ul][li indent=0 align=left][b]Managing State Files:[/b][/li][ul data=1][li indent=1 align=left][b]Terraform Remote State:[/b][/li][ul data=2][li indent=2 align=left]Use S3 backend with server-side encryption (SSE-KMS).[/li][li indent=2 align=left]Enable DynamoDB table for state locking to prevent concurrent writes.[/li][li indent=2 align=left]Use workspaces (e.g., dev, staging, prod) to isolate state per environment.[/li][/ul][li indent=1 align=left][b]CloudFormation Stack Versions:[/b][/li][ul data=2][li indent=2 align=left]CloudFormation implicitly versions stack updates in “StackEvents,” but if you need to track template changes, store each template revision in Git and embed a version or commit hash as a stack tag.[/li][/ul][/ul][li indent=0 align=left][b]Real-World Tie-in:[/b][/li][ul data=1][li indent=1 align=left]“We used trunk-based development: every change to Terraform code had to pass terraform fmt, terraform validate, and a terraform plan review in our CI pipeline. We stored state in S3 with DynamoDB locking. Production deployments triggered a Git tag (e.g., prod-2025-05-30) so we could quickly roll back by checking out that tag and re-running apply.”[/li][/ul][li indent=0 align=left][b]Tip:[/b] Stress that version control is as crucial for IaC as for application code—merge requests (PRs) should always include a diff of the plan (for Terraform) or Change Set (for CloudFormation) so reviewers can approve infrastructure changes before they’re pushed.[/li][/ul][/ml] [b]9. “How do you detect and remediate drift at scale when managing hundreds of CloudFormation stacks or Terraform modules?”[/b] [b]How to Answer:[/b] [ml][ul][li indent=0 align=left][b]CloudFormation at Scale:[/b][/li][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Automated Drift Detection Jobs:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]Schedule a daily AWS Lambda function to loop through all stack names (using aws cloudformation describe-stacks) and call detect-stack-drift. Send alerts via SNS or Slack when any stack is DRIFTED.[/li][/ul][/ul][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Tagging & Filtering:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]Tag each stack with Environment: Production or Team: Analytics. Your Lambda can filter by tag using ListStacks + ListStackResources.[/li][/ul][/ul][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Remediation:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]Generate Change Sets automatically to reconcile drifted resources or alert the responsible team to update the template or revert manual changes.[/li][/ul][/ul][li indent=0 align=left][b]Terraform at Scale:[/b][/li][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]CI/CD Orchestration:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]Use a pipeline (e.g., GitLab CI or Jenkins) that loops through each Terraform workspace or directory, runs terraform plan -detailed-exitcode, and fails if any drift is detected (exit code 2).[/li][/ul][/ul][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Terraform Cloud/Enterprise:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]If using Terraform Cloud, enable Continuous Run triggers so that any changes to remote resources (e.g., AWS console changes) can be detected when another user triggers a run.[/li][/ul][/ul][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]State Monitoring:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]Keep a “drift report” in S3 or a database, updating the timestamp of last successful plan check.[/li][/ul][/ul][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Remediation:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]For minor drifts (e.g., building permissions), a team can manually approve a run to reapply the correct infrastructure. For major drifts (e.g., accidental deletion), have automated backups of state to restore prior state.[/li][/ul][/ul][li indent=0 align=left][b]Real-World Example:[/b][/li][ul data=1][li indent=1 align=left]“We had over 150 CloudFormation stacks across Dev, QA, and Prod. We wrote a Python Lambda that runs nightly, calls detect-stack-drift, and if any stacks reported drift, it opened a Jira ticket with a link to the drift summary. Similarly, our Terraform repos used GitHub Actions: each PR triggered a plan, and a scheduled nightly job ran terraform plan on the default branch to catch any drift. We’d then assign owners to fix configuration mismatches.”[/li][/ul][li indent=0 align=left][b]Tip:[/b] Highlight that combining automated detection with clear ownership (via tagging and notification) ensures drift is remediated before it leads to outages or compliance failures.[/li][/ul][/ml] [b]10. “When managing template changes over time, how do you enforce version control, review, and auditability for both CloudFormation and Terraform?”[/b] [b]How to Answer:[/b] [ml][ul][li indent=0 align=left][b]CloudFormation Best Practices:[/b][/li][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Store Templates in Git:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]Keep every template (root and nested) in version-controlled repositories (e.g., iac/cloudformation/networking/v1.0.0.yaml).[/li][/ul][/ul][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Template Validation & Linting:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]Use tools like cfn-lint or cfn_nag in pre-commit hooks or CI pipelines to catch syntax errors, insecure security group rules, or deprecated resource types.[/li][/ul][/ul][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Change Set Reviews:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]Always generate a Change Set via CLI/SDK or CI. Have a policy that no stack update occurs without at least one peer review confirming the Change Set contents.[/li][/ul][/ul][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Template Tagging & Metadata:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]Embed metadata (e.g., Metadata: CommitHash: abc123) in the template so that if someone inspects the live stack, they know exactly which Git commit created it.[/li][/ul][/ul][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Audit Trails:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]CloudTrail logs every CreateStack, UpdateStack, and API call. If any template was run outside of the CI pipeline, you can trace who invoked it and when.[/li][/ul][/ul][li indent=0 align=left][b]Terraform Best Practices:[/b][/li][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Module Version Pinning:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]In root modules, reference module source with a specific version:[/li][/ul][/ul][/ul][/ml] [code]module "vpc" {   source  = "git::ssh://git@github.com/myorg/terraform-aws-vpc.git?ref=v2.1.0"   # … } [/code][ml][ul][ul data=2][ul data=2][li indent=2 align=left]This ensures that breaking changes in upstream modules don’t automatically impact your environments.[/li][/ul][/ul][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]State Locking & Version History:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]Use remote backends (S3 + DynamoDB) so that your state file is protected and versioned. If someone manually tampers with resources, your state backup can restore the prior correct state.[/li][/ul][/ul][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Pull Request–Driven Changes:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]Enforce that every Terraform change lives in a feature branch. The CI pipeline runs terraform fmt, terraform validate, terraform plan, and publishes the plan in the PR for reviewers. Only after approval and merge to main does CI run terraform apply.[/li][/ul][/ul][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Audit with Sentinel or Open Policy Agent:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]If using Terraform Cloud/Enterprise, define Sentinel policies to prevent certain risky changes (e.g., disallow public S3 buckets, require encryption on RDS).[/li][/ul][/ul][/ul][/ml][ml][ol][ol data=1][li indent=1 align=left][b]Tagging & Outputs:[/b][/li][/ol][/ol][/ml][ml][ul][ul data=2][ul data=2][li indent=2 align=left]Tag resources with CreatedBy: GitCommit or Env: prod so you can trace which commit created which AWS resources. Terraform outputs can include git_commit = "${chomp(exec("git rev-parse HEAD", ""))}" for auditability.[/li][/ul][/ul][li indent=0 align=left][b]Real-World Tie-in:[/b][/li][ul data=1][li indent=1 align=left]“Our organization required strict audit controls: no IaC changes could occur outside of a GitHub PR. Each PR triggered a CircleCI job that validated CloudFormation templates with cfn-lint, generated a Change Set, and attached the Change Set link to the PR. For Terraform, we used Atlantis to coordinate plan/apply only after PR approval. All resources were tagged with CreatedBy: <username> and CommitHash: <sha>, so security auditors could verify that every resource in the account corresponded to an approved Git commit.”[/li][/ul][li indent=0 align=left][b]Tip:[/b] Emphasize how combining Git-based review workflows, automated linting/validation, and resource tagging enables full traceability and compliance—critical for production environments subject to audits.[/li][/ul][/ml] [b]Final Tips for Interviewing on Infrastructure as Code (IaC):[/b] [b][/b] [ml][ol][li indent=0 align=left][b]Be Explicit with Examples:[/b] Whenever you claim “we modularized our Terraform code,” specify how (e.g., directory structure, variables.tf abstractions, module registry usage).[/li][li indent=0 align=left][b]Discuss Trade-Offs:[/b] No tool is perfect. If you prefer Terraform for readability, also acknowledge scenarios where CloudFormation’s native features (stack policies, Change Sets) shine.[/li][li indent=0 align=left][b]Tie Answers to Real Impact:[/b] Quantify improvements—e.g., “By adopting Terraform modules, we reduced duplicate code by 60% and sped up VPC provisioning from 20 minutes to 5 minutes.”[/li][li indent=0 align=left][b]Show How You Prevent Common Pitfalls:[/b] Talk about drift detection, state locking, and template linting to demonstrate you know how to maintain long-lived IaC pipelines rather than just writing one-off scripts.[/li][li indent=0 align=left][b]Ask Clarifying Questions:[/b] If an interviewer asks “Design an IaC approach for a banking app,” probe for compliance requirements, expected team size, multi-region needs, and rollback SLAs before diving into CloudFormation vs. Terraform debate.[/li][/ol][/ml] By mastering these ten questions—and focusing on how you’ve implemented, modularized, and maintained IaC at scale—you’ll show interviewers that you’re prepared to adopt best practices and keep production infrastructure reliable, auditable, and drift-free. Good luck!