2026-09-16 16:21:28 -04:00
# Per-workload permissions boundary. Created on the first (bootstrap) apply.
# The scoped apply role denies iam:CreatePolicy / CreatePolicyVersion, so later
# edits to this document need the hcptf-bootstrap window.
data " aws_iam_policy_document " " exec_boundary " {
2026-09-16 16:23:22 -04:00
# checkov:skip=CKV_AWS_108: Boundary is an upper bound, not a grant. DescribeLogGroups requires Resource=*. Bucket, secret, DLQ, and Athena are ARN-prefixed.
# checkov:skip=CKV_AWS_109: Boundary is an upper bound, not a grant. No IAM permission-management actions.
# checkov:skip=CKV_AWS_111: AWS requires Resource=* for logs:DescribeLogGroups. Exports, secrets, DLQ, and Athena are ARN-pinned.
2026-09-16 16:21:28 -04:00
statement {
sid = " CloudWatchLogsWrite "
effect = " Allow "
actions = [
" logs:CreateLogGroup " ,
" logs:CreateLogStream " ,
" logs:PutLogEvents " ,
" logs:DescribeLogStreams " ,
]
resources = [
" arn:aws:logs: ${ var . aws_region } : ${ local . account_id } :log-group:/aws/lambda* " ,
]
}
statement {
sid = " CloudWatchLogsDescribe "
effect = " Allow "
actions = [ " logs:DescribeLogGroups " ]
resources = [ " * " ]
}
statement {
sid = " ExportsBucket "
effect = " Allow "
actions = [
" s3:GetObject " ,
" s3:PutObject " ,
" s3:DeleteObject " ,
" s3:AbortMultipartUpload " ,
" s3:ListBucket " ,
" s3:GetBucketLocation " ,
]
resources = [
" arn:aws:s3::: ${ local . exports_bucket_name } " ,
" arn:aws:s3::: ${ local . exports_bucket_name } /* " ,
]
}
statement {
sid = " Secrets "
effect = " Allow "
actions = [
" secretsmanager:GetSecretValue " ,
" secretsmanager:DescribeSecret " ,
]
resources = [
" arn:aws:secretsmanager: ${ var . aws_region } : ${ local . account_id } :secret:apm-wo-analysis/* " ,
]
}
statement {
sid = " SsmParams "
effect = " Allow "
actions = [
" ssm:GetParameter " ,
" ssm:GetParameters " ,
]
resources = [
" arn:aws:ssm: ${ var . aws_region } : ${ local . account_id } :parameter ${ local . ssm_prefix } /* " ,
]
}
statement {
sid = " InvokeSlackPost "
effect = " Allow "
actions = [
" lambda:InvokeFunction " ,
]
resources = [
" arn:aws:lambda: ${ var . aws_region } : ${ local . account_id } :function:apm-wo-analysis-slack-post " ,
]
}
statement {
sid = " ClassifierDlq "
effect = " Allow "
actions = [
" sqs:SendMessage " ,
]
resources = [
" arn:aws:sqs: ${ var . aws_region } : ${ local . account_id } :apm-wo-analysis-classifier-dlq " ,
]
}
statement {
sid = " AthenaQuery "
effect = " Allow "
actions = [
" athena:StartQueryExecution " ,
" athena:StopQueryExecution " ,
" athena:GetQueryExecution " ,
" athena:GetQueryResults " ,
" athena:GetWorkGroup " ,
]
resources = [
" arn:aws:athena: ${ var . aws_region } : ${ local . account_id } :workgroup/ ${ local . athena_workgroup } " ,
]
}
statement {
sid = " AthenaList "
effect = " Allow "
actions = [ " athena:ListWorkGroups " ]
resources = [ " * " ]
}
statement {
sid = " GlueRead "
effect = " Allow "
actions = [
" glue:GetDatabase " ,
" glue:GetDatabases " ,
" glue:GetTable " ,
" glue:GetTables " ,
" glue:GetPartition " ,
" glue:GetPartitions " ,
]
resources = [
" arn:aws:glue: ${ var . aws_region } : ${ local . account_id } :catalog " ,
" arn:aws:glue: ${ var . aws_region } : ${ local . account_id } :database/ ${ local . glue_database } " ,
" arn:aws:glue: ${ var . aws_region } : ${ local . account_id } :table/ ${ local . glue_database } /* " ,
]
}
statement {
sid = " SsmManagedInstance "
effect = " Allow "
actions = [
" ssm:DescribeAssociation " ,
" ssm:GetDeployablePatchSnapshotForInstance " ,
" ssm:GetDocument " ,
" ssm:DescribeDocument " ,
" ssm:GetManifest " ,
" ssm:GetParameter " ,
" ssm:GetParameters " ,
" ssm:GetParametersByPath " ,
" ssm:ListAssociations " ,
" ssm:ListInstanceAssociations " ,
" ssm:UpdateAssociationStatus " ,
" ssm:UpdateInstanceAssociationStatus " ,
" ssm:UpdateInstanceInformation " ,
" ssmmessages:CreateControlChannel " ,
" ssmmessages:CreateDataChannel " ,
" ssmmessages:OpenControlChannel " ,
" ssmmessages:OpenDataChannel " ,
" ec2messages:AcknowledgeMessage " ,
" ec2messages:DeleteMessage " ,
" ec2messages:FailMessage " ,
" ec2messages:GetEndpoint " ,
" ec2messages:GetMessages " ,
" ec2messages:SendReply " ,
" ec2:DescribeInstanceStatus " ,
]
resources = [ " * " ]
}
statement {
sid = " SsmAgentS3 "
effect = " Allow "
actions = [
" s3:GetObject " ,
]
resources = [
" arn:aws:s3:::aws-ssm-*/* " ,
" arn:aws:s3:::amazon-ssm-*/* " ,
" arn:aws:s3:::amazon-ssm-packages-*/* " ,
" arn:aws:s3:::patch-baseline-snapshot-*/* " ,
]
}
statement {
sid = " DlmSnapshots "
effect = " Allow "
actions = [
" ec2:CreateSnapshot " ,
" ec2:CreateSnapshots " ,
" ec2:DeleteSnapshot " ,
" ec2:DescribeInstances " ,
" ec2:DescribeVolumes " ,
" ec2:DescribeSnapshots " ,
" ec2:EnableFastSnapshotRestores " ,
" ec2:DescribeFastSnapshotRestores " ,
" ec2:DisableFastSnapshotRestores " ,
" ec2:CopySnapshot " ,
" ec2:ModifySnapshotAttribute " ,
" ec2:DescribeSnapshotAttribute " ,
" ec2:DescribeTags " ,
" ec2:CreateTags " ,
" ec2:DeleteTags " ,
]
resources = [ " * " ]
}
statement {
sid = " DlmKms "
effect = " Allow "
actions = [
" kms:CreateGrant " ,
" kms:DescribeKey " ,
" kms:GenerateDataKeyWithoutPlaintext " ,
" kms:ReEncryptFrom " ,
" kms:ReEncryptTo " ,
" kms:ListGrants " ,
]
resources = [
" arn:aws:kms: ${ var . aws_region } : ${ local . account_id } :key/* " ,
]
}
}
resource " aws_iam_policy " " exec_boundary " {
name = " apm-wo-analysis-exec-boundary "
path = " /tf-managed/ "
description = " Per-workload permissions boundary for apm-wo-analysis (PLAT-75). "
policy = data . aws_iam_policy_document . exec_boundary . json
}