syslog-server/terraform/iam.tf
Adam Moussa 2b12aba50e
feat(infra): archive UniFi All Traffic to S3 via Vector (PLAT-206) (#41)
Replace the public rsyslog-to-CloudWatch collector with Vector over a
prod 10.40 IPsec VGW, Firehose, 90-day S3, Glue, and Athena.
2026-09-17 18:48:25 +00:00

194 lines
5 KiB
HCL

# Instance (and Firehose delivery role) permissions boundary.
# The scoped apply role denies iam:CreatePolicy / CreatePolicyVersion,
# so later edits to this document need the hcptf-bootstrap window.
data "aws_iam_policy_document" "instance_boundary" {
# checkov:skip=CKV_AWS_111: SSM managed policy requires Resource=* for ssmmessages and describe APIs. Firehose and S3 writes are ARN-prefixed.
statement {
sid = "FirehosePut"
effect = "Allow"
actions = [
"firehose:PutRecord",
"firehose:PutRecordBatch",
]
resources = [
"arn:aws:firehose:${var.aws_region}:${local.account_id}:deliverystream/${local.firehose_name}",
]
}
statement {
sid = "S3Archive"
effect = "Allow"
actions = [
"s3:AbortMultipartUpload",
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:PutObject",
"s3:DeleteObject",
]
resources = [
"arn:aws:s3:::${local.bucket_name}",
"arn:aws:s3:::${local.bucket_name}/*",
]
}
statement {
sid = "CloudWatchMetrics"
effect = "Allow"
actions = [
"cloudwatch:PutMetricData",
]
resources = ["*"]
}
statement {
sid = "Ec2DescribeForAgent"
effect = "Allow"
actions = [
"ec2:DescribeTags",
"ec2:DescribeVolumes",
"ec2:DescribeInstances",
]
resources = ["*"]
}
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:GetDeployablePatchSnapshotForInstance",
"ssm:GetDocument",
"ssm:DescribeDocument",
"ssm:GetManifest",
"ssm:ListAssociations",
"ssm:ListInstanceAssociations",
"ssm:PutInventory",
"ssm:PutComplianceItems",
"ssm:PutConfigurePackageResult",
"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" "instance_boundary" {
# checkov:skip=CKV_AWS_111: SSM managed policy requires Resource=* for ssmmessages and describe APIs. Firehose and S3 writes are ARN-prefixed.
name = local.boundary_name
path = "/tf-managed/"
description = "Per-workload permissions boundary for syslog-server EC2 and Firehose (PLAT-206)."
policy = data.aws_iam_policy_document.instance_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.instance_boundary.arn
tags = {
Name = local.instance_role_name
}
}
resource "aws_iam_role_policy_attachment" "ssm" {
role = aws_iam_role.instance.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
data "aws_iam_policy_document" "instance_firehose" {
statement {
sid = "FirehosePut"
effect = "Allow"
actions = [
"firehose:PutRecord",
"firehose:PutRecordBatch",
]
resources = [
"arn:aws:firehose:${var.aws_region}:${local.account_id}:deliverystream/${local.firehose_name}",
]
}
}
resource "aws_iam_role_policy" "instance_firehose" {
name = "firehose-put"
role = aws_iam_role.instance.id
policy = data.aws_iam_policy_document.instance_firehose.json
}
resource "aws_iam_instance_profile" "this" {
name = local.instance_profile_name
path = "/tf-managed/"
role = aws_iam_role.instance.name
}