Amazon DevOps Engineer Interview Questions & Answers

amazon icon

Questions with Detailed ExplanationsWith Detailed Explanations

(Last Updated: September 1, 2026)

11. An ALB is healthy, but 20% of requests return 502. How do you isolate the failing hop?ObservabilityMediumAmazon

Question Details

Correlate ALB access logs, target health and reason codes, connection metrics, any intermediate NLB observations, application logs, traces, and deployment versions for the same request population. Separate failures generated by the load balancer from target resets, timeouts, malformed responses, port or protocol mismatch, and application errors. State what a passing health check proves and what it cannot prove about real requests.

Short Interview Answer (30-60 seconds)

I would correlate the same failing requests across ALB logs, target health, connection signals, optional NLB evidence, application telemetry, traces, and deployment versions. I would first separate ALB-returned 502s from target-returned 502s, identify the first failing hop, correct that boundary, and verify the 502 rate returns to baseline.

Detailed Explanation

The system passes its simple health test, but one out of every five real requests still fails. The goal is to find the first place where those failing requests stop working correctly. I would compare evidence from each step of the request journey during the same time period. I would also check whether failures appeared after a release, settings change, or scaling event. Passing a simple health test only proves that one configured test request works. It does not prove that normal customer requests, heavier traffic, connected services, or every running application version work correctly.

Useful Questions to Ask the Interviewer
  1. Are clients receiving the 502 directly from the ALB, and is there an intermediate NLB anywhere in the affected request path?
  2. Are ALB access logs available, and can requests be correlated with timestamps, request IDs, or trace IDs?
  3. Did the 20% failure rate begin after a deployment, configuration change, scaling event, or target replacement?
  4. Are failures concentrated on specific targets, Availability Zones, deployment versions, routes, or request types?
  5. What protocol, port, path, thresholds, and accepted response codes are configured for the target health check?
An ALB is healthy, but 20% of requests return 502. How do you isolate the failing hop? diagram
How to Explain It in an Interview

I would treat this as a fault-boundary isolation problem. First I define one incident window and preserve evidence before changing code or configuration. Then I correlate the same request population across ALB access logs, target health, connection metrics, application telemetry, traces, optional NLB observations, and deployment versions.

I start with the ALB access log because it tells me what the ALB returned and what it observed from the target. I compare elb_status_code, target_status_code, target:port, request_processing_time, target_processing_time, response_processing_time, trace_id, error_reason, classification, and classification_reason when populated. If target_status_code is 502, the target produced an HTTP 502, so I move into application logs and traces. If the ALB returned 502 while the target status is missing and the ALB has connection, protocol, or response-classification evidence, I investigate the ALB-to-target boundary.

For that boundary, I look for target connection failures, resets or early closes, malformed HTTP responses, incorrect target port or protocol, TLS problems, security-group or network-ACL issues, and network-path problems. Connection metrics such as TargetConnectionErrorCount, connection counts, and reset-related evidence help show whether failures cluster around transport behavior. I correlate metrics by the same incident window because aggregate metrics do not identify an individual request by themselves.

Next I examine target health. Target-health reason codes such as Target.ResponseCodeMismatch, Target.Timeout, Target.FailedHealthChecks, and Elb.InternalError describe why a target may not be considered healthy. UnHealthyHostCount is different: it is a CloudWatch health metric, not a reason code. A passing health check proves that the load balancer can reach the target using the configured health-check protocol and port and that the configured health-check path returns an accepted result. It does not prove that real request paths, authentication, headers, payloads, dependencies, capacity under load, every business route, or the intended deployment version work correctly.

If the target returned 502, I correlate the request or trace identifier with application logs and distributed traces. I look for the first failing span or application event, including application-generated 5xx responses, malformed HTTP responses, crashes or restarts, connection-pool exhaustion, downstream database, cache, or API failures, and other resource pressure. Traces may be sampled, so the absence of a trace is not proof that a request did not occur. Logs and metrics still need to be correlated.

If an NLB is actually present in the architecture, I inspect it as an additional transport hop. I look for TCP resets, connection failures, rejected flow evidence, Availability Zone patterns, and capacity indicators. An NLB works at the transport layer and does not itself create an HTTP 502 response, but a reset or failed connection at that hop can cause an upstream HTTP component to fail the request.

I also treat timeout evidence separately. Target.Timeout, high target response time, slow application work, saturated connection pools, database or cache waits, and CPU pressure can identify a latency problem. However, an ALB request timeout normally appears as HTTP 504, so I do not label every timeout as a 502. I use timing evidence to distinguish timeout failures from 502 cases caused by resets, connection failures, early closes, or malformed responses.

