Jeff’s Note #
Jeff’s Note #
“Unlike generic exam dumps, ADH analyzes this scenario through the lens of a Real-World Lead Developer.”
“For DVA-C02 candidates, the confusion often lies in distinguishing between UpdateItem and PutItem API semantics. In production, this is about knowing exactly which DynamoDB API call handles create-or-update operations atomically and what minimal IAM permissions your Lambda needs. Let’s drill down.”
The Certification Drill #
Scenario #
TechNova Solutions is building a serverless user preference management system. A backend Lambda function needs to handle user settings updates from their mobile application. The function receives a user’s primary key (user_id) and must:
- Check if the user’s preference record exists in the DynamoDB table
- If it exists, update specific attributes (theme, notification_settings, last_updated)
- If it doesn’t exist, create a new record with default values plus the user_id
The development team wants to implement this with minimal IAM permissions following the principle of least privilege while ensuring the Lambda function can perform these operations reliably.
The Requirement #
Which IAM permissions should the developer request for the Lambda function to achieve this create-or-update (upsert) functionality?
The Options #
- A)
dynamodb:DeleteItem,dynamodb:GetItem,dynamodb:PutItem - B)
dynamodb:UpdateItem,dynamodb:GetItem,dynamodb:DescribeTable - C)
dynamodb:GetRecords,dynamodb:PutItem,dynamodb:UpdateTable - D)
dynamodb:UpdateItem,dynamodb:GetItem,dynamodb:PutItem
Google adsense #
Correct Answer #
Option D.
Quick Insight: The API Behavior Imperative #
- For Developers: Understanding DynamoDB’s
PutItemvsUpdateItembehavior is critical.PutItemperforms a full item replacement (upsert by default), whileUpdateItemcan conditionally update or create with attribute-level granularity. The combination withGetItemprovides flexibility for conditional logic in your Lambda code.
Content Locked: The Expert Analysis #
You’ve identified the answer. But do you know the implementation details that separate a Junior from a Senior?
The Expert’s Analysis #
Correct Answer #
Option D: dynamodb:UpdateItem, dynamodb:GetItem, dynamodb:PutItem
The Winning Logic #
This combination provides complete flexibility for implementing the upsert pattern:
-
dynamodb:GetItem: Allows the Lambda function to check if an item exists using the primary key. This is essential for conditional logic in your code. -
dynamodb:PutItem: Enables creating new items or completely replacing existing items. ThePutItemAPI operation performs an upsert by default—it will create the item if it doesn’t exist or overwrite it entirely if it does. -
dynamodb:UpdateItem: Allows granular updates to specific attributes without replacing the entire item. This is crucial when you want to modify only certain fields (likelast_updatedtimestamp) while preserving other existing attributes.
The Developer’s Perspective: In practice, you might use GetItem first to determine existence, then choose between PutItem (for full replacement) or UpdateItem (for partial updates). Alternatively, you can use UpdateItem alone with attribute expressions, which can create items if they don’t exist when you don’t specify conditions.
// Example: Using UpdateItem for upsert pattern
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
async function upsertUserPreference(userId, preferences) {
const params = {
TableName: 'UserPreferences',
Key: { user_id: userId },
UpdateExpression: 'SET theme = :theme, notification_settings = :notif, last_updated = :timestamp',
ExpressionAttributeValues: {
':theme': preferences.theme,
':notif': preferences.notifications,
':timestamp': Date.now()
}
};
// UpdateItem creates the item if it doesn't exist
return await dynamodb.update(params).promise();
}
The Trap (Distractor Analysis) #
-
Why not Option A (
DeleteItem,GetItem,PutItem)?DeleteItemis irrelevant to the create-or-update requirement. The scenario never mentions deleting records. This is a classic distractor that adds an unnecessary permission, violating least privilege principles.- While
PutItemcan handle upserts, you lose the granular update capability.
-
Why not Option B (
UpdateItem,GetItem,DescribeTable)?DescribeTableis a table-level metadata operation used to retrieve table schema, status, and provisioned throughput—not for data operations.- Missing
PutItemlimits your implementation options. WhileUpdateItemalone can technically handle upserts, having both provides architectural flexibility. - This option would work for update-only scenarios but doesn’t give you the choice between full replacement vs. partial update.
-
Why not Option C (
GetRecords,PutItem,UpdateTable)?GetRecordsis a DynamoDB Streams API call, not a standard DynamoDB table operation. Completely wrong context.UpdateTableis a control plane operation for modifying table configuration (like changing throughput or adding GSIs), not for data manipulation.- This option confuses data plane operations with control plane operations—a common DVA-C02 trap.
The Technical Blueprint #
# Python implementation using boto3 - demonstrating both approaches
import boto3
from botocore.exceptions import ClientError
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('UserPreferences')
# Approach 1: Using PutItem (full replacement)
def upsert_with_put(user_id, preferences):
"""
PutItem replaces the entire item - simpler but less granular
IAM Required: dynamodb:PutItem
"""
item = {
'user_id': user_id,
'theme': preferences.get('theme', 'light'),
'notification_settings': preferences.get('notifications', {}),
'last_updated': int(time.time())
}
table.put_item(Item=item)
return item
# Approach 2: Using UpdateItem (conditional update/create)
def upsert_with_update(user_id, preferences):
"""
UpdateItem with attribute expressions - more granular control
IAM Required: dynamodb:UpdateItem
"""
try:
response = table.update_item(
Key={'user_id': user_id},
UpdateExpression='SET theme = :theme, notification_settings = :notif, last_updated = :ts',
ExpressionAttributeValues={
':theme': preferences.get('theme', 'light'),
':notif': preferences.get('notifications', {}),
':ts': int(time.time())
},
ReturnValues='ALL_NEW'
)
return response['Attributes']
except ClientError as e:
print(f"Error: {e.response['Error']['Code']}")
raise
# Approach 3: Check-then-write pattern
def upsert_with_get_first(user_id, preferences):
"""
Explicit check for existence, then choose operation
IAM Required: dynamodb:GetItem, dynamodb:PutItem OR dynamodb:UpdateItem
"""
try:
response = table.get_item(Key={'user_id': user_id})
if 'Item' in response:
# Item exists - use UpdateItem for partial update
return upsert_with_update(user_id, preferences)
else:
# Item doesn't exist - use PutItem to create
return upsert_with_put(user_id, preferences)
except ClientError as e:
print(f"Error: {e.response['Error']['Code']}")
raise
IAM Policy Example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem"
],
"Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/UserPreferences"
}
]
}
The Comparative Analysis #
| Option | API Operations | Implementation Flexibility | Performance | Use Case Fit |
|---|---|---|---|---|
| A (Delete/Get/Put) | ❌ Includes irrelevant DeleteItem |
Moderate - limited to full replacement | Good - PutItem is fast |
❌ Violates least privilege, wrong operations |
| B (Update/Get/Describe) | ❌ Missing PutItem, includes control plane op |
Low - DescribeTable is metadata only |
Degraded - missing key operation | ❌ Cannot perform full item replacement |
| C (GetRecords/Put/UpdateTable) | ❌ Streams API + control plane ops | None - completely wrong context | N/A - won’t work | ❌ Confuses data vs. control plane |
| D (Update/Get/Put) ✅ | ✅ All relevant data plane operations | High - supports all upsert patterns | Excellent - optimal for all scenarios | ✅ Perfect for create-or-update with flexibility |
Key Performance Note:
UpdateItemhas lower write capacity consumption when updating existing items (only modified attributes are written)PutItemalways writes the entire item but is simpler for full replacementsGetItemadds one read capacity unit but enables conditional logic in application code
Real-World Application (Practitioner Insight) #
Exam Rule #
“For the DVA-C02 exam, when you see a scenario requiring ‘create if not exists, update if exists’ (upsert pattern) with DynamoDB, always look for the combination of GetItem, PutItem, and UpdateItem. These three permissions give you complete flexibility for all upsert implementation patterns.”
Real World #
“In production, we often optimize by using UpdateItem alone with conditional expressions to reduce IAM permissions and API calls. The UpdateItem API can create items when they don’t exist without needing GetItem first:
# Production optimization - UpdateItem only
response = table.update_item(
Key={'user_id': user_id},
UpdateExpression='SET theme = if_not_exists(theme, :default_theme), last_updated = :ts',
ExpressionAttributeValues={
':default_theme': 'light',
':ts': int(time.time())
}
)
However, we keep all three permissions in the IAM policy because:
- Future-proofing: Different code paths might need different strategies
- Conditional logic: Sometimes we need
GetItemto make business decisions before writing - Full replacement scenarios:
PutItemis more intuitive when completely replacing an item
The exam wants you to understand that having all three provides architectural flexibility, even if your specific implementation might use fewer. In real-world systems, requirements evolve, and having the permission already in place avoids redeployment cycles.”
Stop Guessing, Start Mastering #
Disclaimer
This is a study note based on simulated scenarios for the AWS DVA-C02 exam. All company names and scenarios are fictional and created for educational purposes. Always refer to official AWS documentation and the AWS Certified Developer - Associate exam guide for the most current information.