101 lines
3.4 KiB
Markdown
101 lines
3.4 KiB
Markdown
# Assignment
|
|
The Nautilus DevOps team needs to set up a DynamoDB table for storing user data. They need to create a DynamoDB table with the following specifications:
|
|
|
|
1) The table name should be nautilus-users.
|
|
|
|
2) The primary key should be nautilus_id (String).
|
|
|
|
3) The table should use PAY_PER_REQUEST billing mode.
|
|
|
|
Use Terraform to create this DynamoDB table. The Terraform working directory is /home/bob/terraform. Create the main.tf file (do not create a different .tf file) to create the DynamoDB table.
|
|
|
|
Note: Right-click under the EXPLORER section in VS Code and select Open in Integrated Terminal to launch the terminal.
|
|
|
|
# Solution
|
|
|
|
# DynamoDB Table — `nautilus-users`
|
|
|
|
Terraform solution to create an on-demand DynamoDB table keyed on a string
|
|
partition key.
|
|
|
|
## `main.tf`
|
|
|
|
```hcl
|
|
terraform {
|
|
required_providers {
|
|
aws = {
|
|
source = "hashicorp/aws"
|
|
version = "~> 6.0"
|
|
}
|
|
}
|
|
}
|
|
|
|
provider "aws" {
|
|
region = "us-east-1"
|
|
}
|
|
|
|
resource "aws_dynamodb_table" "nautilus_users" {
|
|
name = "nautilus-users"
|
|
billing_mode = "PAY_PER_REQUEST"
|
|
hash_key = "nautilus_id"
|
|
|
|
attribute {
|
|
name = "nautilus_id"
|
|
type = "S"
|
|
}
|
|
}
|
|
```
|
|
|
|
## How to run
|
|
|
|
```bash
|
|
cd /home/bob/terraform
|
|
terraform init
|
|
terraform apply -auto-approve
|
|
```
|
|
|
|
## How it works
|
|
|
|
### `aws_dynamodb_table`
|
|
|
|
A single resource provisions the whole table.
|
|
|
|
- **`name = "nautilus-users"`** — the table name, exactly as required.
|
|
|
|
- **`hash_key = "nautilus_id"`** — sets the table's **partition key** (DynamoDB's
|
|
API calls it the "hash key"). This is the primary key the task asks for. No
|
|
`range_key` is defined, so `nautilus_id` alone uniquely identifies each item — a
|
|
simple primary key rather than a composite one.
|
|
|
|
- **`attribute` block** — this is the part people forget. DynamoDB is schemaless for
|
|
non-key fields, so you only ever declare attributes that participate in a key
|
|
(partition key, sort key, or an index key). Here `nautilus_id` is the partition
|
|
key, so it **must** be declared with its type. `type = "S"` marks it as a
|
|
**String** (the valid types are `S` string, `N` number, `B` binary). Referencing a
|
|
`hash_key` without a matching `attribute` block fails validation with
|
|
"all attributes must be indexed."
|
|
|
|
- **`billing_mode = "PAY_PER_REQUEST"`** — puts the table in **on-demand** mode.
|
|
You pay per read/write request with no capacity to provision or manage, and
|
|
DynamoDB auto-scales to traffic. Because of this mode, the `read_capacity` /
|
|
`write_capacity` arguments are **omitted** — they're only valid (and required)
|
|
under `PROVISIONED` billing. Setting them here would be a config error.
|
|
|
|
### Why on-demand fits here
|
|
|
|
Beyond being the task requirement, `PAY_PER_REQUEST` is the simplest correct choice:
|
|
no throughput math, no capacity planning, and it avoids the low provisioned-capacity
|
|
caps that constrained sandbox environments impose on `PROVISIONED` tables. The table
|
|
comes up ready to take reads and writes immediately.
|
|
|
|
## Verify
|
|
|
|
```bash
|
|
aws dynamodb describe-table --table-name nautilus-users \
|
|
--query 'Table.{Name:TableName,Billing:BillingModeSummary.BillingMode,Key:KeySchema,Attrs:AttributeDefinitions,Status:TableStatus}'
|
|
```
|
|
|
|
Expected — `BillingMode: PAY_PER_REQUEST`, a key schema with `nautilus_id` as
|
|
`HASH`, an attribute definition of `nautilus_id` type `S`, and `TableStatus: ACTIVE`
|
|
(the table takes a few seconds to transition from `CREATING` to `ACTIVE`).
|