Finally, I overlay deployment versions, feature flags, configuration changes, infrastructure changes, and scaling events on the failure timeline. A 20% failure rate can mean that only a subset of targets or one application version is bad. Once the evidence identifies the first failing boundary, I make the smallest safe correction supported by that evidence, such as correcting the target port or protocol, TLS configuration, network policy, malformed response, application defect, dependency issue, or faulty deployment.

For verification, I use the same production signals. The 502 rate should return to its normal baseline, the associated connection or application errors should disappear, target health should remain stable, and key latency and error indicators should improve. For prevention, I define a user-facing availability SLI, such as successful request ratio, and an appropriate SLO before choosing alert thresholds. I alert on sustained 5xx symptoms and error-budget impact with ownership, severity, runbook context, and noise controls. Dashboards should correlate ALB 5xx, target 5xx, target health, latency, application telemetry, and deployment versions. I also control trace sampling, retention, ingestion cost, high-cardinality attributes, clock skew, and missing telemetry, and I redact credentials, tokens, personal information, and sensitive payloads.

Technical Approach
  1. Define the incident time window and preserve evidence before making changes.
  2. Correlate the same failing request population using timestamps, target address, request IDs, or trace IDs.
  3. Inspect ALB access logs and compare elb_status_code with target_status_code plus ALB error or classification evidence.
  4. If the target returned 502, investigate application logs, traces, dependencies, crashes, malformed responses, and resource pressure.
  5. If the ALB returned 502 without a valid target response, inspect target connection failures, resets or early closes, port and protocol configuration, TLS, security groups, network ACLs, and network-path evidence.
  6. Review target-health reason codes separately from CloudWatch health metrics such as UnHealthyHostCount.
  7. Inspect connection and reset metrics for patterns aligned with the same failure window.
  8. If an intermediate NLB exists, inspect its TCP reset, connection, flow, Availability Zone, and capacity evidence as an additional transport hop.
  9. Treat timeout evidence as a separate branch because an ALB request timeout normally surfaces as 504 rather than 502.
  10. Correlate failures with deployment versions, feature flags, configuration changes, infrastructure changes, and scaling events.
  11. Apply only the smallest correction supported by the evidence.
  12. Verify that the 502 rate returns to baseline and that health, connection, application, and latency signals improve, then add SLO-based alerts, dashboards, and a runbook.
Practical Insights

The investigation becomes more expensive as traffic volume, target count, telemetry volume, and retention increase. ALB access logs can generate large data sets, while distributed traces consume more storage as sampling increases. High-cardinality values such as unrestricted request IDs should be used for logs and traces rather than careless metric labels because they can make metric systems expensive. Longer retention increases storage and query cost. Sampling lowers trace cost but can miss rare failures, so traces should be supported by logs and metrics. Operators must also account for missing telemetry, different system clocks, ingestion delays, maintenance effort, and privacy controls.

Why Interviewers Ask This

This question tests whether the candidate can isolate an intermittent production failure with correlated evidence instead of assuming that healthy targets mean the real request path is healthy. A strong answer distinguishes an ALB-returned 502 from a target-returned 502, follows the request boundary through network and application evidence, understands the limits of health checks, correlates failures with deployment versions, and makes the smallest correction supported by evidence.

Common interview mistakes

Common mistakes are assuming that healthy targets prove real requests are healthy, treating every ALB 502 as an application-generated 502, or relying on one metric without correlating the same request population. Another mistake is treating UnHealthyHostCount as a target-health reason code. Do not assume an NLB exists in every architecture or claim that an NLB itself generates HTTP 502. Do not classify every timeout as 502 because an ALB request timeout normally appears as 504. Other mistakes include changing configuration before preserving evidence, ignoring deployment versions, treating missing sampled traces as proof, mixing unrelated time windows, and logging credentials or sensitive payloads.

Interview tip

Explain the investigation as a request-by-request fault-boundary exercise. Start with ALB versus target status evidence, then walk through target health, connection behavior, application telemetry, optional NLB evidence, and deployment versions. Explicitly state what a passing health check proves and what it cannot prove about real traffic.

Interviewer may ask next
What does a passing ALB target health check prove, and what does it not prove?

It proves that the load balancer can reach the target using the configured health-check protocol and port and that the configured health-check path returns an accepted response under the configured health-check rules. It does not prove that real customer routes work, that authentication, headers, and payloads work, that dependencies are healthy, that performance under load is acceptable, that every business path avoids 5xx responses, or that the intended application version and feature flags are serving traffic.

How do you distinguish a target-generated 502 from an ALB-returned 502 caused by a bad target connection or response?

Correlate the ALB access log for the failing request. If target_status_code is 502, the target returned HTTP 502, so investigate application logs, traces, and downstream dependencies. If the ALB reports 502 while the target status is missing and ALB error or classification evidence indicates a connection or response problem, investigate the ALB-to-target boundary for connection failures, resets or early closes, malformed HTTP responses, TLS or protocol mismatches, wrong target ports, or network-path problems. Use supporting connection metrics and target-health evidence rather than relying on one field alone.

