# 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 EC2 permissions boundary for syslog-server (PLAT-78)." 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 }