Welcome, and thank you for the opportunity to present my Infrastructure as Code demo.
This solution is structured with a client-facing mindset, prioritizing clarity, automation, scalability, and practical consulting value.
Dévald Tari
The client expects a modular, maintainable, and cloud-native solution to run a one-time web crawler job in AWS.
This solution follows infrastructure-as-code best practices and is presented in the same way I would deliver it to a client.
terraform
and optionally terragrunt
The codebase is split into a reusable module layer and a live/
layer using Terragrunt:
live/<env>/<region>/<component>
.
├── root.hcl
├── live/
│ └── demo/
│ └── eu-central-1/
│ ├── aws-data/
│ ├── vpc-1/
│ ├── eks-1/
│ ├── crawler-job-1/
│ ├── crawler-s3-1/
│ └── github-oidc/
├── modules/
│ ├── aws-data/
│ ├── crawler-job/
│ └── github-oidc/
The root-level Terragrunt configuration dynamically adjusts behavior based on directory structure and account context — making the setup environment- and region-aware without manual repetition.
It includes:
locals {
path_parts = split("/", path_relative_to_include())
environment = local.path_parts[1]
region = local.path_parts[2]
component = local.path_parts[3]
}
remote_state {
backend = "s3"
generate = {
path = "backend.tf"
if_exists = "overwrite"
}
config = {
encrypt = true
region = local.region
key = format("%s/terraform.tfstate", path_relative_to_include())
bucket = format("terraform-states-%s", get_aws_account_id())
dynamodb_table = format("terraform-states-%s", get_aws_account_id())
}
}
generate "provider_aws" {
path = "provider_aws.tf"
if_exists = "overwrite"
contents = <<EOF
provider "aws" {
region = "${local.region}"
default_tags {
tags = {
Environment = "${local.environment}"
Region = "${local.region}"
Component = "${local.component}"
ManagedBy = "terragrunt/terraform"
}
}
}
EOF
}
CI/CD is built with GitHub Actions and OpenID Connect:
The aws-data
module centralizes the retrieval of region-specific AWS metadata for consistent use across all other infrastructure modules.
It provides:
data.aws_region
→ current AWS region name and descriptiondata.aws_availability_zones
→ list of AZ names and zone IDsThis removes duplication, ensures reliability, and keeps modules clean from boilerplate region logic.
The module is easily extendable to include:
data.aws_caller_identity
→ to expose AWS account ID and user context
The github-oidc
module provisions an IAM role that allows GitHub Actions to securely authenticate to AWS without long-lived access keys.
It configures:
Benefits:
The crawler-job
module provisions a one-time Kubernetes Job
on an EKS cluster to run a containerized web crawler.
It encapsulates:
Benefits:
Using nix develop
ensures consistent tools:
terraform
, terragrunt
, kubectl
, awscli
nix develop
shell offers a reproducible environment for hands-on work
terragrunt
commands (e.g. plan
, apply
, destroy
)nix run .#validate
nix run .#apply
can be run outside the nix develop
shell as well
This presentation was written entirely in Org Mode
and exported with ox-reveal
to Reveal.js HTML.