Skip to content

Commit 37a392d

Browse files
authored
feat!: Update dependencies, replace Dependabot with Renovate, and simplify S3 architecture (#14)
1 parent 73f826a commit 37a392d

19 files changed

Lines changed: 170 additions & 264 deletions

.github/dependabot.yml

Lines changed: 0 additions & 29 deletions
This file was deleted.

.github/renovate.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
3+
"extends": [
4+
"config:recommended",
5+
":semanticCommits"
6+
],
7+
"enabledManagers": [
8+
"github-actions",
9+
"terraform"
10+
],
11+
"reviewersFromCodeOwners": true,
12+
"dependencyDashboard": true,
13+
"commitMessageLowerCase": "never",
14+
"minimumReleaseAge": "30 days"
15+
}

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/antonbabenko/pre-commit-terraform
3-
rev: v1.90.0
3+
rev: v1.105.0
44
hooks:
55
- id: terraform_fmt
66
- id: terraform_validate

CLAUDE.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
Terraform module that deploys Plex Media Server on AWS using EC2 Spot Instances with S3-backed media storage (s3fs-fuse) and Docker. Runs Plex as a systemd-managed Docker container on Amazon Linux 2.
8+
9+
## Common Commands
10+
11+
```bash
12+
# Format all Terraform files
13+
terraform fmt -recursive
14+
15+
# Validate configuration
16+
terraform validate
17+
18+
# Run all pre-commit hooks (formatting, validation, docs, linting)
19+
pre-commit run -a
20+
21+
# Generate/update README documentation tables
22+
terraform-docs markdown . --lockfile=false
23+
```
24+
25+
There are no automated tests. Validation is done via `terraform validate` and `tflint` through pre-commit hooks.
26+
27+
## Architecture
28+
29+
The module provisions a complete single-instance Plex deployment:
30+
31+
- **VPC** (`vpc.tf`): `10.0.0.0/16` CIDR (stored as `local.vpc_cidr`), 3 public subnets only
32+
- **EC2** (`autoscaling.tf`): Single Spot instance via ASG with rolling refresh, Amazon Linux 2 AMI
33+
- **Storage** (`s3.tf`): Single S3 storage bucket with folder-based library prefixes + one DB backup bucket, all using INTELLIGENT_TIERING
34+
- **IAM** (`iam.tf`): Instance profile with S3 and SSM access
35+
- **Security** (`sg.tf`): Port 32400 open for Plex access
36+
- **Secrets** (`ssm.tf`): Plex claim token stored as SecureString in SSM Parameter Store
37+
- **Bootstrap** (`templates/userdata.sh`): Installs Docker/s3fs, mounts S3 buckets, starts Plex container as systemd service
38+
39+
Subnet CIDRs are computed directly in `vpc.tf` using `cidrsubnets()`. VPC CIDR is defined once in `locals.tf`.
40+
41+
## Key Dependencies
42+
43+
- **Terraform**: `>= 1.5.7`
44+
- **AWS Provider**: `>= 6.29`
45+
- **Public modules**: `terraform-aws-modules/vpc/aws ~> 6.6`, `terraform-aws-modules/autoscaling/aws ~> 9.2`, `terraform-aws-modules/s3-bucket/aws ~> 5.10`
46+
47+
## Conventions
48+
49+
- **Commits**: Conventional Commits format required. Allowed types: `fix`, `feat`, `docs`, `ci`, `chore`, `revert`. Subject must start with uppercase.
50+
- **Releases**: Semantic Release on `master` branch, triggered by pushes to `.tf`, `.py`, `.tpl` files.
51+
- **PR titles**: Must follow Conventional Commits (enforced by CI). Scopes: `deps`, plus Jira-style project keys.
52+
- **Pre-commit hooks**: `terraform_fmt`, `terraform_validate`, `terraform_docs`, `terraform_tflint` (via `antonbabenko/pre-commit-terraform`).
53+
- **Code ownership**: `@zahorniak` is default CODEOWNER.
54+
55+
## Coding Guidelines
56+
57+
- Don't specify Terraform/AWS defaults explicitly (e.g., gp3 baseline IOPS, `protect_from_scale_in = false`). Only set values that differ from defaults.
58+
- `templates/userdata.sh` uses Terraform `templatefile()` variables — never hardcode values available as variables (e.g., region).
59+
- IMDSv2 is enforced (`http_tokens = "required"`). Userdata already uses v2 token flow.
60+
- The `plex_claim_token` variable is marked `sensitive = true`.
61+
- The module has no `outputs.tf` — it currently exposes no outputs.

