Amazon Web Services free practice

Free DOP-C02 practice questions

18 real DOP-C02 sample questions, each with a worked explanation and a rationale for every option, right and wrong. No account, no card. This is the reasoning the DOP-C02 tests: knowing why the tempting answer is wrong, not just spotting the right one.

The real DOP-C02 is 75 questions in 180 minutes, pass mark 750 / 1000. For a domain-by-domain breakdown and a study plan, read the DOP-C02 study guide. The full bank has 288 questions.

SDLC Automation (22% of the exam)

Free sampleSDLC Automationmedium

A company runs its AWS CodePipeline in a shared tooling account but deploys the built artifacts into a separate production account using a CloudFormation deploy action. The pipeline currently fails at the deploy stage with an access denied error, even though a cross-account IAM role exists in the production account. The team encrypts the pipeline artifact store with a customer managed AWS KMS key. They want the most reliable way to let the production-account role read the artifacts and deploy them. Which change resolves the failure while keeping access scoped?

  • AGrant the production-account deploy role permission to use the customer managed KMS key in the key policy, and allow the tooling-account pipeline role to assume that role, so the role can decrypt and read the artifacts. Correct
  • BReplace the customer managed KMS key on the artifact bucket with the default Amazon S3 managed key, because cross-account CodePipeline actions cannot decrypt artifacts protected by a customer managed key under any configuration.
  • CMake the artifact S3 bucket public-read so the production account can fetch the artifacts directly, then attach an administrator policy to the cross-account role so it has enough permissions to deploy.
  • DMove the entire pipeline into the production account so no cross-account artifact access is needed, then have developers push source directly into that account to avoid configuring any assume-role trust.
For cross-account CodePipeline deploys with a customer managed KMS key, the target role needs both assume-role trust and key-usage rights to decrypt artifacts. When a CodePipeline artifact store uses a customer managed AWS KMS key, any cross-account role that reads those artifacts must be listed as a key user in the key policy in addition to having S3 read access and assume-role trust; without the KMS grant the deploy action gets access denied even though the IAM role exists.

Why A is correct: Cross-account actions fail when the deploy role cannot decrypt the artifacts; adding the role as a key user in the KMS key policy plus the assume-role trust lets it read the encrypted artifact and deploy, with access scoped to that one role.

Why B is wrong: Cross-account decryption with a customer managed key is fully supported once the key policy and bucket grants are correct, so downgrading encryption sacrifices control to fix a problem that is really a missing grant.

Why C is wrong: A public bucket and an administrator policy both breach least privilege and expose build output, and neither addresses the KMS decryption grant that is the actual cause of the access denied error.

Why D is wrong: Collapsing accounts removes the separation the company chose and is a large re-architecture, when the failure is simply a missing KMS key grant on the existing cross-account role.

Free sampleSDLC Automationmedium

A team uses AWS CodePipeline to ship a customer-facing service. Builds and automated tests run without human involvement, but the company requires that a release manager sign off in writing before any change reaches the production deploy stage, and the sign-off must be captured as part of the pipeline run. The team wants the most native way to pause the pipeline for that approval and record who approved it, without bolting on an external workflow tool. Which approach meets the requirement?

  • AInsert a Lambda invoke action that emails the release manager and then sleeps in a polling loop until a reply arrives, parsing the inbox to decide whether the pipeline should continue to production.
  • BAdd a manual approval action as a stage gate before the production deploy stage, so the pipeline pauses until an authorised user approves or rejects, and the decision and approver are recorded in the action history. Correct
  • CConfigure the production deploy stage to start only on a schedule during business hours, on the assumption that the release manager will be watching the pipeline whenever a deployment can run.
  • DRequire the release manager to disable the transition into the production stage by default and re-enable it by hand for each release, treating the enable click as the approval record.
Use a CodePipeline manual approval action to pause a pipeline for a recorded human sign-off before a sensitive deploy stage. CodePipeline supports a manual approval action that halts the pipeline until an authorised principal approves or rejects, optionally with a comment and an SNS notification; the approver identity and decision are kept in the action execution history, giving a native, auditable sign-off gate before production.

Why A is wrong: An email-parsing Lambda is a fragile hand-rolled workflow that risks long-running invocations and weak audit trails, which is exactly the external tooling the team wants to avoid when a native approval action exists.

Why B is correct: A CodePipeline manual approval action pauses the pipeline at that point, requires an authorised user to approve or reject with an optional comment, and records the approver and outcome in the run history, which is exactly the native sign-off control the requirement describes.

Why C is wrong: A schedule controls timing but captures no explicit sign-off and does not pause for a decision, so it cannot satisfy a requirement for a recorded written approval before production.

Why D is wrong: Disabling a stage transition stops automatic flow but logs no approver identity or comment, so it provides weaker auditing than a manual approval action and relies on manual toggling for every run.

Free sampleSDLC Automationmedium

