Courses / Hands-on Cloud for Freshers
Session 6 of 8
Data that outlives the server: DynamoDB
Overview
Unit 6 — Data That Outlives the Server: DynamoDB
Course: Hands-on Cloud for Freshers
Prerequisites: You can sign in to the AWS CLI with short-lived credentials and run commands
against your account, and you can read an IAM policy document and say what its Effect, Action
and Resource elements grant (Unit 2). You have launched and terminated an EC2 instance and know
that anything stored on its disk goes with it (Unit 4). You can write a JSON object by hand. No
database experience is assumed.
What the reader can do after this unit:
- Create a DynamoDB table with a partition key chosen for how the data will be fetched, and write, read, query and scan its items from both the console and the AWS CLI using DynamoDB’s typed JSON.
- Explain why fetching an item by its key and reading the whole table give the same answer on a small table and very different costs on a large one, and choose the operation an application should use.
- Write a least-privilege IAM policy that lets an application role use one table and nothing else, attach it to a role, and prove with the IAM policy simulator which requests it allows and which it denies.
Core question this unit answers: How does an application keep its records somewhere that outlives any one server, and how do you let that application’s code touch exactly that data and nothing else?
Connections:
- Builds on: Unit 2’s policies, which you now scope to a single resource by its ARN, and Unit 4’s instance, whose disk disappeared at termination — the problem a managed table solves.
- Leads into: Unit 7, where a Lambda function named
hoc-notes-apiruns with the role you create here,hoc-notes-api-role, and reads and writes the tablehoc-notesyou build here.
Your answers are scored
This unit is assessed. The quiz is marked against a key held separately from your materials. Its first eight questions are multiple choice. Its last two ask you to write a short answer — a DynamoDB item and a set of allow-or-deny decisions — in a format the question states exactly.
Two consequences worth knowing before you start:
- Each written answer is marked by fixed checks, not by opinion. The question tells you every requirement your answer must meet; a grader runs the same checks on every submission.
- Formatting is not marked. Spacing, line breaks and the order of keys inside a JSON object do not change the score. What is marked is whether your answer means the right thing.
Notes
Hands-on Cloud for Freshers — Unit 6: Data That Outlives the Server: DynamoDB
Before you start
You need an AWS account, an everyday administrator identity that is not the root user, and the AWS
CLI signed in as that identity, in the Asia Pacific (Mumbai) Region, ap-south-1. If you set these
up in Units 1 and 2, nothing more is needed; skip to the account ID below.
If you are starting here, without an account or an administrator identity:
- Create the account. Open the Sign up for AWS page,
https://signin.aws.amazon.com/signup?request_type=register. You need an email address you can receive mail at (it becomes the root user’s sign-in name), a phone number that can receive an SMS, and a valid payment method; you choose an account plan during sign-up. Wait for the email confirming that the account is activated before you sign in (Sign up for AWS (advanced)). - Protect the root user. Sign in at
https://console.aws.amazon.com/as Root user and turn on MFA (multi-factor authentication: a one-time code from a device you hold, asked for at each console sign-in) for it. The IAM User Guide’s advice is not to use the root user for daily tasks (Setting up your AWS account). - Create the everyday administrator. Still as root, open the IAM console and choose Users →
Create user. Enter a user name such as
hoc-admin, tick Provide user access to the AWS Management Console and choose I want to create an IAM user, and set a password. On Set permissions choose Add user to group → Create group, name the grouphoc-admins, select the AWS managed policy AdministratorAccess, choose Create user group, select the new group, then Next and Create user (Create an IAM user for emergency access shows these screens). - Switch to it. Sign out of root and sign in at
https://<your-account-id>.signin.aws.amazon.com/consoleashoc-admin(How IAM users sign in to AWS). Use this identity for everything below.
Then sign in the AWS CLI, if it is not signed in already:
- Install the AWS CLI version 2 for your operating system by following the AWS CLI install guide
(Sources).
aws loginneeds version 2.32.0 or later, so check withaws --versionand update if it reports anything older (Sign in withaws login). - Run
aws login. The first time, it asks for a Region: enterap-south-1. It then opens your browser, you sign in as your everyday administrator (not the root user), and the CLI receives temporary credentials that it refreshes on its own — no long-term access key is stored. An IAM identity needs theSignInLocalDevelopmentAccessmanaged policy or equivalent permissions;AdministratorAccessallows every action, so it covers this. - To change the Region later, run
aws configure set region ap-south-1.
You also need your 12-digit account ID, because permissions in this unit name resources by their full address. Print it with:
aws sts get-caller-identity
The Account field of the output is the ID. The AWS CLI documentation notes that no permissions are
required to run this command, so it works whatever identity you are signed in as.
What costs money here. The table in this unit uses on-demand capacity, which the DynamoDB
documentation describes as the default and recommended mode: you are billed per read or write
request, and “if you are driving zero traffic to your table, then with on-demand, you are not charged
for any throughput.” Storage is billed separately. The DynamoDB pricing page lists 25 GB of data
storage per Region as part of the AWS Free Tier; the free 25 read and 25 write capacity units it also
lists apply to the provisioned capacity mode, not to on-demand requests. The few dozen requests in
this unit are billed per request on on-demand, which on the Free account plan is drawn from your
credits. IAM roles and policies cost nothing themselves: the IAM User Guide states that IAM is a
feature of your AWS account “offered at no additional charge”, and you are charged only for the
other services you use with it. Tag the table with project = hands-on-cloud like
everything else.
Nothing here needs a VPC, a subnet or an instance. That is part of the point.
Summary
When Unit 4’s instance was terminated, everything on its disk went with it. An application whose
records live on its own server loses them the day the server is replaced, so real applications keep
their data in a service that outlives any one server. Amazon DynamoDB is such a service: you create a
table, choose a partition key that identifies each record, and read and write records through
an AWS API, with no database server of your own to run, patch or size. Two ideas decide whether you
use it well. The first is that the partition key is how DynamoDB finds an item, so fetching by key
goes straight to one item while Scan reads every item in the table, which on a large table is the
difference between one read and millions. The second is that an application should be allowed to
touch its own table and nothing else, which you express as an IAM policy whose Resource is that one
table’s ARN — and then prove with the IAM policy simulator rather than assume.
Key concepts
| Term | Definition |
|---|---|
| Table | A collection of items, the unit DynamoDB stores data in. You name it and choose its primary key when you create it |
| Item | A group of attributes that is uniquely identifiable among all the other items in the table — similar to a row or record |
| Attribute | A single named data element of an item, such as title — similar to a field or column |
| Primary key | The attribute, or pair of attributes, that uniquely identifies each item. Every item must have it; no two items share it |
| Partition key | The first attribute of the primary key. On its own it is the whole primary key (a simple primary key); combined with a sort key it forms a composite primary key. DynamoDB uses its value as input to an internal hash function that decides where the item is stored |
| Sort key | An optional second key attribute. Items with the same partition key are stored together, ordered by sort key |
| Schemaless | Apart from the primary key, attributes and their types are not declared in advance; each item can carry different ones |
| On-demand capacity mode | A table setting in which you pay per read and write request, with no capacity to plan. The default and recommended mode |
| GetItem | Reads one item, given its full primary key |
| Query | Reads the items that share one partition key value, optionally narrowed by a sort-key condition |
| Scan | Reads every item in the table, up to 1 MB per request, and can filter what it returns only after reading |
| Typed JSON (attribute value) | The CLI’s way of writing an item: each value is wrapped in its type, such as {"S": "text"} for a string or {"N": "2"} for a number |
| ARN | Amazon Resource Name: the full address of one AWS resource, such as a table, used in policies to say exactly which resource is meant |
| Execution role | An IAM role a service such as AWS Lambda assumes to act on your behalf; its trust policy names the service, its permissions policies say what it may do |
Explanations
The failure, before the explanation
You keep notes in a table. Each note is identified by noteId. You add a note:
aws dynamodb put-item --table-name hoc-notes \
--item '{"noteId": {"S": "n-001"}, "title": {"S": "Buy milk"}, "body": {"S": "Two litres"}}'
Later, a different part of your code adds what it thinks is a new note and reuses the same id:
aws dynamodb put-item --table-name hoc-notes \
--item '{"noteId": {"S": "n-001"}, "title": {"S": "Call home"}}'
Both commands succeed. Neither prints an error or a warning. Read the item back and you find only
Call home, with no body at all: the first note is gone. The AWS documentation’s own description
of a put is exact about why — it “creates a new item, or replaces an existing item with a new item.”
The primary key is the item’s identity. Two writes with the same key are two versions of one
item, and the second replaces the first entirely, attributes and all.
This is the most important property of a primary key, and it is why choosing the key is the first design decision for any table: the key is not a label on the data, it is which item you are talking about.
Two ways to picture a table and its key
As a wall of numbered lockers. The table is the wall. The partition key value is the number on a locker door. To fetch an item you name the number and walk straight to that locker: DynamoDB runs the number through its hash function and knows exactly where the item is stored. Putting a new item with a number already in use does not add a second locker; it empties the existing one and puts the new contents in. And the only way to find “every locker containing a red bag” is to open every locker — which is what a Scan does.
As the contacts app on your phone. Each contact is an item, and its unique key might be a contact ID. Some contacts have an email address, some have a birthday, some have neither: the app does not make every contact fill in the same fields. That is what schemaless means — only the key is required, and each item carries whatever other attributes it has. Looking up one contact by ID is instant; reading through all of them to find who lives in one city takes as long as your contact list is long.
Creating a table, and why the key matters first
The table for this unit is hoc-notes, with partition key noteId, a string, and no sort key. The
console path, per the DynamoDB getting-started guide, is Tables → Create table, then a Table
name and a Partition key, leaving Sort key empty, with Table settings left on Default
settings. The CLI form, which also lets you tag the table at creation, is:
aws dynamodb create-table \
--table-name hoc-notes \
--attribute-definitions AttributeName=noteId,AttributeType=S \
--key-schema AttributeName=noteId,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--tags Key=project,Value=hands-on-cloud
Three parts of that command carry the teaching:
--attribute-definitionsdeclares only the key attribute. You do not listtitleorbody: apart from the key, the table is schemaless.KeyType=HASHmarksnoteIdas the partition key. (The documentation explains the old name: the partition key is also called the hash attribute, after the hash function that places items. A sort key isRANGE.) A key attribute must be a string, number or binary.PAY_PER_REQUESTis on-demand capacity.
The command returns at once with "TableStatus": "CREATING". Wait until it reports ACTIVE:
aws dynamodb describe-table --table-name hoc-notes --query "Table.TableStatus"
Why noteId and not title? Because the key is how the application will fetch a note — by its id,
from a link or an API path — and because it must be unique. Titles repeat; two notes called
“Shopping” would overwrite each other, exactly as in the failure above.
Writing items in typed JSON
The CLI writes items in a form where every value is wrapped in its type:
| You mean | You write |
|---|---|
the string Buy milk |
{"S": "Buy milk"} |
| the number 2 | {"N": "2"} |
The number is written inside quotes. That looks wrong the first time and is correct: the type
descriptor N says it is a number, and the value travels as a string. Writing {"N": 2} without
quotes is a mistake to watch for in hand-written items: the value must be the quoted string "2".
A complete item, then, is an object whose keys are attribute names and whose values are these typed wrappers:
{"noteId": {"S": "n-002"}, "title": {"S": "Read chapter 3"}, "priority": {"N": "2"}}
In the console the same item is built with Explore table items → Create item, where Add new attribute asks you to choose each attribute’s type before you type its value.
Three ways to read: GetItem, Query and Scan
Your notes app needs to do two different things. When someone opens a link to note n-002, it must
show that one note. When someone opens the home page, it must list every note. The first job knows
the key; the second does not. DynamoDB gives you a different read for each situation, and choosing
the wrong one is the commonest way to make a table slow and expensive.
Fetching the one note you can name. Back at the wall of lockers: you know the number, so you
walk straight to locker n-002 and open only that door. On the command line:
aws dynamodb get-item --table-name hoc-notes --key '{"noteId": {"S": "n-002"}}'
That is GetItem: you give it the full primary key and it returns that one item, or nothing. By
default DynamoDB reads are eventually consistent; adding --consistent-read asks for a strongly
consistent read, which costs twice as much and reflects every write that completed before it.
Fetching everything filed under one name. Picture the documentation’s own Music table, keyed
by Artist and SongTitle. Asking for one artist is like pulling out the one drawer labelled with
that artist’s name: every song in it comes out, already in title order, and no other drawer is
touched. The same request against this unit’s table looks like this, with the value passed through a
placeholder that starts with a colon:
aws dynamodb query --table-name hoc-notes \
--key-condition-expression "noteId = :id" \
--expression-attribute-values '{":id": {"S": "n-002"}}'
That is Query: it returns the items that share one partition key value, and its key condition
must name the partition key with an equality test. On hoc-notes this returns at most one item,
because in a table with only a partition key no two items can share that value. Query earns its
place when a table has a sort key, as Music does, where a query for one artist returns all of
that artist’s songs, in sort-key order. On this unit’s table, GetItem and Query reach the same single
item; the application in Unit 7 uses GetItem for that.
Listing everything, when you cannot name anything. For the home page there is no key to walk to, so you open every locker on the wall, one after another, and note what is inside:
aws dynamodb scan --table-name hoc-notes --return-consumed-capacity TOTAL
That is Scan: it reads every item in the table. On five notes it looks harmless, and it is the only way here to list all notes. Its cost is the point to understand. The documentation is precise about three behaviours:
- A Scan reads every item, up to 1 MB per request, and the CLI keeps requesting pages until the whole table has been read.
- A filter expression is applied after the items are read: “a
Scanconsumes the same amount of read capacity, regardless of whether a filter expression is present.” Filtering makes the answer smaller, not the work — like opening every locker and then keeping only the red bags. - The response shows both
ScannedCount, the items read, andCount, the items returned. A largeScannedCountwith a smallCountis the signature of an inefficient Scan.
So a Scan that “finds the one note titled X” in a table of a million notes reads a million notes. GetItem by key reads one. On on-demand capacity you pay for what is read, which makes this a bill as well as a speed problem. Listing a handful of notes for a practice app is a fair use of Scan; looking up a single item with it is not.
Least privilege: one role, one table
Think of the staff card a shop gives a delivery worker: it opens the loading bay and nothing else, not the till and not the manager’s office. If the card is lost, the damage is limited to the loading bay. An application should hold its permissions the same way — exactly the ones it needs, and no more. In Unit 7 the code that serves the notes API will run as a Lambda function, and Lambda acts with an execution role — an IAM role whose trust policy names the Lambda service as allowed to assume it:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "lambda.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}
That document answers who may use the role. A separate permissions policy answers what the role may do. For the notes API — create a note, fetch one note, delete one, list them all — that is four DynamoDB actions on one table:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "HocNotesTableOnly",
"Effect": "Allow",
"Action": [
"dynamodb:PutItem",
"dynamodb:GetItem",
"dynamodb:DeleteItem",
"dynamodb:Scan"
],
"Resource": "arn:aws:dynamodb:ap-south-1:<ACCOUNT_ID>:table/hoc-notes"
}
]
}
Read the Resource from the right: the table hoc-notes, in account <ACCOUNT_ID>, in Region
ap-south-1, in the DynamoDB service. That is the table’s ARN, the same form the DynamoDB
documentation uses in its own single-table policy example. Two consequences follow:
- A request to read another table, such as
hoc-orders, matches no statement and is denied. IAM denies anything not explicitly allowed. - A request to delete the table itself (
dynamodb:DeleteTable) is denied too, because that action is not listed. The code can manage notes; it cannot destroy where they live.
Compare the tempting shortcut, "Action": "dynamodb:*" with "Resource": "*". It makes every
permission error disappear, and with it every protection: a bug in the notes code could then read or
delete any table in the account. The documentation’s single-table example also lists the
table/<name>/index/* ARN, which a policy needs only when the table has secondary indexes;
hoc-notes has none, so it is left out.
Proving a policy, rather than assuming it
Suppose you have just typed the policy above and want to know whether a typo in the account ID has
quietly denied everything, or whether DeleteTable slipped in. You could run real requests and find
out the hard way — or you could ask IAM what it would decide. That is what the simulator is for.
The IAM console has a Policy simulator (in the IAM navigation pane). In Principal mode you pick
an identity — here, the role hoc-notes-api-role — and it evaluates the policies attached to that
role against the actions and resource ARNs you enter. Each result row says whether the action is
allowed, implicitly denied (nothing allowed it) or explicitly denied (a Deny statement
matched), with a short explanation.
The documentation is explicit that the simulator “does not make an actual AWS service request”, so
you can test a dangerous action such as DeleteTable without any risk of it happening. It also warns
that simulator results can differ from the live environment in some advanced cases, so the final
proof is always a real request — which Unit 7 makes when the function runs.
The useful habit is to test both sides: the actions that must be allowed, and at least one that must not — a different table, and an action you deliberately left out. A policy that has only ever been shown to allow things has not been shown to be least-privilege.
Flashcards
Say the answer aloud before revealing it. Speaking it is what exposes the gaps that reading past a written answer hides.
You `put-item` twice with the same `noteId`. How many items exist?
One. A put creates a new item or replaces an existing item with the same primary key, entirely, with no error.
What does the partition key do besides identify the item?
Its value is the input to DynamoDB’s internal hash function, which decides where the item is stored — which is why fetching by key goes straight to the item.
Which attributes do you declare when you create a table?
Only the key attributes. Everything else is schemaless and can differ from item to item.
How do you write the number 2 in a CLI item?
{"N": "2"}: the type descriptor N, with the value in quotes.
What is the difference between GetItem and Scan?
GetItem reads the one item whose full key you give. Scan reads every item in the table, a page of up to 1 MB at a time.
Does a filter expression make a Scan cheaper?
No. It is applied after the items are read, so the read capacity consumed is the same with or without it.
On a table with only a partition key, how many items can a Query return?
At most one, since no two items share a partition key value there. Query becomes useful when a table has a sort key.
What are you billed for on an on-demand table with no traffic?
No throughput charge; you are billed per request, and zero requests means zero request charges. Stored data is billed separately.
Do the Free Tier's 25 read and 25 write capacity units cover on-demand requests?
No. Per the pricing page they apply to provisioned capacity mode; on-demand requests are billed per request.
What does a role's trust policy say, and what does its permissions policy say?
The trust policy says who may assume the role (here, lambda.amazonaws.com). The permissions policy says what the role may then do.
Your role's policy allows four actions on `table/hoc-notes`. What happens to `GetItem` on `table/hoc-orders`?
It is denied: no statement allows it, and IAM denies anything not explicitly allowed.
Why test a denied action in the policy simulator, not only the allowed ones?
Because a policy shown only to allow things has not been shown to be least-privilege. The simulator makes no real request, so testing a dangerous action is safe.
Model answer
The question: “Your application needs to store users’ notes. Talk me through how you would set up the storage and its access.”
There are five beats, and they come in this order. Missing any one is a failure state rather than a stylistic gap: each beat is a decision that, skipped, produces either lost data or excess access.
- Key. Choose the partition key from how the data is fetched and what makes it unique — a note id, not a title — and say what happens on a duplicate key: the put replaces the item.
- Access pattern. Name the operations the application performs and match each to GetItem, Query or Scan, saying where a Scan is acceptable (a small list) and where it is not (finding one item in a large table).
- Capacity and cost. Choose on-demand capacity and say what is billed: requests and stored data, with nothing charged for throughput when there is no traffic.
- Least privilege. Give the application a role whose permissions policy lists only the actions from beat two, on only this table’s ARN.
- Proof. Test the role in the policy simulator for the allowed actions and for at least one action and one resource that must be denied, then confirm with a real request.
Spoken, the answer sounds like this:
“I would start with the key, because it decides how every note is found: each note gets a unique
noteId, not its title, since two notes can share a title — and I know a put with an existing key replaces the whole item, so ids must never be reused. Next, the access patterns: the app creates a note, fetches one by id, deletes one, and lists them. Fetching and deleting use the key directly, so they are GetItem and DeleteItem; listing is a Scan, which is fine for one user’s small list but would read every item in a large table, so it is not how I would find a single note. Then capacity and cost: on-demand mode, so I pay per request and for stored data, and an idle table has no throughput charge. Fourth, least privilege: the app runs as a role whose policy allows only those four actions, on only this table’s ARN — nothing on other tables, and no DeleteTable. Finally, the proof: I run the role through the policy simulator for the allowed actions and for a different table and a left-out action that must be denied, and then confirm with a real request.”
Beat five is the one most answers drop, and beat four without it is a claim, not a control.
Why this matters
- A web app that loses data on redeploy. An app that writes to a file on its server loses every record when the server is replaced. Moving the records to a managed table is what lets the server become disposable — which Unit 8 relies on.
- Silent overwrites in production. Two parts of a system generate ids the same way and collide. No error is raised; one record replaces another. Knowing that a put replaces is how you know to design unique keys, or to add a condition that refuses to overwrite.
- A bill driven by one endpoint. A “search” feature implemented as a Scan with a filter reads the whole table on every request. It works in testing on a hundred items and becomes the largest line on the bill at a million.
- A leaked credential with a small blast radius. If the notes service’s role can touch only
table/hoc-notes, a bug or a stolen credential in that service cannot read the users table or delete anything else. Least privilege is what limits how bad a bad day gets.
After this unit
The project for this unit is A Notes Table and the Role That May Use It (project.md). You create
hoc-notes, write and read items from the CLI, measure what a Scan reads compared with a GetItem,
create the role hoc-notes-api-role with the permissions policy above, and prove in the policy
simulator what it allows and denies.
Unit 7 writes the Lambda function hoc-notes-api, attaches this role to it, and serves the notes over
a function URL — the first time your code, rather than you at a command line, reads the table.
Sources
Every AWS behaviour, console label, command and price statement in these notes was checked against the pages below.
- Amazon DynamoDB Developer Guide, Core components of Amazon DynamoDB — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html (fetched 2026-10-02)
- Amazon DynamoDB Developer Guide, Step 1: Create a table in DynamoDB — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-1.html (fetched 2026-10-02)
- Amazon DynamoDB Developer Guide, Step 2: Write data to a DynamoDB table — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-2.html (fetched 2026-10-02)
- Amazon DynamoDB Developer Guide, Step 3: Read data from a DynamoDB table — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-3.html (fetched 2026-10-02)
- Amazon DynamoDB Developer Guide, DynamoDB on-demand capacity mode — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/on-demand-capacity-mode.html (fetched 2026-10-02)
- Amazon DynamoDB Developer Guide, Querying tables in DynamoDB — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html (fetched 2026-10-02)
- Amazon DynamoDB Developer Guide, Key condition expressions for the Query operation — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.KeyConditionExpressions.html (fetched 2026-10-02)
- Amazon DynamoDB Developer Guide, Scanning tables in DynamoDB — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html (fetched 2026-10-02)
- Amazon DynamoDB Developer Guide, IAM policy to grant access to a specific DynamoDB table and its indexes — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/iam-policy-specific-table-indexes.html (fetched 2026-10-02)
- Amazon DynamoDB pricing for on-demand capacity (Free Tier statement) — https://aws.amazon.com/dynamodb/pricing/on-demand/ (fetched 2026-10-02)
- AWS CLI Command Reference,
dynamodb create-table— https://docs.aws.amazon.com/cli/latest/reference/dynamodb/create-table.html (fetched 2026-10-02) - AWS CLI Command Reference,
dynamodb delete-table— https://docs.aws.amazon.com/cli/latest/reference/dynamodb/delete-table.html (fetched 2026-10-02) - AWS Account Management Reference, Sign up for AWS (advanced) — https://docs.aws.amazon.com/accounts/latest/reference/getting-started.html (fetched 2026-10-02)
- IAM User Guide, Setting up your AWS account — https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started-account-iam.html (fetched 2026-10-02)
- IAM User Guide, Create an IAM user in your AWS account (MFA) — https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html (fetched 2026-10-02)
- IAM User Guide, Create an IAM user for emergency access — https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started-emergency-iam-user.html (fetched 2026-10-02)
- AWS Managed Policy Reference, AdministratorAccess — https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AdministratorAccess.html (fetched 2026-10-02)
- IAM User Guide, How IAM users sign in to AWS — https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_sign-in.html (fetched 2026-10-02)
- AWS CLI User Guide, Installing or updating to the latest version of the AWS CLI — https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html (fetched 2026-10-02)
- AWS CLI User Guide, Sign in with
aws login— https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sign-in.html (fetched 2026-10-02) - AWS CLI Command Reference,
configure set— https://docs.aws.amazon.com/cli/latest/reference/configure/set.html (fetched 2026-10-02) - AWS CLI Command Reference,
sts get-caller-identity— https://docs.aws.amazon.com/cli/latest/reference/sts/get-caller-identity.html (fetched 2026-10-02) - AWS Lambda Developer Guide, Defining Lambda function permissions with an execution role — https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html (fetched 2026-10-02)
- IAM User Guide, What is IAM? (Service cost information) — https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html (fetched 2026-10-02)
- IAM User Guide, Create a role to delegate permissions to an AWS service — https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html (fetched 2026-10-02)
- IAM User Guide, Create IAM policies (console) — https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create-console.html (fetched 2026-10-02)
- IAM User Guide, IAM policy testing with the IAM policy simulator — https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_testing-policies.html (fetched 2026-10-02)
- IAM User Guide, How to simulate policies — https://docs.aws.amazon.com/IAM/latest/UserGuide/policies_policy-simulator-how-to.html (fetched 2026-10-02)
- IAM User Guide, Delete roles or instance profiles — https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_manage_delete.html (fetched 2026-10-02)
Project
Hands-on Project — A Notes Table and the Role That May Use It
Objective
Create the DynamoDB table hoc-notes, fill it and read it back from the CLI, measure what a Scan
reads compared with fetching one item by its key, then create the role hoc-notes-api-role with a
policy that reaches only this table and prove in the IAM policy simulator what that role may and may
not do. The point is not the table. The point is that you finish holding a table and a role whose
behaviour you have measured and tested rather than assumed — and both are what Unit 7’s code will
run against.
What you need: the AWS CLI version 2 signed in with short-lived credentials, Region
ap-south-1, and your 12-digit account ID, which aws sts get-caller-identity prints. Units 1 and
2 set these up. If you are starting here, follow If you are starting here under Before you
start in this unit’s notes: it creates the account and an everyday administrator identity, then
signs the CLI in with aws login, which needs AWS CLI version 2.32.0 or later (Sign in with aws login). No task needs a VPC or an instance.
What costs money. An on-demand table is billed per read and write request and for the data it stores (DynamoDB on-demand pricing); on the Free account plan those charges are drawn from your Free Tier credits. Tasks 1 and 2 make a few dozen requests. IAM roles and policies carry no charge (What is IAM?).
Conventions for every task:
- Every resource carries the tag
project = hands-on-cloud. - Every output file is plain text in the shape given. Where a shape is given, follow it exactly:
the parts in
<angle brackets>are what you fill in, without the brackets, and every other character is copied as shown. - On Windows, the CLI commands below need the quoting changes the DynamoDB getting-started guide
shows for Windows CMD; the simplest route is to put each item in a file and pass
--item file://item.json.
Task 1 — Create the table and fill it
Scope: one table, five notes, one deliberate overwrite. Stop once the five notes read back correctly.
-
Create the table:
aws dynamodb create-table \ --table-name hoc-notes \ --attribute-definitions AttributeName=noteId,AttributeType=S \ --key-schema AttributeName=noteId,KeyType=HASH \ --billing-mode PAY_PER_REQUEST \ --tags Key=project,Value=hands-on-cloudIt returns at once with a
TableStatusofCREATING; you can read and write items only once the table isACTIVE. Wait for that:aws dynamodb wait table-exists --table-name hoc-notesIt checks every 20 seconds and returns with no output once the table is
ACTIVE. If it exits with return code 255 instead, it gave up after 25 checks: run it again. Then confirm withaws dynamodb describe-table --table-name hoc-notes --query "Table.TableStatus", which must print"ACTIVE".If
create-tablefails withResourceInUseException, a table namedhoc-notesalready exists in this Region, left by an earlier attempt. Delete it and wait for it to go, exactly as in Task 4 (step 1, then thewait table-not-existscommand), and runcreate-tableagain, so that you start from an empty table. -
Write five notes,
n-001ton-005, each with atitlestring and aprioritynumber from 1 to 3. The first one is:aws dynamodb put-item --table-name hoc-notes \ --item '{"noteId": {"S": "n-001"}, "title": {"S": "Buy milk"}, "priority": {"N": "2"}}'Choose your own titles for the other four. Give
n-003an extrabodystring attribute that the others do not have. -
The deliberate overwrite. Put an item with
noteIdn-001and only atitleofOverwritten. Readn-001back:aws dynamodb get-item --table-name hoc-notes \ --key '{"noteId": {"S": "n-001"}}' --consistent-read--consistent-readasks for a strongly consistent read, which returns the most up-to-date data. Without it the read is eventually consistent, the default, and might not yet reflect a write that has only just completed. Note what is left of the original item. Then put the originaln-001back with the same command you used in step 2, and run theget-itemabove once more: it must showpriorityagain. If it does not, repeat the put. -
Open the table in the console with Explore table items and confirm all five notes are listed, with
bodyshowing only onn-003. If a note is missing, orbodyshows on another note, run that note’sput-itemagain with the corrected item and reload the page.
Time budget: 30 minutes
Output: items.txt, in this shape:
$ <a command you ran>
<its output, pasted as it is, if it printed anything>
$ <the next command you ran>
...
survived: <attribute>,<attribute>,...
The commands, in the order you ran them, are the five put-item commands from step 2, the
overwrite put-item from step 3, and the get-item straight after it, with its output. Write each
command on a single line starting with $ (a dollar sign and a space), joining any continued lines
into one. Do not include the restoring put or the second get-item. The last line lists,
comma-separated with no spaces, the attribute names present in that get-item output.
Task 2 — Measure what each read costs
Scope: three reads, compared. Stop once the table below is filled.
Run each command and copy the numbers it reports. --return-consumed-capacity TOTAL makes DynamoDB
report the capacity each request consumed.
aws dynamodb get-item --table-name hoc-notes \
--key '{"noteId": {"S": "n-003"}}' \
--return-consumed-capacity TOTAL
aws dynamodb scan --table-name hoc-notes \
--return-consumed-capacity TOTAL
aws dynamodb scan --table-name hoc-notes \
--filter-expression "priority = :p" \
--expression-attribute-values '{":p": {"N": "3"}}' \
--return-consumed-capacity TOTAL
Write reads.txt in this shape, one line per command:
get-item n-003 | items returned: 1 | items read: 1 | capacity: <CapacityUnits>
scan | items returned: <Count> | items read: <ScannedCount> | capacity: <CapacityUnits>
scan priority = 3 | items returned: <Count> | items read: <ScannedCount> | capacity: <CapacityUnits>
Before you go on, check the scan line: its items returned must equal the number of notes you
wrote in Task 1, five. If it is lower, a note did not land: go back to Task 1, step 4, then run the
three commands again.
Then add two lines in this shape:
filter-changed-items-read: <yes|no>
million-note-scan-reads: <integer>
The first says whether the second and third lines show a different items read. The second says
how many items the third command would read if the table held exactly one million notes; reason it
out from your own measurements and the notes’ section on Scan. Write the number as plain digits,
with no commas or spaces.
Time budget: 20 minutes
Output: reads.txt with the three measurement lines and the two lines above.
Task 3 — Create the role and prove what it may do
Scope: one policy, one role, six simulated requests. Stop once all six results are recorded.
-
The permissions policy. In the IAM console choose Policies → Create policy, choose the JSON option, and paste this policy, with
<ACCOUNT_ID>replaced by your 12-digit account ID:{ "Version": "2012-10-17", "Statement": [ { "Sid": "HocNotesTableOnly", "Effect": "Allow", "Action": [ "dynamodb:PutItem", "dynamodb:GetItem", "dynamodb:DeleteItem", "dynamodb:Scan" ], "Resource": "arn:aws:dynamodb:ap-south-1:<ACCOUNT_ID>:table/hoc-notes" } ] }Resolve anything policy validation reports, choose Next, name it
hoc-notes-table-access, add theprojecttag, and choose Create policy. -
The role. Choose Roles → Create role. For Trusted entity type choose AWS service; for Service or use case choose Lambda. Choose Next. Under Permissions policies select
hoc-notes-table-accessonly. Choose Next, name the rolehoc-notes-api-role, add theprojecttag, review, and choose Create role. Open the role and check two things: its trust policy nameslambda.amazonaws.com, and its Permissions tab listshoc-notes-table-accessand no other policy. If the trust policy names a different service, you chose another use case: delete the role as in Task 4, step 2, and create it again. If the policy is missing, choose Add permissions → Attach policies on that tab and attach it. -
The proof. In the IAM console’s navigation pane choose Policy simulator, and use Principal mode. Select the role
hoc-notes-api-roleas the identity; the side panel then lists the policies attached to it, and it must showhoc-notes-table-access. Add the actions below. For each, enter the specific resource ARN shown (replace<ACCOUNT_ID>) rather than testing against all resources; fordynamodb:GetItementer both ARNs, the one in row 2 and the one in row 5. Then run the simulation.
| # | Action | Resource |
|---|---|---|
| 1 | dynamodb:PutItem |
arn:aws:dynamodb:ap-south-1:<ACCOUNT_ID>:table/hoc-notes |
| 2 | dynamodb:GetItem |
arn:aws:dynamodb:ap-south-1:<ACCOUNT_ID>:table/hoc-notes |
| 3 | dynamodb:DeleteItem |
arn:aws:dynamodb:ap-south-1:<ACCOUNT_ID>:table/hoc-notes |
| 4 | dynamodb:Scan |
arn:aws:dynamodb:ap-south-1:<ACCOUNT_ID>:table/hoc-notes |
| 5 | dynamodb:GetItem |
arn:aws:dynamodb:ap-south-1:<ACCOUNT_ID>:table/hoc-orders |
| 6 | dynamodb:DeleteTable |
arn:aws:dynamodb:ap-south-1:<ACCOUNT_ID>:table/hoc-notes |
The simulator does not make a real request, so no row can change anything in your account. Before
you run it, write down for each row what you predict from the policy’s Action and Resource.
Each result the simulator shows says the action is allowed, implicitly denied or explicitly denied;
record allowed as allowed, and either kind of denied as denied. Write simulator.txt one line
per row, in row order, with the resource name being the part of the ARN after table/:
<row> | <action> | <resource name> | predicted: <allowed|denied> | simulator: <allowed|denied>
If the role is missing from the list, its side panel shows no policy, or every row is denied straight after you created them, IAM may not yet show your new role and policy everywhere: changes in IAM take time to become visible (Troubleshoot IAM). Wait a few minutes and run the simulation again before you change anything. If a result still differs from your prediction, find out which of the two is wrong. When the policy is the cause — most often a mistyped account ID or Region in the ARN — fix it and run the simulation again.
Time budget: 40 minutes
Output: simulator.txt with six lines in the shape above.
Task 4 — Write the hand-off record for Unit 7: keep, or tear down
Scope: a decision, a check, and a seven-line record. This task is not optional. Its output,
teardown.txt, is the hand-off record Unit 7 opens with: the first thing Unit 7 does is check
whether hoc-notes and hoc-notes-api-role exist, and this file already holds that answer, the
role’s ARN, and what the simulator said the role may do.
Unit 7 uses hoc-notes and hoc-notes-api-role as they are now. If you are going straight on to
Unit 7, keep both: an on-demand table with no traffic makes no requests to be billed for, only
its small stored data, and IAM resources carry no charge.
If you are stopping here, or will not return soon, delete them, and Unit 7 rebuilds them from its own appendix:
- Delete the table:
aws dynamodb delete-table --table-name hoc-notes. Its status becomesDELETING, and the table and all its items are removed. - In the IAM console choose Roles, select
hoc-notes-api-role, choose Delete, type the role name to confirm, and choose Delete. Deleting a role in the console detaches its managed policies for you (Delete roles or instance profiles). - In the IAM console choose Policies, select the button next to
hoc-notes-table-access(the search box filters the list), choose Actions → Delete, follow the instructions to confirm, and choose Delete (Delete IAM policies (console)). Delete the role first: a policy that is still attached cannot be deleted, and the CLI reportsDeleteConflict(iam delete-policy).
The check, either way. If you deleted the table, first wait for the deletion to finish, because
straight after delete-table the table still exists with status DELETING:
aws dynamodb wait table-not-exists --table-name hoc-notes
This command polls describe-table until DynamoDB reports ResourceNotFoundException, then returns
with no output. If it instead exits with return code 255, it gave up before the table was gone: run
it again (dynamodb wait table-not-exists). If you kept the table, skip the wait. Then run:
aws sts get-caller-identity --query "Account" --output text
aws dynamodb describe-table --table-name hoc-notes --query "Table.TableStatus" --output text
aws iam get-role --role-name hoc-notes-api-role --query "Role.Arn" --output text
--output text prints each value without quotation marks. The first prints your 12-digit account
ID. If you kept the resources, the second prints the table’s status and the third the role’s ARN. If
you deleted them, the second fails with ResourceNotFoundException and the third with
NoSuchEntity — the errors the DynamoDB and IAM API references name for a table or role that does
not exist. If you deleted the role but the third command still prints its ARN, the deletion is not
yet visible everywhere, because changes in IAM take time to become visible (Troubleshoot IAM):
wait a few minutes and run it again.
If you deleted them, also confirm the policy is gone. This lists only the policies you created
(--scope Local) and prints nothing once hoc-notes-table-access no longer exists:
aws iam list-policies --scope Local \
--query "Policies[?PolicyName=='hoc-notes-table-access'].Arn" --output text
Write two files.
teardown.txt holds exactly these seven lines and nothing else:
decision: <kept|deleted>
region: ap-south-1
account: <the 12-digit account ID>
table: hoc-notes | <the status printed, or ResourceNotFoundException>
role: hoc-notes-api-role | <the role ARN printed, or NoSuchEntity>
simulator-allowed: <the actions simulator.txt records as allowed, comma-separated>
unit7-starts-with: <attach logging to the kept role|rebuild table and role from the appendix>
Fill it from the commands above and from simulator.txt. On the simulator-allowed line, list the
action of every simulator.txt row that says simulator: allowed, in row order, each action once,
separated by commas with no spaces. On the last line, write the first choice if you kept the
resources and the second if you deleted them.
teardown-check.txt holds the evidence the record was filled from: every command you ran in this
task, in the order you ran it, each followed by what it printed, in the same shape as items.txt:
$ <a command you ran in this task>
<its output or error message, pasted as it is, or (empty) if it printed nothing>
$ <the next command you ran>
...
Before you finish, check teardown.txt against the one case that applies to you. This check is for
you; it goes in neither file:
- Kept: the
tableline showsACTIVE, theroleline shows an ARN ending inrole/hoc-notes-api-role, and the last line saysattach logging to the kept role. - Deleted: the
tableandrolelines showResourceNotFoundExceptionandNoSuchEntity, thelist-policiescommand printed nothing, and the last line saysrebuild table and role from the appendix.
If a line does not match, run the command it comes from again and correct the line.
Time budget: 10 minutes
Output: two files — teardown.txt, the seven-line hand-off record above and nothing else; and
teardown-check.txt, the commands you ran in this task with their output.
What this feeds
Unit 7 opens by deploying a Lambda function, hoc-notes-api, and before its first task it needs
exactly what teardown.txt records. Its opening check — do hoc-notes and hoc-notes-api-role
exist? — is answered by your table and role lines, and your unit7-starts-with line tells you
where Unit 7 begins: attaching a logging policy to the role you kept, or rebuilding both from Unit
7’s appendix. The role ARN is the identity the function runs as, and the simulator-allowed line
is what IAM said that role may do with hoc-notes; when the function first runs, its real requests
are the live confirmation of those results.
Sources
- Amazon DynamoDB Developer Guide, Core components of Amazon DynamoDB — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html (fetched 2026-10-02)
- Amazon DynamoDB Developer Guide, Step 1: Create a table in DynamoDB — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-1.html (fetched 2026-10-02)
- Amazon DynamoDB Developer Guide, Step 2: Write data to a DynamoDB table — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-2.html (fetched 2026-10-02)
- Amazon DynamoDB Developer Guide, Step 3: Read data from a DynamoDB table — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-3.html (fetched 2026-10-02)
- Amazon DynamoDB Developer Guide, Scanning tables in DynamoDB — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html (fetched 2026-10-02)
- Amazon DynamoDB Developer Guide, DynamoDB on-demand capacity mode — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/on-demand-capacity-mode.html (fetched 2026-10-02)
- Amazon DynamoDB pricing for on-demand capacity — https://aws.amazon.com/dynamodb/pricing/on-demand/ (fetched 2026-10-02)
- Amazon DynamoDB API Reference, DescribeTable (
ResourceNotFoundException) — https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html (fetched 2026-10-02) - AWS CLI Command Reference,
dynamodb create-table— https://docs.aws.amazon.com/cli/latest/reference/dynamodb/create-table.html (fetched 2026-10-02) - AWS CLI Command Reference,
dynamodb delete-table— https://docs.aws.amazon.com/cli/latest/reference/dynamodb/delete-table.html (fetched 2026-10-02) - AWS CLI Command Reference,
dynamodb wait table-not-exists— https://docs.aws.amazon.com/cli/latest/reference/dynamodb/wait/table-not-exists.html (fetched 2026-10-02) - AWS CLI User Guide, Sign in with
aws login— https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sign-in.html (fetched 2026-10-02) - AWS CLI Command Reference,
sts get-caller-identity— https://docs.aws.amazon.com/cli/latest/reference/sts/get-caller-identity.html (fetched 2026-10-02) - IAM User Guide, What is IAM? — https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html (fetched 2026-10-02)
- IAM User Guide, Create IAM policies (console) — https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create-console.html (fetched 2026-10-02)
- IAM User Guide, Create a role to delegate permissions to an AWS service — https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html (fetched 2026-10-02)
- IAM User Guide, IAM policy testing with the IAM policy simulator — https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_testing-policies.html (fetched 2026-10-02)
- IAM User Guide, How to simulate policies — https://docs.aws.amazon.com/IAM/latest/UserGuide/policies_policy-simulator-how-to.html (fetched 2026-10-02)
- IAM User Guide, Delete roles or instance profiles — https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_manage_delete.html (fetched 2026-10-02)
- IAM API Reference, GetRole (
NoSuchEntity) — https://docs.aws.amazon.com/IAM/latest/APIReference/API_GetRole.html (fetched 2026-10-02) - AWS CLI Command Reference,
dynamodb wait table-exists— https://docs.aws.amazon.com/cli/latest/reference/dynamodb/wait/table-exists.html (fetched 2026-10-02) - Amazon DynamoDB API Reference, CreateTable (
CREATING,ACTIVE,ResourceInUseException) — https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html (fetched 2026-10-02) - Amazon DynamoDB Developer Guide, DynamoDB read consistency — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadConsistency.html (fetched 2026-10-02)
- IAM User Guide, Troubleshoot IAM (changes are not always immediately visible) — https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html (fetched 2026-10-02)
- IAM User Guide, Delete IAM policies (console) — https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-delete-console.html (fetched 2026-10-02)
- AWS CLI Command Reference,
iam delete-policy(DeleteConflict) — https://docs.aws.amazon.com/cli/latest/reference/iam/delete-policy.html (fetched 2026-10-02) - AWS CLI Command Reference,
iam list-policies(--scope Local) — https://docs.aws.amazon.com/cli/latest/reference/iam/list-policies.html (fetched 2026-10-02)
Quiz
Online marking is not open yet. Work through the questions and check the written ones against the criteria printed with each question. The answer key is kept back for now.
Quiz — Unit 6: Data That Outlives the Server: DynamoDB
Instructions: Ten questions in two parts, and both parts are scored.
- Questions 1–8 are multiple choice. Pick one option per question. They are marked by comparing your letter against the key.
- Questions 9–10 ask you to write a short answer in a stated format. Each is marked by a grader that runs fixed checks on what you submit; the checks and the marking rubric are held in the answer key, not here.
Work closed-book on the whole quiz. Submit plain text exactly in the format each question states.
Every question uses the table from this unit: hoc-notes, partition key noteId (string), no sort
key, on-demand capacity, in Region ap-south-1.
1. You run put-item for an item with noteId n-001, then run put-item again with the same
noteId and a different set of attributes. Both commands succeed. What does the table now hold for
n-001?
a) Two items, because DynamoDB keeps every put as a separate version stored under the same key value b) One item holding only the second write’s attributes, because a put replaces the whole existing item c) One item holding the attributes of both writes, because a put merges new attributes into the old d) The first item unchanged, because a put that reuses an existing key value is ignored by DynamoDB
2. Which operation reads every item in the table?
a) GetItem, when it is called with only a partition key on a table that also defines a sort key b) Query, when its key condition names the partition key and leaves the sort key unrestricted c) PutItem, because it checks every existing item for a matching key before it writes a new one d) Scan, which reads each item in the table one page at a time, whether or not it is filtered
3. What does DynamoDB do with an item’s partition key value?
a) It uses the value as input to an internal hash function that decides which partition stores the item b) It uses the value to sort the results of a Scan, which returns items in partition key order c) It indexes only that attribute, so every other attribute must be declared when the table is made d) It uses the value’s type to set the maximum size of the item, so a string key allows larger items
4. In a put-item command, how do you write a priority attribute holding the number 2?
a) "priority": 2, because the CLI infers the type from the JSON value and needs no type wrapper
b) "priority": {"N": 2}, because the descriptor goes in the wrapper and the value stays numeric
c) "priority": {"N": "2"}, because the descriptor marks a number and the value travels as text
d) "priority": {"S": "2"}, because DynamoDB stores every scalar value as a string on its disks
5. A table holds one million notes. A Scan with a filter expression returns three of them. What read capacity does that Scan consume?
a) Capacity for the three items returned, because the filter runs before items are read from storage b) No capacity, because a Scan with a filter is answered from an index at no extra request charge c) Capacity for every item read, because the filter is applied only after the Scan has read them d) Capacity for one item, because a Scan is billed as a single request whatever the number of items
6. The DynamoDB pricing page (Sources, below) lists 25 read and 25 write capacity units as part of the Free Tier. Which tables does that allowance cover?
a) Tables in provisioned capacity mode, so the requests made to an on-demand table are billed per request b) Tables in on-demand capacity mode, so a provisioned table’s capacity is billed from its first unit c) Tables in both modes alike, so the first 25 requests made each month cost nothing on any table d) No tables at all, because the Free Tier for DynamoDB covers stored data and never covers capacity
7. A role’s only policy allows PutItem, GetItem, DeleteItem and Scan on
arn:aws:dynamodb:ap-south-1:<ACCOUNT_ID>:table/hoc-notes. Code running as that role calls GetItem
on the table hoc-orders in the same account and Region. What happens?
a) Allowed, because GetItem is in the policy’s action list and IAM evaluates the action before the resource b) Allowed, because both tables are in the same account and Region as the table named in the policy c) Denied with an explicit deny, because a policy that names one table writes a Deny for all the others d) Denied, because no statement allows that action on that resource, and IAM denies anything not allowed
8. You run a Query on hoc-notes with the key condition noteId = :id. What can it return?
a) Every note whose title contains the value, because a key condition is matched against all attributes
b) At most one item, because in a table with only a partition key no two items share a key value
c) All of the items, sorted by noteId, because a Query on a table without a sort key reads every item
d) An error, because a Query needs a condition on a sort key and this table does not define a sort key
Part 2 — Constructed response
Submit plain text exactly in the format each question states, with no surrounding quotes and no extra commentary.
9. Write the JSON object you would pass to put-item --item for this note:
noteIdis the stringn-010titleis the stringPay feespriorityis the number1
The item must hold exactly these three attributes, each written in the form DynamoDB’s put-item
expects. Format: one JSON object; spacing, line breaks and the order of keys are not marked.
10. A role’s only policy is:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Scan"],
"Resource": "arn:aws:dynamodb:ap-south-1:111122223333:table/hoc-notes"
}
]
}
For each request below, made by code running as that role, decide whether it is allowed.
| # | Action | Resource |
|---|---|---|
| 1 | dynamodb:GetItem |
arn:aws:dynamodb:ap-south-1:111122223333:table/hoc-notes |
| 2 | dynamodb:DeleteItem |
arn:aws:dynamodb:ap-south-1:111122223333:table/hoc-notes |
| 3 | dynamodb:Scan |
arn:aws:dynamodb:ap-south-1:111122223333:table/hoc-notes |
| 4 | dynamodb:GetItem |
arn:aws:dynamodb:ap-south-1:111122223333:table/hoc-orders |
| 5 | dynamodb:PutItem |
arn:aws:dynamodb:us-east-1:111122223333:table/hoc-notes |
| 6 | dynamodb:DeleteTable |
arn:aws:dynamodb:ap-south-1:111122223333:table/hoc-notes |
| 7 | dynamodb:Query |
arn:aws:dynamodb:ap-south-1:111122223333:table/hoc-notes |
| 8 | dynamodb:PutItem |
arn:aws:dynamodb:ap-south-1:111122223333:table/hoc-notes |
Write eight words separated by commas, in row order, each either ALLOW or DENY — for example
ALLOW, DENY, …. Words are compared without regard to case or spaces. Your answer is marked against
how IAM evaluates this policy for each request.
Sources
The AWS behaviour these questions test is taught in this unit’s notes, from these pages:
- Core components of Amazon DynamoDB — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html (fetched 2026-10-02)
- Step 2: Write data to a DynamoDB table — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-2.html (fetched 2026-10-02)
- Querying tables in DynamoDB — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html (fetched 2026-10-02)
- Scanning tables in DynamoDB — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html (fetched 2026-10-02)
- Amazon DynamoDB pricing for on-demand capacity — https://aws.amazon.com/dynamodb/pricing/on-demand/ (fetched 2026-10-02)
- IAM policy to grant access to a specific DynamoDB table and its indexes — https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/iam-policy-specific-table-indexes.html (fetched 2026-10-02)
- IAM User Guide, Policy evaluation logic — https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html (fetched 2026-10-02)
TechEazy Consulting training material — not affiliated with or endorsed by Amazon Web Services (AWS).