12. Cart abandonment rises for one payment method in one Region while infrastructure dashboards stay green. How do you triage it?ObservabilityHardAmazon

Question Details

Slice the user funnel by Region, payment method, application version, response code, and latency percentile. Correlate client-side events, API logs, traces, dependency calls, authorization outcomes, retries, and business success metrics. Define a comparison cohort, preserve the incident timeline, and explain what CPU, memory, and Pod health can rule out versus what they cannot establish about a payment-specific failure.

Short Interview Answer (30-60 seconds)

I would preserve the timeline, slice the payment funnel, compare the affected path with healthy cohorts, and correlate client, API, trace, dependency, authorization, retry, and business evidence. Green infrastructure narrows the search but does not prove payment success. I would confirm the boundary, fix it safely, and verify recovery.

Detailed Explanation

This question asks how I would find why more shoppers stop buying when they use one way to pay in one place, even though the normal health screens still look fine. I would first save what happened and when. Then I would compare each step of the buying journey with similar shoppers who are not having the problem. I would follow the affected customers from the first payment action to the final result. The goal is to prove where the problem begins, make the smallest safe change, and confirm that buying works normally again.

Useful Questions to Ask the Interviewer
  1. At which checkout step does the first clear drop appear: payment initiation, authorization, or order completion?
  2. Do we have a correlation ID or session ID that links client events, API logs, traces, and dependency calls?
  3. Should the healthy comparison include both the same Region with other payment methods and the same payment method in other Regions?
  4. Were there deployments, configuration changes, provider events, or mitigation actions near the first customer impact?
Cart abandonment rises for one payment method in one Region while infrastructure dashboards stay green. How do you triage it? diagram
How to Explain It in an Interview

I would start with the user-visible objective: restore successful checkout for the affected payment method and Region. The smallest useful signal set is funnel conversion, payment authorization success, order-completion success, response-code distribution, latency percentiles, retries, plus supporting client, API, dependency, and business evidence.

I would define SLIs before alert thresholds. An SLI, or service level indicator, is the behavior I measure. Useful SLIs here are payment-authorization success rate, order-completion success rate, payment-related error or timeout rate, and payment latency percentiles, broken down by Region and payment method. An SLO, or service level objective, is the acceptable target for an SLI. I would base symptom alerts on those objectives or a justified healthy baseline, not on CPU alone.

My investigation follows the same seven-step flow as the diagram:

  1. SYMPTOM: Confirm that abandonment is higher for one payment method in one Region while broad infrastructure health remains green.
  2. PRESERVE + SCOPE: Preserve the incident timeline, including first impact, deployments, configuration changes, provider events, and mitigations.
  3. SLICE + COMPARE: Slice by Region, payment method, application version, response code, and latency percentile. Compare the same Region with other payment methods, the same payment method in other Regions, and an equivalent healthy time window.
  4. CORRELATE EVIDENCE: Correlate client events, API logs, traces, dependency calls, authorization outcomes, retries, and business success metrics by a consistent session or correlation ID.
  5. TEST HYPOTHESIS: Test whether the difference is caused by a client or application regression, API behavior, a dependency or payment provider, authorization behavior, or configuration or data. Reject hypotheses contradicted by the healthy cohort and correlated evidence.
  6. ROOT CAUSE + FIX: Confirm the failing boundary before changing anything. Apply the smallest safe correction supported by evidence. If the risk is high, contain or roll back first.
  7. VERIFY + MONITOR: Verify funnel recovery, authorization and order-completion recovery, normalized response codes and latency, and no regression in the comparison cohort. Continue monitoring afterward.

Green infrastructure dashboards are useful, but limited. Healthy CPU, memory, Pod status, and broad capacity signals reduce suspicion of a widespread compute or orchestration problem. They cannot prove that a payment request was authorized correctly, that a dependency succeeded, that payment-specific configuration is correct, or that customers completed checkout.

The telemetry lifecycle also matters. Client instrumentation, APIs, services, dependencies, and business logic create the evidence. Instrumentation or a collector can enrich it with consistent attributes such as Region, payment method, application version, response code, service identity, and correlation ID. High-cardinality values such as raw user IDs should not become unrestricted metric labels. Traces may be sampled to control cost, while important business counters and error signals should remain complete enough to show the real symptom. Telemetry is transported through the observability pipeline, stored in the appropriate log, trace, and metric backends, queried using shared attributes, and retained long enough to cover the incident and comparison window.