A platform team is wiring a new AWS CodePipeline that lives in a shared tooling account and must run an AWS CloudFormation deploy action against resources in a separate production account. The pipeline artifact store is an Amazon S3 bucket in the tooling account encrypted with a customer managed AWS KMS key. No cross-account trust exists yet, and the team wants the deploy action to assume into production with least privilege while still being able to read the encrypted artifacts. Which TWO actions together establish the cross-account deploy correctly? (Select TWO.)

  • ACreate an IAM role in the production account that trusts the tooling account, grant it the deploy permissions, and reference that role as the role for the CloudFormation deploy action in the pipeline. Correct
  • BAdd the production deploy role as a principal in the artifact bucket policy and as a grantee in the customer managed KMS key policy so it can read and decrypt the build artifacts. Correct
  • CEstablish a VPC peering connection between the tooling account VPC and the production account VPC so the deploy action can route to the production resources directly.
  • DMake the artifact Amazon S3 bucket publicly readable and switch the artifact store to an AWS managed key so the production account does not need a key policy entry.
A cross-account CodePipeline deploy needs both a trusted target-account role and bucket plus KMS access for the assumed role to read encrypted artifacts. CodePipeline performs cross-account actions by assuming a role the target account creates and trusts to the pipeline account, and because the artifact store uses a customer managed KMS key, that assumed role must also be granted on the S3 bucket policy and the KMS key policy to read and decrypt the artifact before deploying.

Why A is correct: A cross-account action assumes a role that the target account owns and trusts to the pipeline account, which is the supported way to act on production resources from the tooling pipeline.

Why B is correct: The assumed role must be allowed on both the S3 bucket policy and the KMS key policy, otherwise the deploy action fails to read or decrypt the encrypted artifact even with a valid trust.

Why C is wrong: VPC peering is tempting because it sounds like cross-account connectivity, but CodePipeline cross-account actions use IAM role assumption over AWS APIs, not VPC network routes.

Why D is wrong: A public bucket is an obvious security failure, and an AWS managed key cannot have its key policy edited for cross-account use, so neither part solves the scoped access requirement.

Configuration Management and Infrastructure as Code (17% of the exam)

Free sampleConfiguration Management and Infrastructure as Codemedium

A platform team manages a production VPC stack with "AWS CloudFormation". The stack contains a hand-tuned security group whose rules must never be altered or deleted by a routine template update, while the rest of the stack should still accept ordinary changes through the pipeline. The team wants a guardrail that lives with the stack itself rather than relying on reviewers to spot risky diffs. Which approach BEST protects that one resource while leaving the remainder of the stack updatable?

  • AAdd a "DeletionPolicy" of "Retain" to the security group so that the resource is preserved whenever the production stack is updated by the pipeline.
  • BAttach a stack policy that denies "Update:Modify" and "Update:Delete" on the security group logical ID while allowing updates to all other resources. Correct
  • CEnable termination protection on the stack so that no resource inside it can be changed during a pipeline-driven update.
  • DMove the security group into a separate nested stack and mark that nested stack resource with "Update:Replace" denied in the parent.
Use a stack policy to deny update actions on a specific logical resource while leaving the rest of the stack updatable. Stack policies are JSON documents evaluated by CloudFormation on every update; an explicit Deny on Update:Modify and Update:Delete scoped to one logical ID stops that resource from being changed while Allow statements keep the remaining resources updatable, which is exactly the in-stack guardrail required.

Why A is wrong: "DeletionPolicy" only controls what happens when a resource is removed from the template or the stack is deleted; it does not block in-place modification, so it fails the no-alteration requirement here.

Why B is correct: A stack policy is evaluated during every stack update and can deny modify and delete on a specific logical ID while permitting changes elsewhere, giving an in-stack guardrail that needs no human review.

Why C is wrong: Termination protection only blocks deletion of the whole stack; it is tempting as a safety switch but does nothing to prevent updates to an individual resource during a normal update.

Why D is wrong: Splitting the resource out adds structure but still permits modification, and a deny on replace alone does not stop modify or delete, so the protected rule could still be altered.

Free sampleConfiguration Management and Infrastructure as Codemedium

An engineer must apply a template change to a busy production database stack managed by "AWS CloudFormation". Leadership requires sign-off on exactly which resources will be added, modified or replaced before anything happens, because an unintended replacement of the database would cause downtime. The engineer wants the deployment pipeline to surface that impact for review and only proceed once approved. Which mechanism MOST directly provides this preview-then-approve workflow?

  • ARun "cfn-lint" against the template in the pipeline so that static validation reports any resource that would be replaced before the update is applied.
  • BEnable drift detection on the stack before the update so that the pipeline reports differences between the template and the deployed resources for review.
  • CCreate a change set for the update, have the pipeline pause for approval after the change set lists the affected resources, then execute the change set once approved. Correct
  • DDeploy the change directly with a stack policy that denies replacement on the database, relying on the failed update to reveal whether a replacement was attempted.
Use a CloudFormation change set to preview the resource-level impact of an update and gate execution behind manual approval. A change set is a description of the changes CloudFormation would make, including which resources are added, modified or replaced, computed without touching the live stack; pausing the pipeline between change set creation and execution gives reviewers the exact impact and a controlled approval gate.

