# Instance 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 agent APIs require Resource=*. Secret reads are ARN-scoped. statement { sid = "SecretsRead" effect = "Allow" actions = [ "secretsmanager:GetSecretValue", ] resources = [ var.smb_password_secret_arn, var.filebrowser_password_secret_arn, ] } 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}:${data.aws_caller_identity.current.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 agent APIs require Resource=*. Secret reads are ARN-scoped. name = local.boundary_name path = "/tf-managed/" description = "EC2 permissions boundary for file-share." 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_secrets" { statement { sid = "SecretsRead" effect = "Allow" actions = [ "secretsmanager:GetSecretValue", ] resources = [ var.smb_password_secret_arn, var.filebrowser_password_secret_arn, ] } } resource "aws_iam_role_policy" "instance_secrets" { name = "file-share-secrets" role = aws_iam_role.instance.id policy = data.aws_iam_policy_document.instance_secrets.json } resource "aws_iam_instance_profile" "this" { name = local.instance_profile_name path = "/tf-managed/" role = aws_iam_role.instance.name }