README.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,28 @@ To avoid scanning of the files in the S3 bucket (meaning additional S3 api reque
3030
* Remove old cache files every week
3131
* Upgrade media analysis during maintenance
3232

33-
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
33+
<!-- BEGIN_TF_DOCS -->
3434
## Requirements
3535

3636
| Name | Version |
3737
|------|---------|
38-
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.7 |
39-
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.30 |
38+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
39+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.29 |
4040

4141
## Providers
4242

4343
| Name | Version |
4444
|------|---------|
45-
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.30 |
45+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.29 |
4646

4747
## Modules
4848

4949
| Name | Source | Version |
5050
|------|--------|---------|
51-
| <a name="module_plex_autoscaling"></a> [plex\_autoscaling](#module\_plex\_autoscaling) | terraform-aws-modules/autoscaling/aws | ~> 7.7 |
52-
| <a name="module_s3_plex_db"></a> [s3\_plex\_db](#module\_s3\_plex\_db) | terraform-aws-modules/s3-bucket/aws | ~> 3.3 |
53-
| <a name="module_s3_plex_storage"></a> [s3\_plex\_storage](#module\_s3\_plex\_storage) | terraform-aws-modules/s3-bucket/aws | ~> 3.3 |
54-
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.9 |
51+
| <a name="module_plex_autoscaling"></a> [plex\_autoscaling](#module\_plex\_autoscaling) | terraform-aws-modules/autoscaling/aws | ~> 9.2 |
52+
| <a name="module_s3_plex_db"></a> [s3\_plex\_db](#module\_s3\_plex\_db) | terraform-aws-modules/s3-bucket/aws | ~> 5.10 |
53+
| <a name="module_s3_plex_storage"></a> [s3\_plex\_storage](#module\_s3\_plex\_storage) | terraform-aws-modules/s3-bucket/aws | ~> 5.10 |
54+
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.6 |
5555

5656
## Resources
5757

@@ -72,10 +72,10 @@ To avoid scanning of the files in the S3 bucket (meaning additional S3 api reque
7272
| <a name="input_force_destroy"></a> [force\_destroy](#input\_force\_destroy) | Force destroy the S3 bucket | `bool` | `false` | no |
7373
| <a name="input_instance_storage_size"></a> [instance\_storage\_size](#input\_instance\_storage\_size) | Size for EC2 EBS root volume | `number` | `30` | no |
7474
| <a name="input_instance_type"></a> [instance\_type](#input\_instance\_type) | Type of EC2 instance | `string` | `"t3a.micro"` | no |
75-
| <a name="input_plex_claim_token"></a> [plex\_claim\_token](#input\_plex\_claim\_token) | Token to claim your plex media server. You can get this by going to https://www.plex.tv/claim. | `string` | n/a | yes |
76-
| <a name="input_plex_libraries"></a> [plex\_libraries](#input\_plex\_libraries) | List of Plex libraries | `list(string)` | n/a | yes |
75+
| <a name="input_plex_claim_token"></a> [plex\_claim\_token](#input\_plex\_claim\_token) | Token to claim your plex media server. You can get this by going to https://www.plex.tv/claim. | `string` | n/a | yes |
76+
| <a name="input_plex_libraries"></a> [plex\_libraries](#input\_plex\_libraries) | List of Plex library folder names (created as prefixes inside a single S3 storage bucket) | `list(string)` | n/a | yes |
7777

7878
## Outputs
7979

8080
No outputs.
81-
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
81+
<!-- END_TF_DOCS -->

autoscaling.tf

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
11
module "plex_autoscaling" {
22
source = "terraform-aws-modules/autoscaling/aws"
3-
version = "~> 7.7"
4-
5-
name = "plex"
6-
use_name_prefix = true
7-
ignore_desired_capacity_changes = true
8-
min_size = 1
9-
max_size = 1
10-
desired_capacity = 1
11-
wait_for_capacity_timeout = 0
12-
health_check_type = "EC2"
13-
vpc_zone_identifier = module.vpc.public_subnets
14-
instance_initiated_shutdown_behavior = "terminate"
15-
protect_from_scale_in = false
3+
version = "~> 9.2"
164

5+
name = "plex"
6+
use_name_prefix = true
7+
ignore_desired_capacity_changes = true
8+
min_size = 1
9+
max_size = 1
10+
desired_capacity = 1
11+
wait_for_capacity_timeout = 0
12+
health_check_type = "EC2"
13+
vpc_zone_identifier = module.vpc.public_subnets
1714
instance_refresh = {
1815
strategy = "Rolling"
1916
preferences = {
20-
checkpoint_delay = 600
21-
checkpoint_percentages = [35, 70, 100]
2217
instance_warmup = 30
23-
min_healthy_percentage = 50
18+
min_healthy_percentage = 0
2419
}
2520
}
2621

@@ -32,9 +27,11 @@ module "plex_autoscaling" {
3227

3328
user_data = base64encode(templatefile("${path.module}/templates/userdata.sh",
3429
{
35-
BUCKETS = local.buckets,
36-
BUCKET_FSTAB_STRING = local.bucket_fstab_string
37-
CONFIG_BUCKET = module.s3_plex_db.s3_bucket_id
30+
STORAGE_BUCKET = module.s3_plex_storage.s3_bucket_id
31+
CONFIG_BUCKET = module.s3_plex_db.s3_bucket_id
32+
LIBRARIES = var.plex_libraries
33+
AWS_REGION = var.aws_region
34+
CLAIM_TOKEN_SHA256 = sha256(var.plex_claim_token)
3835
}
3936
))
4037

@@ -51,8 +48,6 @@ module "plex_autoscaling" {
5148
encrypted = true
5249
volume_size = var.instance_storage_size
5350
volume_type = "gp3"
54-
iops = 3000
55-
throughput = 125
5651
}
5752
}
5853
]
@@ -62,27 +57,18 @@ module "plex_autoscaling" {
6257
iam_role_path = "/ec2/"
6358

6459
iam_role_policies = {
65-
AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore",
66-
AmazonEC2ContainerServiceforEC2Role = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role",
67-
S3Access = aws_iam_policy.plex_server.arn
68-
}
69-
70-
capacity_reservation_specification = {
71-
capacity_reservation_preference = "open"
60+
AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore",
61+
S3Access = aws_iam_policy.plex_server.arn
7262
}
7363

7464
instance_market_options = {
7565
market_type = "spot"
7666
}
7767

78-
maintenance_options = {
79-
auto_recovery = "default"
80-
}
81-
8268
metadata_options = {
8369
http_endpoint = "enabled"
84-
http_tokens = "optional"
85-
http_put_response_hop_limit = 32
70+
http_tokens = "required"
71+
http_put_response_hop_limit = 2
8672
instance_metadata_tags = "enabled"
8773
}
8874

data.tf

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,7 @@ data "aws_ami" "plex" {
77
owners = ["amazon"]
88

99
filter {
10-
name = "name"
11-
# values = ["${var.packer_ami_prefix}-*"]
10+
name = "name"
1211
values = ["amzn2-ami-hvm-*-x86_64-ebs"]
1312
}
14-
15-
filter {
16-
name = "architecture"
17-
values = ["x86_64"]
18-
}
1913
}

examples/complete/main.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module "plex" {
22
source = "../../"
3-
plex_libraries = var.plex_libraries
4-
plex_claim_token = var.plex_claim_token
3+
plex_libraries = ["movies", "tv"]
4+
plex_claim_token = "claim-KL7s1QvWn_5xdhx4uyJv"
55
force_destroy = true
66
}

examples/complete/variables.tf

Lines changed: 0 additions & 9 deletions
This file was deleted.

examples/complete/versions.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
terraform {
2-
required_version = ">= 1.3.7"
2+
required_version = ">= 1.5.7"
33
required_providers {
44
aws = {
55
source = "hashicorp/aws"
6-
version = ">= 4.30"
6+
version = ">= 6.29"
77
}
88
}
99
}

0 commit comments

Comments
 (0)