Why A is wrong: Linting catches template syntax and best-practice issues but cannot compute the live resource-level difference against the deployed stack, so it cannot tell reviewers which resources will be replaced.

Why B is wrong: Drift detection compares deployed resources to the last known template, not a proposed new template, so it shows existing drift rather than the impact of the pending update.

Why C is correct: A change set computes the exact resource-level diff including replacements before any change is applied, and execution is a separate step, which is precisely the preview-then-approve flow leadership requires.

Why D is wrong: A stack policy can block a replacement but only at apply time as a failure, which gives no advance preview for human sign-off and risks a disruptive rolled-back update.

Free sampleConfiguration Management and Infrastructure as Codemedium

A large "AWS CloudFormation" template has grown past 600 resources and repeatedly fails to update because it exceeds template and resource limits, and several teams need to own discrete layers such as networking, security and application tiers independently. The platform team wants reusable, versioned building blocks that a single parent template can compose and update together as one deployment. Which design BEST meets these goals?

  • ASplit the layers into separate independent stacks and wire them together at deploy time using exported output values consumed through "Fn::ImportValue".
  • BConvert the template into a "StackSet" and deploy each layer as a separate stack instance across the target account so the resource count per stack drops.
  • CPublish each layer as a product in "AWS Service Catalog" and let teams launch the products on demand to assemble the overall environment.
  • DRefactor the layers into nested stacks referenced by "AWS::CloudFormation::Stack" resources in a parent template, with child templates stored in "Amazon S3". Correct
Use nested stacks to decompose a large template into reusable child templates composed and deployed by one parent stack. Nested stacks are created by declaring AWS::CloudFormation::Stack resources whose TemplateURL points at child templates in Amazon S3; the parent treats each child as a single resource, so layers can be owned and versioned separately yet provisioned and updated together, while staying under per-template resource limits.

Why A is wrong: Cross-stack exports do decouple layers, but exported values become locked and hard to change, and the stacks are deployed separately rather than as one composed unit, missing the single-deployment requirement.

Why B is wrong: StackSets replicate a stack across many accounts or Regions; they solve multi-account roll-out, not composing layered building blocks into one parent deployment in a single account.

Why C is wrong: Service Catalog governs self-service provisioning of approved products, which is tempting for team ownership but does not give a parent template that composes and updates the layers as one coordinated deployment.

Why D is correct: Nested stacks let a parent template compose versioned child templates as reusable building blocks and update them as one deployment, which addresses both the size limits and independent layer ownership.

Security and Compliance (17% of the exam)

Free sampleSecurity and Compliancehard

A company manages around 300 accounts in AWS Organizations grouped into organisational units by environment. Security needs a hard guarantee that no principal in any production account, including account administrators with broad IAM policies, can disable AWS CloudTrail or delete its trails. A previous attempt that relied on attaching an IAM deny policy in each account was bypassed when a team detached the policy. The team wants the most durable control that cannot be removed by account-level administrators. Which approach should they implement?

  • AAttach a permission boundary to every IAM role in the production accounts that omits the CloudTrail stop and delete actions, so the boundary caps what those roles can do regardless of their attached policies.
  • BDistribute an AWS Config rule to the production accounts that detects when a trail is stopped or deleted and triggers a remediation that recreates it, treating detection and repair as the enforcement mechanism for the requirement.
  • CMove all production accounts under a dedicated organisational unit and apply an IAM identity-based deny policy through AWS IAM Identity Center permission sets so every assigned user inherits the CloudTrail restriction centrally.
  • DAttach a service control policy to the production organisational unit that denies cloudtrail:StopLogging and cloudtrail:DeleteTrail, so the guardrail applies to every principal in those accounts and cannot be overridden locally. Correct
Use a service control policy on an organisational unit to set a preventive permission ceiling that even account administrators cannot override. Service control policies define the maximum permissions available to principals in the member accounts they target and are administered only from the AWS Organizations management account; denying cloudtrail:StopLogging and cloudtrail:DeleteTrail at the organisational unit means no principal in those accounts, including an account administrator, can perform those actions, which is a preventive guarantee that local IAM policies, permission boundaries, or detective controls cannot match.

Why A is wrong: A permission boundary caps a principal's effective permissions, but it is set within the account and an account administrator can change or remove it, so it does not survive a local admin acting against the control the way an organisation guardrail does.

Why B is wrong: Config with remediation detects and repairs after the fact rather than preventing the action, so there is a window where logging is off, and an account admin can disable the rule, which falls short of a hard preventive guarantee.

Why C is wrong: Identity Center permission sets only constrain principals that sign in through Identity Center, so roles, account root, and locally created users are unaffected, which leaves the very administrators the requirement targets able to stop or delete the trails.

Why D is correct: A service control policy sets the maximum available permissions for every principal in the targeted accounts including account administrators, and it is managed only from the organisation management account, so denying the CloudTrail stop and delete actions there is a preventive guardrail that local admins cannot remove.

Free sampleSecurity and Compliancehard

