mirror of
https://github.com/Sea-Haven-Industries/forgejo.git
synced 2026-09-30 12:13:11 +00:00
* feat(terraform): migrate forgejo to HCP Terraform Move the prod host onto workspace forgejo-prod in the After Hours VPC and freeze CDK push deploys so cutover can happen without applying into seahaven-prod. * fix(terraform): restore forgejo.db from the dump tarball Boot restore was copying data/ and repos/ and leaving the sqlite file at the archive root, so a volume restore started Forgejo with no database.
429 lines
11 KiB
HCL
429 lines
11 KiB
HCL
# Exec-role ceiling. CreatePolicy is denied on hcptf-forgejo, so the first
|
|
# apply (as hcptf-bootstrap) creates this policy and later document edits need
|
|
# that same bootstrap window.
|
|
|
|
data "aws_iam_policy_document" "exec_boundary" {
|
|
statement {
|
|
sid = "BackupBuckets"
|
|
effect = "Allow"
|
|
actions = [
|
|
"s3:AbortMultipartUpload",
|
|
"s3:GetBucketLocation",
|
|
"s3:GetBucketVersioning",
|
|
"s3:GetObject",
|
|
"s3:GetObjectVersion",
|
|
"s3:GetObjectVersionAcl",
|
|
"s3:GetObjectVersionForReplication",
|
|
"s3:GetObjectVersionTagging",
|
|
"s3:GetReplicationConfiguration",
|
|
"s3:ListBucket",
|
|
"s3:PutObject",
|
|
"s3:ReplicateDelete",
|
|
"s3:ReplicateObject",
|
|
"s3:ReplicateTags",
|
|
]
|
|
resources = [
|
|
"arn:aws:s3:::${local.backup_bucket_name}",
|
|
"arn:aws:s3:::${local.backup_bucket_name}/*",
|
|
"arn:aws:s3:::${local.replica_bucket_name}",
|
|
"arn:aws:s3:::${local.replica_bucket_name}/*",
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "ForgejoSecrets"
|
|
effect = "Allow"
|
|
actions = ["secretsmanager:GetSecretValue"]
|
|
resources = [
|
|
local.secret_arns.api_token,
|
|
local.secret_arns.github_pat,
|
|
local.secret_arns.gcs_sa_key,
|
|
local.secret_arns.slack_webhook,
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "BackupPrefix"
|
|
effect = "Allow"
|
|
actions = [
|
|
"ssm:GetParameter",
|
|
"ssm:GetParameters",
|
|
]
|
|
resources = [
|
|
"arn:aws:ssm:${var.aws_region}:${local.account_id}:parameter/forgejo/*",
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "SnapshotLifecycle"
|
|
effect = "Allow"
|
|
actions = [
|
|
"ec2:CopySnapshot",
|
|
"ec2:CreateSnapshot",
|
|
"ec2:CreateSnapshots",
|
|
"ec2:CreateTags",
|
|
"ec2:DeleteSnapshot",
|
|
"ec2:DeleteTags",
|
|
"ec2:Describe*",
|
|
"ec2:DisableFastSnapshotRestores",
|
|
"ec2:EnableFastSnapshotRestores",
|
|
"ec2:ModifySnapshotAttribute",
|
|
"ec2:ResetSnapshotAttribute",
|
|
]
|
|
resources = ["*"]
|
|
}
|
|
|
|
statement {
|
|
sid = "VerificationLogs"
|
|
effect = "Allow"
|
|
actions = [
|
|
"logs:CreateLogGroup",
|
|
"logs:CreateLogStream",
|
|
"logs:PutLogEvents",
|
|
]
|
|
resources = [
|
|
"arn:aws:logs:${var.aws_region}:${local.account_id}:log-group:${local.verification_log_group}",
|
|
"arn:aws:logs:${var.aws_region}:${local.account_id}:log-group:${local.verification_log_group}:*",
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "SsmAgentBuckets"
|
|
effect = "Allow"
|
|
actions = ["s3:GetObject"]
|
|
resources = [
|
|
"arn:aws:s3:::aws-ssm-*/*",
|
|
"arn:aws:s3:::aws-windows-downloads-*/*",
|
|
"arn:aws:s3:::amazon-ssm-*/*",
|
|
"arn:aws:s3:::amazon-ssm-packages-*/*",
|
|
"arn:aws:s3:::patch-baseline-snapshot-*/*",
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "SsmManagedInstance"
|
|
effect = "Allow"
|
|
actions = [
|
|
"ssm:DescribeAssociation",
|
|
"ssm:DescribeDocument",
|
|
"ssm:GetDeployablePatchSnapshotForInstance",
|
|
"ssm:GetDocument",
|
|
"ssm:GetManifest",
|
|
"ssm:ListAssociations",
|
|
"ssm:ListInstanceAssociations",
|
|
"ssm:PutComplianceItems",
|
|
"ssm:PutConfigurePackageResult",
|
|
"ssm:PutInventory",
|
|
"ssm:UpdateAssociationStatus",
|
|
"ssm:UpdateInstanceAssociationStatus",
|
|
"ssm:UpdateInstanceInformation",
|
|
]
|
|
resources = ["*"]
|
|
}
|
|
|
|
statement {
|
|
sid = "SsmAgentParameters"
|
|
effect = "Allow"
|
|
actions = [
|
|
"ssm:GetParameter",
|
|
"ssm:GetParameters",
|
|
]
|
|
resources = [
|
|
"arn:aws:ssm:${var.aws_region}::parameter/aws/service/*",
|
|
"arn:aws:ssm:${var.aws_region}:${local.account_id}:parameter/aws/service/*",
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "SsmMessages"
|
|
effect = "Allow"
|
|
actions = [
|
|
"ssmmessages:CreateControlChannel",
|
|
"ssmmessages:CreateDataChannel",
|
|
"ssmmessages:OpenControlChannel",
|
|
"ssmmessages:OpenDataChannel",
|
|
]
|
|
resources = ["*"]
|
|
}
|
|
|
|
statement {
|
|
sid = "Ec2Messages"
|
|
effect = "Allow"
|
|
actions = [
|
|
"ec2messages:AcknowledgeMessage",
|
|
"ec2messages:DeleteMessage",
|
|
"ec2messages:FailMessage",
|
|
"ec2messages:GetEndpoint",
|
|
"ec2messages:GetMessages",
|
|
"ec2messages:SendReply",
|
|
]
|
|
resources = ["*"]
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_policy" "exec_boundary" {
|
|
name = local.boundary_name
|
|
path = "/tf-managed/"
|
|
description = "Permissions boundary for Forgejo exec roles (PLAT-80)."
|
|
policy = data.aws_iam_policy_document.exec_boundary.json
|
|
}
|
|
|
|
data "aws_iam_policy_document" "instance_assume" {
|
|
statement {
|
|
sid = "Ec2Assume"
|
|
effect = "Allow"
|
|
actions = ["sts:AssumeRole"]
|
|
|
|
principals {
|
|
type = "Service"
|
|
identifiers = ["ec2.amazonaws.com"]
|
|
}
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_role" "instance" {
|
|
name = local.instance_role_name
|
|
path = "/tf-managed/"
|
|
assume_role_policy = data.aws_iam_policy_document.instance_assume.json
|
|
permissions_boundary = aws_iam_policy.exec_boundary.arn
|
|
}
|
|
|
|
resource "aws_iam_role_policy_attachment" "instance_ssm" {
|
|
role = aws_iam_role.instance.name
|
|
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
|
|
}
|
|
|
|
data "aws_iam_policy_document" "instance" {
|
|
statement {
|
|
sid = "BackupBucket"
|
|
effect = "Allow"
|
|
actions = [
|
|
"s3:GetBucketLocation",
|
|
"s3:GetObject",
|
|
"s3:ListBucket",
|
|
"s3:PutObject",
|
|
]
|
|
resources = [
|
|
"arn:aws:s3:::${local.backup_bucket_name}",
|
|
"arn:aws:s3:::${local.backup_bucket_name}/*",
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "MirrorSecrets"
|
|
effect = "Allow"
|
|
actions = ["secretsmanager:GetSecretValue"]
|
|
resources = [
|
|
local.secret_arns.api_token,
|
|
local.secret_arns.github_pat,
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "BackupPrefix"
|
|
effect = "Allow"
|
|
actions = ["ssm:GetParameter"]
|
|
resources = [
|
|
"arn:aws:ssm:${var.aws_region}:${local.account_id}:parameter/forgejo/backup-s3-prefix",
|
|
]
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_role_policy" "instance" {
|
|
name = "forgejo-instance"
|
|
role = aws_iam_role.instance.id
|
|
policy = data.aws_iam_policy_document.instance.json
|
|
}
|
|
|
|
resource "aws_iam_instance_profile" "forgejo" {
|
|
name = local.instance_profile_name
|
|
path = "/tf-managed/"
|
|
role = aws_iam_role.instance.name
|
|
}
|
|
|
|
data "aws_iam_policy_document" "dlm_assume" {
|
|
statement {
|
|
sid = "DlmAssume"
|
|
effect = "Allow"
|
|
actions = ["sts:AssumeRole"]
|
|
|
|
principals {
|
|
type = "Service"
|
|
identifiers = ["dlm.amazonaws.com"]
|
|
}
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_role" "dlm" {
|
|
name = local.dlm_role_name
|
|
path = "/tf-managed/"
|
|
assume_role_policy = data.aws_iam_policy_document.dlm_assume.json
|
|
permissions_boundary = aws_iam_policy.exec_boundary.arn
|
|
}
|
|
|
|
resource "aws_iam_role_policy_attachment" "dlm" {
|
|
role = aws_iam_role.dlm.name
|
|
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSDataLifecycleManagerServiceRole"
|
|
}
|
|
|
|
data "aws_iam_policy_document" "replication_assume" {
|
|
statement {
|
|
sid = "S3Assume"
|
|
effect = "Allow"
|
|
actions = ["sts:AssumeRole"]
|
|
|
|
principals {
|
|
type = "Service"
|
|
identifiers = ["s3.amazonaws.com"]
|
|
}
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_role" "replication" {
|
|
name = local.replication_role_name
|
|
path = "/tf-managed/"
|
|
assume_role_policy = data.aws_iam_policy_document.replication_assume.json
|
|
permissions_boundary = aws_iam_policy.exec_boundary.arn
|
|
}
|
|
|
|
data "aws_iam_policy_document" "replication" {
|
|
statement {
|
|
sid = "ReadSource"
|
|
effect = "Allow"
|
|
actions = [
|
|
"s3:GetReplicationConfiguration",
|
|
"s3:ListBucket",
|
|
]
|
|
resources = ["arn:aws:s3:::${local.backup_bucket_name}"]
|
|
}
|
|
|
|
statement {
|
|
sid = "ReadSourceObjects"
|
|
effect = "Allow"
|
|
actions = [
|
|
"s3:GetObjectVersion",
|
|
"s3:GetObjectVersionAcl",
|
|
"s3:GetObjectVersionForReplication",
|
|
"s3:GetObjectVersionTagging",
|
|
]
|
|
resources = ["arn:aws:s3:::${local.backup_bucket_name}/*"]
|
|
}
|
|
|
|
statement {
|
|
sid = "WriteReplica"
|
|
effect = "Allow"
|
|
actions = [
|
|
"s3:ReplicateDelete",
|
|
"s3:ReplicateObject",
|
|
"s3:ReplicateTags",
|
|
]
|
|
resources = ["arn:aws:s3:::${local.replica_bucket_name}/*"]
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_role_policy" "replication" {
|
|
name = "forgejo-s3-replication"
|
|
role = aws_iam_role.replication.id
|
|
policy = data.aws_iam_policy_document.replication.json
|
|
}
|
|
|
|
data "aws_iam_policy_document" "lambda_assume" {
|
|
statement {
|
|
sid = "LambdaAssume"
|
|
effect = "Allow"
|
|
actions = ["sts:AssumeRole"]
|
|
|
|
principals {
|
|
type = "Service"
|
|
identifiers = ["lambda.amazonaws.com"]
|
|
}
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_role" "lambda" {
|
|
name = local.lambda_role_name
|
|
path = "/tf-managed/"
|
|
assume_role_policy = data.aws_iam_policy_document.lambda_assume.json
|
|
permissions_boundary = aws_iam_policy.exec_boundary.arn
|
|
}
|
|
|
|
data "aws_iam_policy_document" "lambda" {
|
|
statement {
|
|
sid = "ReadBackups"
|
|
effect = "Allow"
|
|
actions = [
|
|
"s3:GetObject",
|
|
"s3:ListBucket",
|
|
]
|
|
resources = [
|
|
"arn:aws:s3:::${local.backup_bucket_name}",
|
|
"arn:aws:s3:::${local.backup_bucket_name}/*",
|
|
"arn:aws:s3:::${local.replica_bucket_name}",
|
|
"arn:aws:s3:::${local.replica_bucket_name}/*",
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "VerificationSecrets"
|
|
effect = "Allow"
|
|
actions = ["secretsmanager:GetSecretValue"]
|
|
resources = [
|
|
local.secret_arns.gcs_sa_key,
|
|
local.secret_arns.slack_webhook,
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "Snapshots"
|
|
effect = "Allow"
|
|
actions = ["ec2:DescribeSnapshots"]
|
|
resources = ["*"]
|
|
}
|
|
|
|
statement {
|
|
sid = "Logs"
|
|
effect = "Allow"
|
|
actions = [
|
|
"logs:CreateLogGroup",
|
|
"logs:CreateLogStream",
|
|
"logs:PutLogEvents",
|
|
]
|
|
resources = [
|
|
"arn:aws:logs:${var.aws_region}:${local.account_id}:log-group:${local.verification_log_group}",
|
|
"arn:aws:logs:${var.aws_region}:${local.account_id}:log-group:${local.verification_log_group}:*",
|
|
]
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_role_policy" "lambda" {
|
|
name = "forgejo-backup-verification"
|
|
role = aws_iam_role.lambda.id
|
|
policy = data.aws_iam_policy_document.lambda.json
|
|
}
|
|
|
|
resource "aws_iam_user" "gcs_transfer" {
|
|
name = local.gcs_user_name
|
|
path = "/tf-managed/"
|
|
permissions_boundary = aws_iam_policy.exec_boundary.arn
|
|
}
|
|
|
|
data "aws_iam_policy_document" "gcs_transfer" {
|
|
statement {
|
|
sid = "ReadBackups"
|
|
effect = "Allow"
|
|
actions = [
|
|
"s3:GetObject",
|
|
"s3:ListBucket",
|
|
]
|
|
resources = [
|
|
"arn:aws:s3:::${local.backup_bucket_name}",
|
|
"arn:aws:s3:::${local.backup_bucket_name}/*",
|
|
]
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_user_policy" "gcs_transfer" {
|
|
name = "forgejo-gcs-transfer"
|
|
user = aws_iam_user.gcs_transfer.name
|
|
policy = data.aws_iam_policy_document.gcs_transfer.json
|
|
}
|