forgejo/terraform/iam.tf

430 lines
11 KiB
Terraform
Raw Normal View History

# 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
}