A platform team lets application developers create their own IAM roles for Lambda functions through a self-service pipeline. Security requires that no developer-created role can ever grant access outside an approved set of services or escalate its own privileges by attaching administrator policies, yet developers must stay free to add whatever scoped permissions their function needs within that envelope. The team wants the control to travel with each role at creation time and to apply automatically without security reviewing each policy. Which mechanism best enforces this?

  • ARequire the pipeline to attach a permission boundary to every developer-created role that allows only the approved services and denies iam:Attach and iam:Put actions, so the boundary caps each role's effective permissions whatever policies developers add. Correct
  • BAttach a service control policy to the developers' account that lists the approved services, relying on the organisation guardrail alone to constrain each role so no per-role control needs to travel with the role itself.
  • CHave security review and approve every IAM policy a developer attaches to a role before the pipeline applies it, so a human confirms each grant stays inside the approved services and contains no escalation paths.
  • DConfigure an AWS Config rule that flags any developer role whose policies reference services outside the approved set, then notify security so the offending policy can be detached after the role is in use.
Attach an IAM permission boundary at role creation to cap delegated roles' effective permissions while leaving holders free to add scoped policies. A permission boundary is a managed policy that defines the maximum permissions an identity-based policy can grant to a principal; the effective permissions are the intersection of the boundary and the attached policies. Attaching a boundary that allows only approved services and denies the IAM attach and put actions means developers can add their own narrow policies, yet no developer-created role can reach unapproved services or escalate by attaching an administrator policy, all enforced automatically per role at creation.

Why A is correct: A permission boundary is an advanced policy that sets the maximum permissions an identity-based policy can grant, so attaching one at role creation lets developers add their own scoped policies while the effective permissions can never exceed the approved services or include the privilege-escalation actions the boundary denies.

Why B is wrong: A service control policy caps the whole account uniformly and cannot vary per role, so it cannot let the platform team's own roles keep broad access while constraining only developer-created roles, and it does not block a developer attaching an admin policy within the account's allowed services.

Why C is wrong: A manual review on every policy is exactly the per-policy approval the team wants to avoid, it scales poorly across many developers, and it adds latency without giving the automatic at-creation control the requirement describes.

Why D is wrong: Config detection runs after a role already exists and can act, so it neither prevents an over-broad grant at creation nor stops privilege escalation in the interval before remediation, which fails the requirement for a control that travels with the role from the start.

Free sampleSecurity and Compliancehard

A central security tooling account runs an automated remediation service that must read configuration and apply fixes in roughly 200 member accounts across AWS Organizations. The team must avoid storing any long-lived credentials, must scope what the tooling can do in each member account, and wants to add new accounts to the programme without redeploying the tooling. They also need every action the tooling takes in a member account to appear in that account's own audit logs. Which design meets these requirements with the least ongoing credential management?

  • ACreate one IAM user with programmatic access keys in each member account, share the keys with the tooling account through AWS Secrets Manager, and have the tooling rotate and retrieve a key per account when it needs to act.
  • BDeploy a scoped IAM role in every member account that trusts the tooling account, and have the tooling call AWS STS AssumeRole to obtain short-lived credentials for each target account before it reads and remediates. Correct
  • CConfigure the tooling's execution role with a resource-based policy on each member account's resources granting cross-account access directly, so the tooling acts on remote resources without assuming any role in the member accounts.
  • DUse AWS IAM Identity Center to assign the tooling a permission set in every member account, then have the tooling sign in through Identity Center to obtain a session in each account before it remediates.
For unattended cross-account automation, assume a scoped IAM role per account with STS for short-lived credentials and per-account audit attribution. Deploying a permissions-scoped IAM role in each member account whose trust policy names the central tooling account lets the tooling call sts:AssumeRole to receive temporary, automatically expiring credentials before acting; no long-lived keys are stored, the role's policy limits what the tooling can do, and because the calls run as a role within the member account they appear in that account's CloudTrail. New accounts onboard by provisioning the same role, commonly via a CloudFormation StackSet, with no redeployment of the tooling itself.

Why A is wrong: Long-lived IAM user access keys are exactly what the requirement forbids, and managing, rotating, and securely distributing a key per account across 200 accounts is heavy credential management that role assumption is designed to remove.

Why B is correct: A cross-account role with a trust policy naming the tooling account lets the tooling call AssumeRole for temporary credentials scoped by the role's permissions, stores no long-lived secrets, and runs the API calls as a principal in the member account so they land in that account's own CloudTrail; new accounts join by deploying the same role, for example through a StackSet, with no change to the tooling.

Why C is wrong: Resource-based cross-account grants do not exist for most services a remediation tool touches, the calls would be attributed to the tooling account rather than the member account's own logs, and maintaining per-resource policies everywhere is far more work than one assumable role per account.

Why D is wrong: Identity Center is built for human workforce sign-in rather than an unattended service calling APIs, so wiring an automated remediation service through an interactive sign-in flow is the wrong tool and adds operational complexity compared with direct STS role assumption.

Resilient Cloud Solutions (15% of the exam)

Free sampleResilient Cloud Solutionsmedium

