docs: add Terraform certification notes and tasks
This commit is contained in:
130
terraform/task-23.md
Normal file
130
terraform/task-23.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Assignment
|
||||
|
||||
The Nautilus DevOps team needs to set up an Amazon OpenSearch Service domain to store and search their application logs. The domain should have the following specification:
|
||||
|
||||
1) The domain name should be devops-es.
|
||||
|
||||
2) Use Terraform to create the OpenSearch domain. The Terraform working directory is /home/bob/terraform. Create the main.tf file (do not create a different .tf file) to accomplish this task.
|
||||
|
||||
|
||||
Notes:
|
||||
|
||||
The Terraform working directory is /home/bob/terraform.
|
||||
|
||||
Right-click under the EXPLORER section in VS Code and select Open in Integrated Terminal to launch the terminal.
|
||||
|
||||
Before submitting the task, ensure that terraform plan returns No changes. Your infrastructure matches the configuration.
|
||||
|
||||
The OpenSearch domain creation process may take several minutes. Please wait until the domain is fully created before submitting.
|
||||
|
||||
# Solution
|
||||
|
||||
# OpenSearch Domain — `devops-es`
|
||||
|
||||
Terraform solution to create a minimal, single-node Amazon OpenSearch Service domain
|
||||
that comes up clean and reports no drift on re-plan.
|
||||
|
||||
## `main.tf`
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 6.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = "us-east-1"
|
||||
}
|
||||
|
||||
resource "aws_opensearch_domain" "devops_es" {
|
||||
domain_name = "devops-es"
|
||||
|
||||
cluster_config {
|
||||
instance_type = "t3.small.search"
|
||||
instance_count = 1
|
||||
}
|
||||
|
||||
ebs_options {
|
||||
ebs_enabled = true
|
||||
volume_type = "gp2"
|
||||
volume_size = 10
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## How to run
|
||||
|
||||
```bash
|
||||
cd /home/bob/terraform
|
||||
terraform init
|
||||
terraform apply -auto-approve
|
||||
# Domain creation takes ~10-20 minutes. Wait for apply to fully return.
|
||||
|
||||
# Required idempotency check:
|
||||
terraform plan
|
||||
# -> "No changes. Your infrastructure matches the configuration."
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
### `aws_opensearch_domain`
|
||||
|
||||
- **`domain_name = "devops-es"`** — the domain name, exactly as required.
|
||||
|
||||
- **`cluster_config`** — defines the data nodes:
|
||||
- `instance_type = "t3.small.search"` — the smallest current-generation
|
||||
general-purpose node. OpenSearch instance types carry a `.search` suffix. Small
|
||||
burstable nodes keep the domain inside sandbox cost limits (OpenSearch isn't in
|
||||
the published KodeKloud caps, so the general "smallest viable instance" rule
|
||||
applies).
|
||||
- `instance_count = 1` — a single node. No `zone_awareness_enabled` and no
|
||||
`dedicated_master_enabled`, which are unnecessary (and would cost more) for a
|
||||
lab domain.
|
||||
|
||||
- **`ebs_options`** — OpenSearch nodes on this instance family use EBS for storage:
|
||||
- `ebs_enabled = true` — required for non-instance-store types.
|
||||
- `volume_type = "gp2"` — **deliberately gp2, not gp3** (see idempotency note
|
||||
below).
|
||||
- `volume_size = 10` — 10 GiB, the minimum allowed per node.
|
||||
|
||||
### Why this config passes the "No changes" plan check
|
||||
|
||||
The task explicitly requires `terraform plan` to report no drift after apply.
|
||||
OpenSearch domains are notorious for phantom diffs; two choices here prevent that:
|
||||
|
||||
1. **gp2 instead of gp3.** A gp3 volume has `throughput` and `iops` attributes that
|
||||
AWS auto-populates with defaults when you don't specify them. Terraform then sees
|
||||
values in the remote state that aren't in your config and reports a perpetual
|
||||
diff. gp2 has no such tunables, so there's nothing to drift — the cleanest choice
|
||||
for an idempotent lab domain.
|
||||
|
||||
2. **`engine_version` omitted.** When you don't pin the engine version, the argument
|
||||
is treated as computed — AWS picks its current default at create, Terraform
|
||||
records it in state, and because your config says nothing about it, there's
|
||||
nothing to compare against on the next plan. Pinning a version can instead cause
|
||||
drift when AWS applies an automatic minor-version patch.
|
||||
|
||||
Everything else (encryption blocks, endpoint options, auto-tune, off-peak window) is
|
||||
left unset, so the provider treats those as computed defaults rather than managed
|
||||
values — again, no diff.
|
||||
|
||||
### On creation time
|
||||
|
||||
OpenSearch domains provision slowly — the control plane spins up nodes, storage, and
|
||||
networking, which typically takes 10–20 minutes. `terraform apply` blocks until the
|
||||
domain reaches `Active`, so when the command returns the domain is ready. Don't
|
||||
submit until apply completes and the follow-up `plan` is clean.
|
||||
|
||||
## Verify
|
||||
|
||||
```bash
|
||||
aws opensearch describe-domain --domain-name devops-es \
|
||||
--query 'DomainStatus.{Name:DomainName,Processing:Processing,Type:ClusterConfig.InstanceType,Count:ClusterConfig.InstanceCount,Vol:EBSOptions.VolumeType,Size:EBSOptions.VolumeSize}'
|
||||
```
|
||||
|
||||
Expected — name `devops-es`, `Processing: false` (creation finished), instance type
|
||||
`t3.small.search`, count `1`, volume `gp2` size `10`.
|
||||
Reference in New Issue
Block a user