Skip to content

Commit 698e3e3

Browse files
committed
Allow IAM bootstrap without AMI and add snapshot permissions
1 parent 4b2399e commit 698e3e3

File tree

5 files changed

+29
-12
lines changed

5 files changed

+29
-12
lines changed

AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ Bootstrap (local):
5757
- `RULES=../nix/nix-secrets/secrets.nix agenix -d homelab-admin.age -i ~/.ssh/id_ed25519`
5858
- OpenTofu env:
5959
- `TF_VAR_aws_region=eu-central-1`
60-
- `TF_VAR_ami_id=ami-...`
61-
- `TF_VAR_ssh_public_key="$(cat ~/.ssh/id_ed25519.pub)"`
60+
- `TF_VAR_ami_id=ami-...` (empty string skips instance creation)
61+
- `TF_VAR_ssh_public_key="$(cat ~/.ssh/id_ed25519.pub)"` (required when ami_id is set)
6262
- Run `tofu init` + `tofu apply` in `infra/opentofu/aws`.
6363
- After apply, update CI secrets from outputs:
6464
- `tofu output -raw access_key_id``clawdinator-image-uploader-access-key-id.age`

infra/opentofu/aws/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ Usage:
1010
- export AWS_SECRET_ACCESS_KEY=...
1111
- export AWS_REGION=eu-central-1
1212
- export TF_VAR_aws_region=eu-central-1
13-
- export TF_VAR_ami_id=ami-...
14-
- export TF_VAR_ssh_public_key="$(cat ~/.ssh/id_ed25519.pub)"
13+
- export TF_VAR_ami_id=ami-... # leave empty to skip instance creation
14+
- export TF_VAR_ssh_public_key="$(cat ~/.ssh/id_ed25519.pub)" # required when ami_id is set
1515
- tofu init
1616
- tofu apply
1717

infra/opentofu/aws/main.tf

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ provider "aws" {
44

55
locals {
66
tags = merge(var.tags, { "app" = "clawdinator" })
7+
instance_enabled = var.ami_id != ""
78
}
89

910
resource "aws_s3_bucket" "image_bucket" {
@@ -121,8 +122,12 @@ data "aws_iam_policy_document" "ami_importer" {
121122
sid = "ImportImage"
122123
actions = [
123124
"ec2:ImportImage",
125+
"ec2:ImportSnapshot",
126+
"ec2:DescribeImportSnapshotTasks",
124127
"ec2:DescribeImportImageTasks",
125128
"ec2:DescribeImages",
129+
"ec2:DescribeSnapshots",
130+
"ec2:RegisterImage",
126131
"ec2:CreateTags"
127132
]
128133
resources = ["*"]
@@ -153,51 +158,57 @@ data "aws_subnets" "default" {
153158
}
154159

155160
resource "aws_key_pair" "operator" {
161+
count = local.instance_enabled ? 1 : 0
156162
key_name = "clawdinator-operator"
157163
public_key = var.ssh_public_key
158164
tags = local.tags
159165
}
160166

161167
resource "aws_security_group" "clawdinator" {
168+
count = local.instance_enabled ? 1 : 0
162169
name = "clawdinator"
163170
description = "CLAWDINATOR access"
164171
vpc_id = data.aws_vpc.default.id
165172
tags = local.tags
166173
}
167174

168175
resource "aws_security_group_rule" "ssh_ingress" {
176+
count = local.instance_enabled ? 1 : 0
169177
type = "ingress"
170-
security_group_id = aws_security_group.clawdinator.id
178+
security_group_id = aws_security_group.clawdinator[0].id
171179
from_port = 22
172180
to_port = 22
173181
protocol = "tcp"
174182
cidr_blocks = var.allowed_cidrs
175183
}
176184

177185
resource "aws_security_group_rule" "gateway_ingress" {
186+
count = local.instance_enabled ? 1 : 0
178187
type = "ingress"
179-
security_group_id = aws_security_group.clawdinator.id
188+
security_group_id = aws_security_group.clawdinator[0].id
180189
from_port = 18789
181190
to_port = 18789
182191
protocol = "tcp"
183192
cidr_blocks = var.allowed_cidrs
184193
}
185194

186195
resource "aws_security_group_rule" "egress" {
196+
count = local.instance_enabled ? 1 : 0
187197
type = "egress"
188-
security_group_id = aws_security_group.clawdinator.id
198+
security_group_id = aws_security_group.clawdinator[0].id
189199
from_port = 0
190200
to_port = 0
191201
protocol = "-1"
192202
cidr_blocks = ["0.0.0.0/0"]
193203
}
194204

195205
resource "aws_instance" "clawdinator" {
206+
count = local.instance_enabled ? 1 : 0
196207
ami = var.ami_id
197208
instance_type = var.instance_type
198209
subnet_id = element(data.aws_subnets.default.ids, 0)
199-
vpc_security_group_ids = [aws_security_group.clawdinator.id]
200-
key_name = aws_key_pair.operator.key_name
210+
vpc_security_group_ids = [aws_security_group.clawdinator[0].id]
211+
key_name = aws_key_pair.operator[0].key_name
201212
associate_public_ip_address = true
202213

203214
tags = merge(local.tags, {

infra/opentofu/aws/outputs.tf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@ output "secret_access_key" {
2424
}
2525

2626
output "instance_id" {
27-
value = aws_instance.clawdinator.id
27+
value = local.instance_enabled ? aws_instance.clawdinator[0].id : null
2828
description = "CLAWDINATOR instance ID."
2929
}
3030

3131
output "instance_public_ip" {
32-
value = aws_instance.clawdinator.public_ip
32+
value = local.instance_enabled ? aws_instance.clawdinator[0].public_ip : null
3333
description = "CLAWDINATOR public IP."
3434
}
3535

3636
output "instance_public_dns" {
37-
value = aws_instance.clawdinator.public_dns
37+
value = local.instance_enabled ? aws_instance.clawdinator[0].public_dns : null
3838
description = "CLAWDINATOR public DNS."
3939
}

infra/opentofu/aws/variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ variable "tags" {
2424
variable "ami_id" {
2525
description = "AMI ID for CLAWDINATOR instances."
2626
type = string
27+
default = ""
2728
}
2829

2930
variable "instance_name" {
@@ -41,6 +42,11 @@ variable "instance_type" {
4142
variable "ssh_public_key" {
4243
description = "SSH public key for the CLAWDINATOR operator."
4344
type = string
45+
default = ""
46+
validation {
47+
condition = var.ami_id == "" || length(var.ssh_public_key) > 0
48+
error_message = "ssh_public_key is required when ami_id is set."
49+
}
4450
}
4551

4652
variable "allowed_cidrs" {

0 commit comments

Comments
 (0)