A team runs a stateful relational database for a payments service on a single Amazon RDS instance in one Availability Zone. A recent zonal hardware event took the database offline for over an hour, and the business now requires that an Availability Zone failure trigger an automatic failover with no application code changes and minimal recovery time. The team wants the lowest operational overhead while meeting this requirement. Which approach should they choose?

  • ACreate a cross-Region read replica of the RDS instance in a second AWS Region and promote that replica to a standalone primary manually whenever the original Availability Zone becomes unavailable.
  • BSchedule automated RDS snapshots every fifteen minutes and write a runbook so an operator can restore the latest snapshot into a healthy Availability Zone after an outage is detected.
  • CConvert the RDS instance to a Multi-AZ deployment so AWS maintains a synchronous standby in a second Availability Zone and automatically fails over to it when the primary Availability Zone is impaired. Correct
  • DAdd an in-Region RDS read replica in a second Availability Zone and point the application at the replica endpoint so reads continue if the primary Availability Zone fails.
Select RDS Multi-AZ when a single database must survive an Availability Zone failure with automatic failover and no application changes. An RDS Multi-AZ deployment provisions a synchronous standby in a separate Availability Zone and updates the DNS endpoint to the standby automatically when the primary is impaired, so applications reconnect to the same endpoint without code changes and recovery is measured in minutes.

Why A is wrong: A cross-Region read replica protects against Regional loss but promotion is a manual step that adds recovery time, and it addresses a different blast radius than the single-AZ failure the requirement actually targets.

Why B is wrong: Frequent snapshots reduce data loss but restoring one is a manual, slow operation that misses the automatic-failover and minimal-recovery-time requirement, leaving the service down while the restore runs.

Why C is correct: Multi-AZ keeps a synchronous standby in another Availability Zone and performs an automatic DNS-based failover on a zonal fault, meeting the requirement with no code change and the least operational overhead.

Why D is wrong: A read replica serves reads only and cannot accept writes without manual promotion, so a payments database that needs writes after an AZ loss is not protected by this design.

Free sampleResilient Cloud Solutionsmedium

An order-processing web tier runs behind an Application Load Balancer across three Availability Zones in an Amazon EC2 Auto Scaling group. During a deployment, several instances passed the load balancer health check on the TCP port but were returning HTTP 500 errors because a downstream dependency was misconfigured, so the load balancer kept sending them traffic. The team wants the load balancer to stop routing to an instance whenever the application itself reports unhealthy. Which change should they make?

  • AReduce the target group deregistration delay to zero seconds so failing instances are removed from the load balancer immediately once the deployment marks them as outdated.
  • BSwitch the load balancer from an Application Load Balancer to a Network Load Balancer so faster Layer 4 health checks can detect the failing instances and remove them from the target group.
  • CAttach a CloudWatch alarm on the HTTPCode_Target_5XX_Count metric and have it terminate the Auto Scaling group when the error count crosses a threshold during the deployment.
  • DConfigure the target group health check to use the HTTP protocol against an application health endpoint that returns a non-200 status when a downstream dependency is unavailable, so unhealthy targets are removed from rotation. Correct
Use HTTP application-aware Elastic Load Balancing health checks so the load balancer removes targets that fail at the application layer, not just the port. An Application Load Balancer evaluates target health by calling the configured health check path; pointing that check at an HTTP endpoint that reflects downstream dependency state means the application can return a failing status and the load balancer will stop routing to that target until it recovers.

Why A is wrong: Deregistration delay only controls connection draining when a target is deliberately removed; it does nothing to detect an instance that is silently returning errors while still passing the port check.

Why B is wrong: A Network Load Balancer operates at Layer 4 and cannot inspect HTTP status codes, so it would still treat an instance returning 500 errors as healthy as long as the port accepts connections.

Why C is wrong: An aggregate error alarm reacts after the fact and cannot identify which individual targets are unhealthy, and terminating the whole group removes good instances rather than draining the specific failing ones.

Why D is correct: An HTTP health check against a dependency-aware endpoint lets the application signal its true state, so the load balancer drains targets returning errors rather than trusting a shallow port check that ignores application failures.

Free sampleResilient Cloud Solutionsmedium

A company serves a public API from identical Application Load Balancer stacks in two AWS Regions for resilience. They need user traffic to go to the primary Region while it is healthy and to switch to the secondary Region automatically within minutes if the primary stack stops responding, without an operator editing DNS during an incident. Which Amazon Route 53 configuration meets this requirement?

  • ACreate failover records with the primary load balancer as the primary record and the secondary as the secondary, each associated with a Route 53 health check that monitors the regional endpoint. Correct
  • BCreate weighted records that send ninety percent of traffic to the primary load balancer and ten percent to the secondary, then adjust the weights by hand when the primary Region is reported down.
  • CCreate latency-based records for both Regions so Route 53 directs each user to the load balancer that gives them the lowest network latency from their location.
  • DCreate multivalue answer records returning both load balancer addresses with health checks, so resolvers receive up to eight healthy values and pick one at random per query.
Use Route 53 failover routing with health checks for automatic active-passive Regional failover that needs no manual DNS change during an incident. Route 53 failover routing pairs a primary and a secondary record with health checks; while the primary health check passes Route 53 answers with the primary endpoint, and on health check failure it automatically serves the secondary endpoint, achieving hands-off active-passive failover within DNS time-to-live windows.