There are important tradeoffs. Sampling lowers trace ingestion cost but can miss rare failures or bias the evidence if the sampling policy favors successful traffic. Aggregation makes dashboards cheaper and easier to read but can hide a payment-specific problem if Region or payment method is aggregated away. High-cardinality dimensions improve slicing but can increase storage and query cost. Missing client telemetry reduces confidence about browser or application behavior. Clock skew between clients, services, and dependencies can distort the incident timeline, so timestamps should be synchronized and correlation should not rely on time alone. Retaining more detailed telemetry helps later investigation but increases storage cost. Sensitive payloads, credentials, tokens, and personal data must be redacted or excluded.

For alerting, I would use customer-symptom alerts based on the SLIs and SLOs above. Each alert should have an owner, severity, affected Region and payment method, runbook context, and noise controls such as a minimum traffic level and a sustained evaluation window. I would test the dashboards and alerts with known failure scenarios or synthetic payment checks and confirm that a real payment-path problem changes the business SLIs even when CPU, memory, and Pod health remain normal.

Technical Approach

1) Confirm the customer-visible symptom and preserve the incident timeline. 2) Slice the funnel by Region, payment method, application version, response code, and latency percentile. 3) Build healthy comparison cohorts from the same time window. 4) Correlate client events, API logs, traces, dependency calls, authorization outcomes, retries, and business metrics with consistent identifiers and attributes. 5) Test client, API, dependency, authorization, configuration, and data hypotheses; reject those contradicted by evidence. 6) Confirm the failing boundary and apply the smallest safe correction, containment, or rollback. 7) Verify funnel, authorization, order-completion, response-code, and latency recovery, then monitor for regression.

Practical Insights

The main cost is observability data, not algorithm speed. More detailed logs, traces, and dimensions make diagnosis easier but increase ingestion, storage, query, and retention costs. High-cardinality labels such as unique users or sessions can make metric systems expensive, so they should be controlled and used mainly where appropriate for logs or traces. Sampling reduces trace cost but may hide rare failures. More dashboards and alerts also require maintenance, testing, ownership, and tuning so that operators are not overwhelmed by noise.

Why Interviewers Ask This

Interviewers want to see whether you diagnose a customer-impacting problem with evidence instead of trusting green infrastructure dashboards or guessing. They are testing whether you can preserve the timeline, define useful comparison cohorts, correlate several observability signals, distinguish infrastructure health from business success, reject unsupported hypotheses, identify the failing boundary, and choose a safe correction.

Common interview mistakes

Common mistakes are treating green CPU, memory, and Pod dashboards as proof that checkout is healthy; changing code before preserving evidence; looking only at infrastructure instead of the user funnel; failing to compare with a healthy cohort; aggregating away Region or payment method; treating one trace or log as proof of root cause; ignoring client events, authorization outcomes, retries, or business success metrics; using uncontrolled high-cardinality metric labels; overlooking sampling bias or clock skew; and verifying only infrastructure after the change instead of confirming customer and business recovery.

Interview tip

Explain the sequence in order: preserve, slice, compare, correlate, test, confirm, fix, verify. State explicitly that green infrastructure narrows the fault boundary but does not prove payment success. That distinction is the key judgment this question is testing.

Interviewer may ask next
What would you do if client-side telemetry for the payment flow is missing or incomplete?

I would not assume the client is healthy. I would continue with the evidence I still have: funnel drop points, API logs, traces, dependency calls, authorization outcomes, retries, application-version data, and business success metrics. I would compare the affected cohort with healthy cohorts to narrow the boundary. I would also record missing client visibility as an observability gap and add privacy-safe client instrumentation or synthetic payment checks for future incidents. The missing signal reduces confidence, but it does not prevent an evidence-based server, dependency, or business-side investigation.

How would you alert on this issue without creating noisy alerts for low-traffic payment methods?

I would first define payment-authorization and order-completion SLIs by Region and payment method, then set an SLO or justified healthy baseline. The alert should require meaningful traffic volume plus a sustained degradation, so a few failures in a low-volume cohort do not page an operator. I would include ownership, severity, affected dimensions, and a runbook link. I would also use business-success and dependency evidence together because infrastructure-only alerts can stay green during this incident. Synthetic payment checks can provide an additional signal when real traffic is too sparse.

13. Write a Bash script that lists EC2 instances not using the approved AMI in every enabled Region.Automation And ScriptingHardAmazon

Question Details

