eleven / messenger Public

Clone
git clone https://amadan.net/eleven/messenger

Plain git — no account needed to clone.

Download

Download this file

1# πŸ€– The dev box: one Graviton instance for the hibernation-activator proof
2# (#550 Part 7's "minimum viable" shape β€” the ASG comes later; one pet
3# instance is enough to prove wake/sleep on real AWS metal). It reads the
4# instances bucket via an INSTANCE ROLE β€” no AWS keys ever land on the box.
5
6data "aws_ami" "al2023_arm" {
7 most_recent = true
8 owners = ["amazon"]
9
10 filter {
11 name = "name"
12 values = ["al2023-ami-2023*-arm64"]
13 }
14
15 filter {
16 name = "architecture"
17 values = ["arm64"]
18 }
19}
20
21resource "aws_key_pair" "dev_box" {
22 key_name = "eleven-dev-box"
23 public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILReNBCz+nwYvJ7x/RfgW/kbvSFe3pzPhOBM1SOqbjSg eleven-dev-box"
24}
25
26variable "ssh_ingress_cidr" {
27 description = "Where SSH is allowed from (the operator's current IP/32)"
28 type = string
29 default = "109.255.206.133/32"
30}
31
32resource "aws_security_group" "dev_box" {
33 name = "eleven-dev-box"
34 description = "dev activator box: ssh from the operator, web open"
35
36 ingress {
37 description = "ssh (operator only)"
38 from_port = 22
39 to_port = 22
40 protocol = "tcp"
41 cidr_blocks = [var.ssh_ingress_cidr]
42 }
43
44 ingress {
45 description = "http/https (autocert + serving, for when DNS points here)"
46 from_port = 80
47 to_port = 80
48 protocol = "tcp"
49 cidr_blocks = ["0.0.0.0/0"]
50 }
51
52 ingress {
53 description = "https"
54 from_port = 443
55 to_port = 443
56 protocol = "tcp"
57 cidr_blocks = ["0.0.0.0/0"]
58 }
59
60 egress {
61 from_port = 0
62 to_port = 0
63 protocol = "-1"
64 cidr_blocks = ["0.0.0.0/0"]
65 }
66}
67
68# The box's identity: object-rw on the instances bucket only, via instance
69# profile β€” the credential-free path every later box in the pool follows.
70resource "aws_iam_role" "dev_box" {
71 name = "eleven-dev-box"
72
73 assume_role_policy = jsonencode({
74 Version = "2012-10-17"
75 Statement = [{
76 Action = "sts:AssumeRole"
77 Effect = "Allow"
78 Principal = { Service = "ec2.amazonaws.com" }
79 }]
80 })
81}
82
83data "aws_iam_policy_document" "dev_box" {
84 statement {
85 sid = "ListInstancesBucket"
86 actions = ["s3:ListBucket", "s3:ListBucketVersions"]
87 resources = [aws_s3_bucket.state["instances"].arn]
88 }
89
90 statement {
91 sid = "ReadWriteInstanceObjects"
92 actions = [
93 "s3:GetObject",
94 "s3:PutObject",
95 "s3:DeleteObject",
96 "s3:DeleteObjectVersion",
97 ]
98 resources = ["${aws_s3_bucket.state["instances"].arn}/*"]
99 }
100}
101
102resource "aws_iam_role_policy" "dev_box" {
103 name = "eleven-dev-box-instances-bucket"
104 role = aws_iam_role.dev_box.id
105 policy = data.aws_iam_policy_document.dev_box.json
106}
107
108resource "aws_iam_instance_profile" "dev_box" {
109 name = "eleven-dev-box"
110 role = aws_iam_role.dev_box.name
111}
112
113resource "aws_instance" "dev_box" {
114 ami = data.aws_ami.al2023_arm.id
115 instance_type = "t4g.small"
116 key_name = aws_key_pair.dev_box.key_name
117 vpc_security_group_ids = [aws_security_group.dev_box.id]
118 iam_instance_profile = aws_iam_instance_profile.dev_box.name
119
120 # The instance role's credentials are served by IMDS, so require IMDSv2's
121 # session tokens: an SSRF or misconfigured proxy on the box can't read the
122 # role credentials with a bare GET. Hop limit stays at the default 1 β€”
123 # nothing here runs in containers.
124 metadata_options {
125 http_endpoint = "enabled"
126 http_tokens = "required"
127 }
128
129 # encrypted forces a replacement of the original (unencrypted) volume β€”
130 # apply with -replace=aws_instance.dev_box; the box is a disposable pet
131 # (state parks in S3, that's the whole point of the activator proof).
132 root_block_device {
133 volume_size = 20
134 volume_type = "gp3"
135 encrypted = true
136 }
137
138 tags = {
139 Name = "eleven-dev-box"
140 }
141}
142
143output "dev_box_ip" {
144 value = aws_instance.dev_box.public_ip
145}
146