Skip to main content

AWS DVA-C02 Drill: DynamoDB IAM Permissions - The Upsert Pattern Strategy

Jeff Taakey
Author
Jeff Taakey
21+ Year Enterprise Architect | AWS SAA/SAP & Multi-Cloud Expert.

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:

  1. Check if the user’s preference record exists in the DynamoDB table
  2. If it exists, update specific attributes (theme, notification_settings, last_updated)
  3. 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 PutItem vs UpdateItem behavior is critical. PutItem performs a full item replacement (upsert by default), while UpdateItem can conditionally update or create with attribute-level granularity. The combination with GetItem provides 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. The PutItem API 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 (like last_updated timestamp) 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)?

    • DeleteItem is 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 PutItem can handle upserts, you lose the granular update capability.
  • Why not Option B (UpdateItem, GetItem, DescribeTable)?

    • DescribeTable is a table-level metadata operation used to retrieve table schema, status, and provisioned throughput—not for data operations.
    • Missing PutItem limits your implementation options. While UpdateItem alone 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)?

    • GetRecords is a DynamoDB Streams API call, not a standard DynamoDB table operation. Completely wrong context.
    • UpdateTable is 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:

  • UpdateItem has lower write capacity consumption when updating existing items (only modified attributes are written)
  • PutItem always writes the entire item but is simpler for full replacements
  • GetItem adds 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:

  1. Future-proofing: Different code paths might need different strategies
  2. Conditional logic: Sometimes we need GetItem to make business decisions before writing
  3. Full replacement scenarios: PutItem is 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.

The DevPro Network: Mission and Founder

A 21-Year Tech Leadership Journey

Jeff Taakey has driven complex systems for over two decades, serving in pivotal roles as an Architect, Technical Director, and startup Co-founder/CTO.

He holds both an MBA degree and a Computer Science Master's degree from an English-speaking university in Hong Kong. His expertise is further backed by multiple international certifications including TOGAF, PMP, ITIL, and AWS SAA.

His experience spans diverse sectors and includes leading large, multidisciplinary teams (up to 86 people). He has also served as a Development Team Lead while cooperating with global teams spanning North America, Europe, and Asia-Pacific. He has spearheaded the design of an industry cloud platform. This work was often conducted within global Fortune 500 environments like IBM, Citi and Panasonic.

Following a recent Master’s degree from an English-speaking university in Hong Kong, he launched this platform to share advanced, practical technical knowledge with the global developer community.


About This Site: AWS.CertDevPro.com


AWS.CertDevPro.com focuses exclusively on mastering the Amazon Web Services ecosystem. We transform raw practice questions into strategic Decision Matrices. Led by Jeff Taakey (MBA & 21-year veteran of IBM/Citi), we provide the exclusive SAA and SAP Master Packs designed to move your cloud expertise from certification-ready to project-ready.