Create executable /home/interview/find_outdated_amis.sh APPROVED_JSON. The JSON file maps each enabled AWS Region to one approved AMI ID, for example {"us-east-1":"ami-aaa","us-west-2":"ami-bbb"}; keys and values must be non-empty strings. Use the default AWS credential chain to obtain the account's enabled Regions, reject the input with exit 2 when any enabled Region lacks a mapping, then query every enabled Region and list non-terminated instances whose ImageId differs from that Region's approved value. Print tab-separated region<TAB>instance_id<TAB>current_ami<TAB>approved_ami, sorted by Region and instance ID. Paginate all responses, do not modify instances, use finite AWS CLI connect and read timeouts, and make at most three attempts for retryable calls. Invalid JSON or arguments exits 2 before instance queries; an unrecoverable Region failure is logged, other Regions continue, and final status is 1; full success logs Region, instance, and mismatch counts to stderr and exits 0. The operation is read-only and idempotent for an unchanged account state. Example mapping us-east-1=ami-new with running i-1=ami-old and i-2=ami-new must print only us-east-1 i-1 ami-old ami-new using tabs.

Short Interview Answer (30-60 seconds)

I would validate the APPROVED_JSON file first, then use the default AWS credential chain to discover every enabled Region. Before querying any instances, I would verify that every enabled Region has one non-empty approved AMI. Then I would query each Region with pagination, finite timeouts, and at most three total attempts for retryable AWS calls. I would collect non-terminated instances using the wrong AMI, sort them by Region and instance ID, print TSV output, and return exit 0, 1, or 2.

Detailed Explanation

See the Code while reading this explanation.

The script receives one JSON file that maps each enabled AWS Region to its approved AMI. It first checks the argument and the JSON file. Next, it asks AWS which Regions are enabled. Before looking at any EC2 instances, it verifies that every enabled Region has a non-empty AMI mapping. Then it checks every instance except terminated instances. It records only instances whose current AMI differs from the approved AMI. The script is read-only. It prints deterministic tab-separated output and handles failures without stopping healthy Regions.

Useful Questions to Ask the Interviewer
  1. Should a missing AMI mapping for any enabled Region stop the script before all instance queries? Yes. The required behavior is exit 2 before any DescribeInstances call.
  2. Should stopped and shutting-down instances also be checked? Yes. Every state except terminated is included.
  3. Should one failed Region stop processing the remaining Regions? No. The failure should be logged, the other Regions should continue, and the final status should be 1.
Write a Bash script that lists EC2 instances not using the approved AMI in every enabled Region. diagram
How to Explain It in an Interview
1. Validate the argument and JSON

The program requires exactly one argument. That argument is the APPROVED_JSON file path. The file must be readable. Its top-level value must be a JSON object. Every Region key and every AMI value must be a non-empty string. If these checks fail, the script writes an error to stderr and exits with status 2. No instance query has happened yet.

2. Discover all enabled Regions

The script calls EC2 DescribeRegions using the normal AWS default credential chain. It keeps Regions whose OptInStatus is opt-in-not-required or opted-in. The AWS CLI call uses finite connect and read timeouts. AWS standard retry behavior is limited to three total attempts. If Region discovery cannot succeed, the script logs the failure and exits with status 1 because this is an AWS operational failure rather than invalid input.

3. Validate the complete Region-to-AMI mapping

After Region discovery succeeds, the script checks every enabled Region against APPROVED_JSON. This happens before the first DescribeInstances call. If any enabled Region is missing or maps to an empty value, the script logs the configuration problem and exits with status 2. The key invariant is simple: instance scanning starts only after every enabled Region has a valid approved AMI.

4. Query and compare instances in each Region

For each enabled Region, the script reads that Region's approved AMI and calls DescribeInstances. AWS CLI pagination remains enabled, so all pages are processed. Each returned instance provides InstanceId, ImageId, and State. The script ignores only instances whose state is terminated. Pending, running, shutting-down, stopping, and stopped instances are eligible. If current ImageId is different from the approved AMI, the script records region, instance ID, current AMI, and approved AMI.

5. Isolate Region failures

A non-retryable DescribeInstances failure makes that Region fail immediately. A retryable failure can be retried by the AWS CLI, but there are at most three total attempts. If a Region still cannot be queried, the program writes the error to stderr, increments its Region-failure count, and continues with the remaining Regions. This preserves useful results from healthy Regions. At the end, any such Region failure makes the final exit status 1.

6. Walk through the verified example

APPROVED_JSON contains {"us-east-1":"ami-new"}. In us-east-1, running instance i-1 uses ami-old and running instance i-2 uses ami-new. Both instances are eligible because neither is terminated. For i-1, ami-old differs from ami-new, so the script records a mismatch. For i-2, the values are equal, so it records nothing. The only stdout record is the four tab-separated fields us-east-1, i-1, ami-old, and ami-new.

7. Sort, report counts, and return the final status

After the Region loop, the script sorts mismatch records first by Region and then by instance ID. It prints region, instance_id, current_ami, and approved_ami as tab-separated fields. It logs Region count, scanned instance count, and mismatch count to stderr. With no operational Region failures it exits

  1. If at least one Region failed, it exits
  2. Invalid arguments, invalid JSON, or an incomplete Region mapping use exit 2 before instance queries.