Why A is correct: Failover routing with health checks keeps answering with the primary record while it is healthy and automatically returns the secondary record when the health check fails, switching traffic with no manual DNS edit.

Why B is wrong: Weighted routing splits traffic by ratio rather than reacting to health, and changing the weights during an incident is the manual operator action the requirement explicitly rules out.

Why C is wrong: Latency-based routing optimises performance, not availability, and without health checks it can keep sending users to a low-latency primary Region even after that stack has failed.

Why D is wrong: Multivalue answer routing returns several healthy endpoints for client-side balancing rather than enforcing a primary-then-secondary order, so it does not give the controlled active-passive failover the company wants.

Monitoring and Logging (15% of the exam)

Free sampleMonitoring and Loggingmedium

A DevOps team runs a fleet of Amazon EC2 instances behind an Auto Scaling group and needs to alarm when an instance is short of available memory or when its root disk passes 85 percent used. The default Amazon EC2 metrics that Amazon CloudWatch publishes do not expose either value, and the team wants these metrics in CloudWatch with the least ongoing maintenance so existing CloudWatch alarms can act on them. Which approach should they implement?

  • AWrite a cron job on each instance that reads memory and disk usage from the operating system and calls the CloudWatch PutMetricData API with custom metric values on a fixed schedule for every host.
  • BInstall the Amazon CloudWatch agent on the instances and bake a unified agent configuration into the launch template so memory and disk metrics are published to CloudWatch as the group scales. Correct
  • CEnable detailed monitoring on the Auto Scaling group so Amazon CloudWatch collects memory and disk metrics from each instance at one-minute resolution without any additional software on the hosts.
  • DEnable AWS Compute Optimizer on the account so it analyses the Auto Scaling group and publishes the memory and disk utilisation of each instance into Amazon CloudWatch for alarming.
Use the Amazon CloudWatch agent to collect guest-level memory and disk metrics that default EC2 metrics never expose. Default Amazon CloudWatch metrics for EC2 come from the hypervisor, which cannot see inside the guest operating system, so memory and disk-usage figures require an in-guest collector. The CloudWatch agent is the managed collector for this, and embedding its configuration in the launch template makes each new instance publish the metrics automatically without bespoke scripts to maintain.

Why A is wrong: A hand-rolled cron and PutMetricData script does surface the values, but it is bespoke code the team must patch, secure, and maintain on every host, which is the high-maintenance path the requirement explicitly rules out.

Why B is correct: The CloudWatch agent is the managed way to collect guest-level memory and disk metrics, and shipping its configuration in the launch template means every scaled instance self-configures with no per-host code to maintain.

Why C is wrong: Detailed monitoring only raises the publishing frequency of the existing hypervisor-level EC2 metrics to one minute; it never adds guest memory or disk-usage metrics, which the hypervisor cannot observe.

Why D is wrong: Compute Optimizer produces right-sizing recommendations from historical data and does not stream live memory or disk metrics into CloudWatch, so no CloudWatch alarm could fire from its output.

Free sampleMonitoring and Loggingmedium

An application writes its logs to Amazon CloudWatch Logs, and each authentication failure produces a log line containing the token "AuthFailure". The security team wants an alarm to notify them through Amazon SNS when more than fifty such lines appear within five minutes, and they want to reuse the log data already in CloudWatch Logs rather than introduce a separate pipeline. What is the most appropriate way to achieve this?

  • AStream the log group to Amazon OpenSearch Service through a subscription filter, then schedule an OpenSearch alert that counts "AuthFailure" documents over five minutes and publishes to the Amazon SNS topic.
  • BRun a CloudWatch Logs Insights query on a five-minute schedule with Amazon EventBridge to count "AuthFailure" entries and invoke a Lambda function that publishes to the Amazon SNS topic when the count is high.
  • CCreate a metric filter on the log group that matches "AuthFailure", emit a custom metric, and attach a CloudWatch alarm that notifies the Amazon SNS topic when the metric exceeds fifty over five minutes. Correct
  • DConfigure a CloudWatch Logs subscription filter that matches "AuthFailure" and delivers each matching event straight to the Amazon SNS topic so the team is notified on every authentication failure.
Convert a recurring log pattern into an alarmable metric with a CloudWatch Logs metric filter rather than a separate analytics pipeline. A metric filter scans incoming log events in a CloudWatch Logs group, and every event matching its pattern increments a CloudWatch metric you define. A CloudWatch alarm can then evaluate that metric against a threshold over a period and trigger an SNS notification, giving threshold-based alerting on log content without provisioning OpenSearch, scheduled queries, or custom code.

Why A is wrong: Streaming to OpenSearch and running an alerting query works, but it stands up and maintains a separate search cluster and pipeline, which is more operational overhead than the in-place CloudWatch capability the requirement points to.

Why B is wrong: A scheduled Insights query plus a Lambda function is plausible, but it adds custom polling and code to maintain when a metric filter and alarm deliver the same alerting natively without writing or operating any function.