Key Insight / Why This Solution Works

The main idea is to separate configuration validation from EC2 scanning. The central invariant is that no DescribeInstances call begins until every enabled Region has one non-empty approved AMI. Once that invariant is true, each Region can be processed independently. The script compares every non-terminated instance ImageId with the approved AMI for that Region and stores only mismatches. AWS failures are isolated per Region so healthy Regions still produce results. Finally, sorting by Region and instance ID gives deterministic output. All AWS operations are reads, so an unchanged account produces the same result without modifying resources.

Example

The Bash program first validates that exactly one APPROVED_JSON file was supplied. jq confirms that the file contains a JSON object and that every key and value is a non-empty string. A small AWS wrapper applies finite connect and read timeouts and configures the AWS CLI standard retry mode for at most three total attempts. DescribeRegions discovers the enabled Regions through the default credential chain. The program then validates every enabled Region mapping before it makes any DescribeInstances call. During the Region loop, DescribeInstances automatically paginates all results. jq produces InstanceId, ImageId, and State. The loop skips only terminated instances, counts the other instances, and appends ImageId mismatches to a temporary TSV file. If one Region cannot be queried, the script logs that failure and continues. At the end, sort orders the mismatch rows by Region and instance ID. The script prints them to stdout, writes counts to stderr, exits 1 after any Region failure, otherwise exits 0. Invalid input exits 2 before instance queries.

Code
#!/usr/bin/env bash
set -u

readonly EXIT_SUCCESS=0 EXIT_PARTIAL=1 EXIT_INPUT=2
readonly CONNECT_TIMEOUT=5 READ_TIMEOUT=20 MAX_ATTEMPTS=3