Why C is correct: A metric filter turns matching log events into a CloudWatch metric directly inside CloudWatch Logs, and a standard alarm on that metric with an SNS action meets the threshold requirement with no extra pipeline.

Why D is wrong: Subscription filters cannot target SNS and would page on every single event rather than on a count, so they neither support the destination nor honour the more-than-fifty-in-five-minutes threshold.

Free sampleMonitoring and Loggingmedium

A company runs around forty AWS accounts under AWS Organizations, and each account writes application logs to its own Amazon CloudWatch Logs groups. The platform team needs all of these logs to flow continuously into a single logging account where they are indexed for search, and they want a near real-time, push-based mechanism that scales as new accounts and log groups appear. Which design meets this requirement with the least custom code?

  • ASchedule a Lambda function in every account to call the CloudWatch Logs GetLogEvents API on a timer and write the retrieved events into an Amazon S3 bucket owned by the central logging account.
  • BExport each log group to Amazon S3 with a daily CloudWatch Logs export task in every account and copy the resulting objects into the central logging account for later indexing.
  • CTurn on AWS CloudTrail organisation logging so every account delivers its CloudWatch Logs data to a central trail bucket that the logging account then indexes for full-text search.
  • DCreate CloudWatch Logs subscription filters in each account that send matching events to an Amazon Kinesis Data Streams destination in the central logging account, where a consumer indexes the events for search. Correct
Centralise CloudWatch Logs across many accounts in near real time using cross-account subscription filters to a shared destination. CloudWatch Logs subscription filters deliver matching log events to a configured destination, including an Amazon Kinesis stream owned by another account, as the events arrive. Pointing each account at a destination in the central logging account gives a push-based, continuously scaling aggregation path that needs only filter configuration rather than polling code or batch export jobs.

Why A is wrong: Polling GetLogEvents on a timer is custom code in every account, it lags behind real time, and tracking read positions across many log groups is brittle compared with the push-based subscription mechanism.

Why B is wrong: Log group export tasks are batch operations meant for archival and run on a schedule measured in hours, so they cannot satisfy the stated near real-time, continuous flow requirement.

Why C is wrong: CloudTrail records AWS API activity, not arbitrary application log content in CloudWatch Logs, so it captures the wrong data entirely and would not aggregate the application logs the team needs.

Why D is correct: Subscription filters push log events to a cross-account Kinesis destination in near real time and scale automatically as log groups are added, which is the native, low-code pattern for centralising CloudWatch Logs across accounts.

Incident and Event Response (14% of the exam)

Free sampleIncident and Event Responsemedium

A security team wants every change to an Amazon S3 bucket policy across the account to trigger an automated response. The team has confirmed that AWS CloudTrail management events are delivered to the default event bus. They need an Amazon EventBridge rule that runs only when a PutBucketPolicy API call occurs, and they want the matched event passed to an AWS Lambda function that evaluates the new policy. With the least custom code, how should the rule be built?

  • ACreate an EventBridge rule with an event pattern that matches the aws.s3 event source and the PutBucketPolicy event name, then add the Lambda function as a target so the function receives the matched CloudTrail event directly. Correct
  • BCreate an EventBridge rule with a schedule expression that fires every five minutes and targets a Lambda function that scans CloudTrail logs for any recent PutBucketPolicy call before evaluating the bucket policy.
  • CConfigure an Amazon S3 event notification on each bucket for the s3:ObjectCreated event type and route it to the Lambda function, which then reads the current bucket policy and evaluates it.
  • DCreate an EventBridge rule that matches all events from the aws.s3 source, then have the Lambda target inspect each event and discard anything that is not a PutBucketPolicy call before evaluating the policy.
Match a specific API call with an EventBridge event pattern on source and eventName and pass the matched event straight to a Lambda target. EventBridge evaluates each incoming event against the rule event pattern, so a pattern matching the aws.s3 source and the PutBucketPolicy eventName fires the rule only for that management API call, and a Lambda target receives the full matched CloudTrail event as its input without any polling, scanning, or in-function filtering.

Why A is correct: An event pattern keyed on the source and the specific eventName matches only the PutBucketPolicy call, and naming the function as a target delivers the matched event as the payload, so EventBridge does the filtering and invocation with no extra code.

Why B is wrong: A scheduled rule polling CloudTrail can find the call eventually, but it adds latency and log-scanning code, whereas the requirement is an event-driven match on the API call with the least custom logic.

Why C is wrong: S3 event notifications report object-level activity such as ObjectCreated, not bucket policy changes, so this never fires on PutBucketPolicy and fails to detect the management action in scope.

Why D is wrong: Matching every S3 event then filtering inside the function works but invokes Lambda needlessly on unrelated calls and pushes filtering into code, when an event pattern can match only PutBucketPolicy at the rule.

Free sampleIncident and Event Responsemedium