if (($# != 1)); then
  printf 'ERROR: usage: %s APPROVED_JSON\n' "$0" >&2
  exit "$EXIT_INPUT"
fi
approved_json=$1
if [[ ! -f $approved_json || ! -r $approved_json ]]; then
  printf 'ERROR: APPROVED_JSON must be a readable file\n' >&2
  exit "$EXIT_INPUT"
fi
for required_command in aws jq sort mktemp; do
  if ! command -v "$required_command" > /dev/null 2>&1; then
    printf 'ERROR: required command %s is unavailable\n' "$required_command" >&2
    exit "$EXIT_INPUT"
  fi
done
if ! jq -e 'type == "object" and all(to_entries[]; (.key | type == "string" and length > 0) and (.value | type == "string" and length > 0))' "$approved_json" > /dev/null 2>&1; then
  printf 'ERROR: JSON must be an object with non-empty string keys and values\n' >&2
  exit "$EXIT_INPUT"
fi

work_dir=$(mktemp -d) || exit "$EXIT_PARTIAL"
cleanup() { rm -rf -- "$work_dir"; }
trap cleanup EXIT
trap 'exit 1' HUP INT TERM
regions_file="$work_dir/regions"
regions_json="$work_dir/regions.json"
regions_unsorted="$work_dir/regions.unsorted"
mismatches_file="$work_dir/mismatches"
: > "$mismatches_file"

aws_read() {
  AWS_RETRY_MODE=standard AWS_MAX_ATTEMPTS=$MAX_ATTEMPTS aws "$@" \
    --cli-connect-timeout "$CONNECT_TIMEOUT" \
    --cli-read-timeout "$READ_TIMEOUT"
}

if ! aws_read ec2 describe-regions --all-regions --output json \
  > "$regions_json" 2> "$work_dir/regions.err"; then
  printf 'ERROR: failed to get enabled Regions\n' >&2
  command cat "$work_dir/regions.err" >&2
  exit "$EXIT_PARTIAL"
fi
if ! jq -r '.Regions[] | select(.OptInStatus == "opt-in-not-required" or .OptInStatus == "opted-in") | .RegionName' \
  "$regions_json" > "$regions_unsorted"; then
  printf 'ERROR: enabled Region response was invalid\n' >&2
  exit "$EXIT_PARTIAL"
fi
if ! LC_ALL=C sort -u "$regions_unsorted" > "$regions_file"; then
  printf 'ERROR: enabled Regions could not be sorted\n' >&2
  exit "$EXIT_PARTIAL"
fi

while IFS= read -r region; do
  if ! jq -e --arg region "$region" 'has($region) and (.[$region] | type == "string" and length > 0)' "$approved_json" > /dev/null; then
    printf 'ERROR: enabled Region %s has no non-empty approved AMI mapping\n' "$region" >&2
    exit "$EXIT_INPUT"
  fi
done < "$regions_file"

region_count=$(wc -l < "$regions_file")
instance_count=0
region_failures=0
while IFS= read -r region; do
  approved_ami=$(jq -r --arg region "$region" '.[$region]' "$approved_json")
  region_json="$work_dir/$region.json"
  if ! aws_read ec2 describe-instances --region "$region" \
    --query 'Reservations[].Instances[].{InstanceId:InstanceId,ImageId:ImageId,State:State.Name}' \
    --output json > "$region_json" 2> "$work_dir/$region.err"; then
    printf 'ERROR: Region %s could not be scanned\n' "$region" >&2
    command cat "$work_dir/$region.err" >&2
    ((region_failures += 1))
    continue
  fi
  if ! jq -e 'type == "array"' "$region_json" > /dev/null 2>&1; then
    printf 'ERROR: Region %s returned invalid JSON from AWS CLI\n' "$region" >&2
    ((region_failures += 1))
    continue
  fi
  current_count=$(jq '[.[] | select(.InstanceId != null and .State != "terminated")] | length' "$region_json")
  ((instance_count += current_count))
  region_mismatches="$work_dir/$region.mismatches"
  if ! jq -r --arg region "$region" --arg approved "$approved_ami" '
    .[] | select(.InstanceId != null and .State != "terminated")
    | select((.ImageId // "") != $approved)
    | [$region, .InstanceId, (.ImageId // ""), $approved] | @tsv
  ' "$region_json" > "$region_mismatches"; then
    printf 'ERROR: Region %s response could not be processed\n' "$region" >&2
    ((region_failures += 1))
    continue
  fi
  if ! command cat "$region_mismatches" >> "$mismatches_file"; then
    printf 'ERROR: mismatch results could not be stored\n' >&2
    exit "$EXIT_PARTIAL"
  fi
done < "$regions_file"

mismatch_count=$(wc -l < "$mismatches_file")
if ! LC_ALL=C sort -t "$(printf '\t')" -k1,1 -k2,2 "$mismatches_file"; then
  printf 'ERROR: mismatch results could not be sorted\n' >&2
  exit "$EXIT_PARTIAL"
fi
printf 'REGION COUNT=%d INSTANCE COUNT=%d MISMATCH COUNT=%d\n' \
  "$region_count" "$instance_count" "$mismatch_count" >&2
if ((region_failures > 0)); then
  exit "$EXIT_PARTIAL"
fi
exit "$EXIT_SUCCESS"
Where it is used

This pattern is useful for cloud compliance scans, AMI governance, patch-baseline reporting, migration checks, security audits, and inventory automation. The same structure works whenever each Region or environment has an approved configuration value and the goal is to report resources that do not match it without modifying those resources.

Why Interviewers Ask This

This problem checks whether you can write production-style cloud automation instead of only a happy-path shell loop. The interviewer is evaluating input validation, AWS credential handling, pagination, bounded retries, finite network timeouts, failure isolation, deterministic output, shell correctness, and safe read-only behavior. It also tests whether you distinguish configuration errors from AWS runtime failures and whether useful results from healthy Regions survive when another Region cannot be scanned.

Common interview mistakes

A common mistake is starting DescribeInstances before proving that every enabled Region has a valid approved AMI. That breaks the required exit-2 behavior. Another mistake is filtering only running instances instead of checking every state except terminated. Candidates may also disable pagination, forget finite AWS CLI timeouts, or allow more than three total attempts. A Region failure should not stop healthy Regions. Other common errors are mixing operational failures with invalid-input exit 2, printing unsorted rows, or using spaces instead of the required four tab-separated fields.

Interview tip

Explain the pre-flight safety rule first: discover enabled Regions and validate the complete Region-to-AMI mapping before any DescribeInstances call. Then explain the read-only per-Region scan, bounded AWS retries, failure isolation, and final deterministic TSV sort.

Interviewer may ask next
How would you change the script for an account with a very large number of instances?

I would keep the same validation, retry, comparison, and exit-code rules. I would process instance pages incrementally instead of storing a full Region response when memory or temporary storage becomes important. Mismatch rows could be written directly to a temporary file and externally sorted at the end. The comparison work remains O(R + N), and sorting M mismatches remains O(M log M). Working memory can approach the current page size, while temporary disk usage grows with the mismatch data. The tradeoff is more pagination and streaming code.

What would change if the script were allowed to remediate outdated AMIs automatically?

I would keep discovery and reporting as a separate read-only phase. Remediation would be an explicit second phase with approvals, rollout controls, health checks, and rollback handling. An EC2 instance's ImageId is not changed in place, so remediation normally means replacing or relaunching the workload from the approved AMI through the application's deployment mechanism. The scan complexity remains based on Regions and instances. Remediation cost depends on the number of mismatches. The main tradeoff is much greater operational risk compared with the current idempotent read-only report.

14. Tell me about a time you showed leadership in a project.BehavioralEasyAmazon

Question Details

Use a real project in which your influence mattered beyond completing your assigned tasks. Explain the goal, your formal role, the point at which leadership was needed, the decision or action you took, how you aligned or supported other people, the obstacles you handled, the outcome, and what you learned about your leadership approach.

Interview tip:

Use STAR to structure your answer: briefly explain the Situation and Task, make Action the most detailed part, and finish with the Result. For example, describe a project where your influence went beyond your assigned work, leadership was needed to keep delivery moving, you aligned people around a clear plan, removed obstacles, supported teammates, made practical decisions, and helped the team reach a reliable outcome.

Situation

In my last role, I worked on a project to improve how our team deployed an important application. The existing release process involved several manual steps, and different teams handled parts of the process in different ways. This created confusion during releases and made it harder to understand who should act when something went wrong. I was a DevOps Engineer on the project, but I did not have formal management authority over the other engineers involved.

Task

My main responsibility was to improve the deployment automation, but I saw that automation alone would not solve the larger problem. The project needed someone to bring the application, platform, and operations teams together around one clear release process. I took responsibility for helping the group agree on priorities, define ownership, and move the project forward without waiting for a manager to direct every decision.

Action

I first spoke with engineers from each team to understand their concerns and the parts of the release process they owned. I then mapped the full deployment flow and showed where manual approvals, unclear ownership, and inconsistent steps were creating risk. Instead of trying to redesign everything at once, I proposed that we first standardize the most important release path and automate the repeated steps that were causing the most confusion. I explained why this smaller first step would give us a safer way to improve the process while still making progress. I organized short working sessions where we agreed on responsibilities, rollback steps, and the checks that had to pass before a release could continue. When people had different opinions, I kept the discussion focused on reliability, recovery, and what the team could realistically support. I also created the initial pipeline changes myself, asked teammates to review them, and incorporated their feedback so the process belonged to the whole team instead of only to me. During testing, I stayed closely involved with the application engineers, helped investigate failures, and documented what we learned so others could troubleshoot the pipeline without depending on me. I also kept stakeholders informed about what was complete, what still carried risk, and what decisions we needed from them. That combination of technical work, communication, and shared ownership helped the team keep moving when the project could easily have stalled.

Result

We established a clearer and more consistent deployment process, and releases became easier for the teams to coordinate and support. The team also had better visibility into responsibilities and recovery steps when a deployment problem occurred. I learned that leadership does not always mean having authority or making every decision. In this project, it meant creating clarity, listening to different concerns, making practical decisions, and helping other people succeed while keeping everyone focused on the shared goal.

Why Interviewers Ask This

Interviewers ask this question to understand whether a candidate can influence people, take ownership, and create direction when leadership is needed. A strong answer shows that the candidate can make sound decisions, communicate clearly, support teammates, handle disagreement, and move a project forward even without formal authority.

Interviewer may ask next
How did you handle people who disagreed with your proposed approach?

I asked them to explain the specific risk or concern behind their disagreement instead of treating it as resistance. I then connected the discussion back to our shared goals of reliable releases and simple recovery. In some cases, their feedback changed parts of my proposal. Keeping the discussion focused on the problem rather than on who had the better idea helped us reach decisions that the whole team could support.

What would you do differently if you led a similar project again?

I would define shared ownership and decision responsibilities even earlier. We eventually created that clarity, but doing it at the start would have reduced some early confusion. I would still use the same approach of listening first, improving the most important path before expanding the scope, and making sure the team understands both the technical changes and the reasons behind them.

Disclaimer: This interview guide is for educational and informational purposes only. It is designed to help readers prepare, but it does not guarantee any interview result, hiring decision, offer, or outcome. Interview questions, hiring criteria, and preferred answers can vary by employer, interviewer, industry, location, and time. The examples and explanations reflect the authors' research and judgment, are provided without warranties of any kind, and should not be treated as the only correct approach. Diagrams are simplified illustrations intended to highlight the main components and their interactions; actual systems and implementations may be more complex. Alternative approaches may be equally valid or better suited to a particular question, context, or interviewer. To the fullest extent permitted by applicable law, the author, contributors, and publisher are not liable for decisions made, actions taken, or losses incurred based on this guide.

Company Notice: This guide is an independent educational resource and is not affiliated with, endorsed by, sponsored by, or approved by the company named in this guide. Company names are used only to identify interview experiences commonly reported by candidates. Interview practices can change without notice, and inclusion of company-specific content does not mean these questions are official, complete, or guaranteed to be asked. To the fullest extent permitted by law, the author, contributors, and publisher are not responsible for outcomes related to use of this material.

Content Accuracy and Verification: To the fullest extent permitted by applicable law, we do not represent or warrant that interview guides, questions, answers, examples, or diagrams are accurate, complete, current, error-free, or suitable for any particular purpose. You are responsible for independently reviewing and verifying the information before relying on it.