An EventBridge rule invokes an AWS Lambda function whenever Amazon GuardDuty raises a finding. During an incident the function began failing because a downstream dependency was unavailable, and the team discovered that several finding events were lost with no record of them. They want any event that the target cannot process successfully to be retained for later inspection and reprocessing, configured with the least operational overhead. What should they do?

  • AIncrease the Lambda function timeout and reserved concurrency so the function has more time and capacity to retry the downstream dependency before EventBridge gives up on delivering each finding event.
  • BConfigure a dead-letter queue on the EventBridge rule target so that events EventBridge cannot deliver to the Lambda function after its retry attempts are written to an Amazon SQS queue for later inspection and reprocessing. Correct
  • CAdd an Amazon SNS topic as a second target on the rule so that every finding event is also published to subscribers, giving the team a copy of each event regardless of whether the Lambda target succeeds.
  • DEnable EventBridge archive on the event bus and set a long retention period, then replay the entire archive whenever the team needs to recover events that the Lambda function failed to process.
Attach a dead-letter queue to an EventBridge rule target so events that cannot be delivered after retries are retained in SQS for inspection and reprocessing. EventBridge retries delivery to a target on transient failures, and when those attempts are exhausted it discards the event unless a dead-letter queue is configured on the target; pointing that dead-letter queue at an SQS queue captures every undeliverable event with its metadata so the team can examine the cause and replay the messages once the dependency recovers.

Why A is wrong: More timeout and concurrency may reduce some failures, but it does nothing to retain an event once delivery is finally exhausted, so findings can still be lost without any record for inspection.

Why B is correct: A dead-letter queue on the target captures any event EventBridge fails to deliver after retries, writing it to an SQS queue where the team can inspect and replay it, which is the managed way to stop losing finding events.

Why C is wrong: A parallel SNS target copies every event whether or not Lambda succeeds, but SNS does not retain undelivered messages for replay, so it neither isolates failures nor supports reprocessing the lost events.

Why D is wrong: An archive retains all matched events, not just failures, so recovering only the failed findings means replaying and re-filtering everything, which is far more overhead than a target dead-letter queue.

Free sampleIncident and Event Responsemedium

A platform team operates a central security account and several workload accounts in AWS Organizations. They want EventBridge findings raised in the workload accounts to be processed by a single set of Lambda automations that live only in the security account, while keeping cross-account permissions tightly scoped. Which design routes the events to the central account with the least duplicated infrastructure?

  • ADeploy identical copies of the Lambda automations into every workload account and have each account-local EventBridge rule invoke its own copy, so events are processed inside the account where they originate.
  • BHave each workload account publish its findings to an Amazon SNS topic in the security account, then subscribe the central Lambda automations to that topic so they run whenever a finding is published.
  • CCreate a custom event bus in the security account, grant the workload accounts permission to put events on it through a resource-based policy, and add rules in each workload account that forward matching events to that bus as a target. Correct
  • DConfigure each workload account to write findings to a central Amazon S3 bucket and trigger the security-account Lambda automations from S3 event notifications when new finding objects arrive.
Centralise event processing by forwarding events from workload accounts to a custom event bus in a security account that is authorised through a scoped resource-based policy. EventBridge supports cross-account delivery: a custom event bus in the security account carries a resource-based policy that grants only the named workload accounts permission to put events, and each workload account adds a rule whose target is that bus, so all matching events converge on one bus where central rules and Lambda automations run, removing the need to replicate functions per account.

Why A is wrong: Local copies process events where they arise, but duplicating and maintaining the same automations in every account is exactly the redundant infrastructure the team wants to avoid by centralising in the security account.

Why B is wrong: An SNS fan-out can reach central functions, but it loses the content-based event-pattern matching of EventBridge and forces the automations to parse and route every message themselves, adding filtering logic the bus provides natively.

Why C is correct: A central custom event bus with a scoped resource-based policy lets each workload account forward only matching events cross-account, so a single set of rules and Lambda automations in the security account processes everything without duplicated functions.

Why D is wrong: Staging findings in S3 introduces storage and an extra hop, adds delivery latency, and relies on object notifications rather than EventBridge matching, which is more moving parts than forwarding to a central event bus.

Want the full bank?

288 DOP-C02 questions, every one with a worked explanation and a per-option rationale. No sign-up to start.

Practise DOP-C02 free

Frequently asked questions

Are these DOP-C02 practice questions free?

Yes. Every DOP-C02 question on this page is free to read with no sign-up, and each one carries a worked explanation and a rationale for every option. The full bank of 288 questions is on Examworthy.

Do the questions explain why the wrong answers are wrong?

Yes, and that is the point. Each option, correct or not, has its own rationale, so you learn to rule out the tempting wrong answer, not just recognise the right one. That is the reasoning the DOP-C02 tests.

Are these real DOP-C02 exam questions?

No. These are original, blueprint-aligned practice questions written to the public Amazon Web Services content outline. We never reproduce live exam items. They mirror the format and difficulty of the real exam.

How many questions are on the real DOP-C02?

The DOP-C02 is 75 questions in 180 minutes, with a pass mark of 750 / 1000. For the full domain-by-domain breakdown and a study plan, read the study guide.

Examworthy is not affiliated with or endorsed by Amazon Web Services. All questions are original, blueprint-aligned practice material. We never reproduce live exam items. DOP-C02 and related marks belong to their respective owners.