2026-09-17 18:48:25 +00:00
# HCP plan/apply roles for syslog-server-prod (PLAT-78 / PLAT-206).
2026-09-16 21:29:43 +00:00
# Copy of seahaven-org-baseline/examples/hcptf-workspace-iam/hcp_iam.tf.example
# with the syslog-server EC2 service set. Create, do not import.
#
# Live seahaven-hcptf-iam-management DenySelfMutation blocks DetachRolePolicy
# and PutRolePolicy on hcptf-* (including this role). First-apply sequence:
# 1. seahaven-org-baseline scripts/create-hcptf-bootstrap-roles.sh
# --account prod --allow-workspace syslog-server-prod
# 2. Point this workspace's TFC_AWS_* at hcptf-bootstrap /
# hcptf-bootstrap-plan (workspace vars, never a project set).
# 3. One Manual apply (create roles + scoped inline + boundary + stack).
# 4. Point TFC_AWS_* back at hcptf-syslog-server / hcptf-syslog-server-plan.
# 5. Re-run the script without --allow-workspace to pin trust back to
# iam-bootstrap-prod only.
# Later apply-role IAM edits use the same window. Do not add StringLike
# on bootstrap trust. CreatePolicy stays on hcptf-bootstrap only; boundary
# document changes after seal also need that window.
data " aws_iam_policy_document " " hcptf_apply_trust " {
statement {
sid = " HcpApply "
effect = " Allow "
actions = [ " sts:AssumeRoleWithWebIdentity " ]
principals {
type = " Federated "
identifiers = [ " arn:aws:iam:: ${ local . account_id } :oidc-provider/app.terraform.io " ]
}
condition {
test = " StringEquals "
variable = " app.terraform.io:aud "
values = [ " aws.workload.identity " ]
}
condition {
test = " StringEquals "
variable = " app.terraform.io:sub "
values = [
" organization:seahaven:project: ${ local . hcp_project } :workspace: ${ local . hcp_workspace } :run_phase:apply " ,
]
}
}
}
data " aws_iam_policy_document " " hcptf_plan_trust " {
statement {
sid = " HcpPlan "
effect = " Allow "
actions = [ " sts:AssumeRoleWithWebIdentity " ]
principals {
type = " Federated "
identifiers = [ " arn:aws:iam:: ${ local . account_id } :oidc-provider/app.terraform.io " ]
}
condition {
test = " StringEquals "
variable = " app.terraform.io:aud "
values = [ " aws.workload.identity " ]
}
condition {
test = " StringEquals "
variable = " app.terraform.io:sub "
values = [
" organization:seahaven:project: ${ local . hcp_project } :workspace: ${ local . hcp_workspace } :run_phase:plan " ,
]
}
}
}
data " aws_iam_policy_document " " hcptf_scoped_iam " {
statement {
sid = " DenyCreatePolicy "
effect = " Deny "
actions = [
" iam:CreatePolicy " ,
" iam:CreatePolicyVersion " ,
" iam:DeletePolicy " ,
" iam:DeletePolicyVersion " ,
" iam:SetDefaultPolicyVersion " ,
]
resources = [ " * " ]
}
statement {
sid = " CreateExecRoleWithBoundary "
effect = " Allow "
actions = [ " iam:CreateRole " ]
resources = [
" arn:aws:iam:: ${ local . account_id } :role/tf-managed/ ${ local . stack_prefix } * " ,
]
condition {
test = " StringLike "
variable = " iam:PermissionsBoundary "
values = [
" arn:aws:iam:: ${ local . account_id } :policy/tf-managed/ ${ local . stack_prefix } * " ,
" arn:aws:iam:: ${ local . account_id } :policy/seahaven-lambda-execution-boundary " ,
" arn:aws:iam:: ${ local . account_id } :policy/seahaven-lambda-execution-boundary- ${ local . stack_name } " ,
]
}
}
statement {
sid = " MutateExecRoleWithBoundary "
effect = " Allow "
actions = [
" iam:AttachRolePolicy " ,
" iam:PutRolePolicy " ,
" iam:PutRolePermissionsBoundary " ,
]
resources = [
" arn:aws:iam:: ${ local . account_id } :role/tf-managed/ ${ local . stack_prefix } * " ,
]
condition {
test = " StringLike "
variable = " iam:PermissionsBoundary "
values = [
" arn:aws:iam:: ${ local . account_id } :policy/tf-managed/ ${ local . stack_prefix } * " ,
" arn:aws:iam:: ${ local . account_id } :policy/seahaven-lambda-execution-boundary " ,
" arn:aws:iam:: ${ local . account_id } :policy/seahaven-lambda-execution-boundary- ${ local . stack_name } " ,
]
}
}
statement {
sid = " WriteExecRoles "
effect = " Allow "
actions = [
" iam:DeleteRole " ,
" iam:DeleteRolePolicy " ,
" iam:DetachRolePolicy " ,
" iam:TagRole " ,
" iam:UntagRole " ,
" iam:UpdateAssumeRolePolicy " ,
" iam:UpdateRole " ,
" iam:UpdateRoleDescription " ,
]
resources = [
" arn:aws:iam:: ${ local . account_id } :role/tf-managed/ ${ local . stack_prefix } * " ,
]
}
statement {
sid = " PassExecRolesToEc2 "
effect = " Allow "
actions = [ " iam:PassRole " ]
resources = [ " arn:aws:iam:: ${ local . account_id } :role/tf-managed/ ${ local . instance_role_name } " ]
condition {
test = " StringEquals "
variable = " iam:PassedToService "
values = [ " ec2.amazonaws.com " ]
}
}
2026-09-17 18:48:25 +00:00
statement {
sid = " PassFirehoseRole "
effect = " Allow "
actions = [ " iam:PassRole " ]
resources = [ " arn:aws:iam:: ${ local . account_id } :role/tf-managed/ ${ local . firehose_role_name } " ]
condition {
test = " StringEquals "
variable = " iam:PassedToService "
values = [ " firehose.amazonaws.com " ]
}
}
2026-09-16 21:29:43 +00:00
statement {
sid = " InstanceProfiles "
effect = " Allow "
actions = [
" iam:AddRoleToInstanceProfile " ,
" iam:CreateInstanceProfile " ,
" iam:DeleteInstanceProfile " ,
" iam:GetInstanceProfile " ,
" iam:ListInstanceProfileTags " ,
" iam:RemoveRoleFromInstanceProfile " ,
" iam:TagInstanceProfile " ,
" iam:UntagInstanceProfile " ,
]
resources = [
" arn:aws:iam:: ${ local . account_id } :instance-profile/tf-managed/ ${ local . instance_profile_name } " ,
]
}
statement {
sid = " IamReadOnly "
effect = " Allow "
actions = [
" iam:GetPolicy " ,
" iam:GetPolicyVersion " ,
" iam:GetRole " ,
" iam:GetRolePolicy " ,
" iam:GetInstanceProfile " ,
" iam:ListAttachedRolePolicies " ,
" iam:ListInstanceProfiles " ,
" iam:ListInstanceProfilesForRole " ,
" iam:ListPolicies " ,
" iam:ListPolicyVersions " ,
" iam:ListRolePolicies " ,
" iam:ListRoleTags " ,
" iam:ListRoles " ,
]
resources = [ " * " ]
}
statement {
sid = " DenySelfMutation "
effect = " Deny "
actions = [
" iam:AttachRolePolicy " ,
" iam:DeleteRole " ,
" iam:DeleteRolePolicy " ,
" iam:DeleteRolePermissionsBoundary " ,
" iam:DetachRolePolicy " ,
" iam:PutRolePolicy " ,
" iam:PutRolePermissionsBoundary " ,
" iam:UpdateAssumeRolePolicy " ,
" iam:UpdateRole " ,
" iam:UpdateRoleDescription " ,
]
resources = [
" arn:aws:iam:: ${ local . account_id } :role/hcptf-* " ,
" arn:aws:iam:: ${ local . account_id } :role/github-cfn-execution-role " ,
" arn:aws:iam:: ${ local . account_id } :role/githubdeploy-* " ,
" arn:aws:iam:: ${ local . account_id } :role/cdk-hnb659fds-* " ,
" arn:aws:iam:: ${ local . account_id } :role/OrganizationAccountAccessRole " ,
" arn:aws:iam:: ${ local . account_id } :role/seahaven-* " ,
]
}
statement {
sid = " DenyBoundaryTampering "
effect = " Deny "
actions = [
" iam:DeleteRolePermissionsBoundary " ,
" iam:DeleteUserPermissionsBoundary " ,
]
resources = [
" arn:aws:iam:: ${ local . account_id } :role/* " ,
" arn:aws:iam:: ${ local . account_id } :user/* " ,
]
}
statement {
sid = " DenyBoundaryPolicyEdit "
effect = " Deny "
actions = [
" iam:CreatePolicyVersion " ,
" iam:DeletePolicy " ,
" iam:DeletePolicyVersion " ,
" iam:SetDefaultPolicyVersion " ,
]
resources = [ " arn:aws:iam:: ${ local . account_id } :policy/seahaven-* " ]
}
}
2026-09-17 19:02:16 +00:00
data " aws_iam_policy_document " " hcptf_apply_archive " {
# checkov:skip=CKV_AWS_111: Glue catalog ARNs require Resource=*. S3, Firehose, Athena, and SNS writes are ARN-prefixed.
2026-09-16 21:29:43 +00:00
statement {
2026-09-17 18:48:25 +00:00
sid = " DescribeLogGroups "
effect = " Allow "
actions = [ " logs:DescribeLogGroups " ]
resources = [ " * " ]
}
statement {
sid = " DeleteLegacyCloudWatchLogGroup "
2026-09-16 21:29:43 +00:00
effect = " Allow "
actions = [
" logs:DeleteLogGroup " ,
" logs:ListTagsForResource " ,
2026-09-17 18:48:25 +00:00
" logs:DeleteRetentionPolicy " ,
2026-09-16 21:29:43 +00:00
]
resources = [
2026-09-17 18:48:25 +00:00
" arn:aws:logs: ${ var . aws_region } : ${ local . account_id } :log-group:unifi-syslog " ,
" arn:aws:logs: ${ var . aws_region } : ${ local . account_id } :log-group:unifi-syslog:* " ,
]
}
statement {
2026-09-17 19:15:05 +00:00
sid = " S3Archive "
2026-09-17 18:48:25 +00:00
effect = " Allow "
actions = [
2026-09-17 19:15:05 +00:00
" s3:* " ,
2026-09-17 18:48:25 +00:00
]
2026-09-17 19:15:05 +00:00
resources = [
" arn:aws:s3::: ${ local . bucket_name } " ,
" arn:aws:s3::: ${ local . bucket_name } /* " ,
2026-09-16 21:29:43 +00:00
]
}
statement {
2026-09-17 18:48:25 +00:00
sid = " FirehoseList "
2026-09-16 21:29:43 +00:00
effect = " Allow "
2026-09-17 18:48:25 +00:00
actions = [ " firehose:ListDeliveryStreams " ]
2026-09-16 21:29:43 +00:00
resources = [ " * " ]
}
2026-09-17 18:48:25 +00:00
statement {
sid = " FirehoseStream "
effect = " Allow "
actions = [
2026-09-17 19:15:05 +00:00
" firehose:* " ,
2026-09-17 18:48:25 +00:00
]
resources = [
" arn:aws:firehose: ${ var . aws_region } : ${ local . account_id } :deliverystream/ ${ local . firehose_name } " ,
]
}
statement {
sid = " GlueCatalog "
effect = " Allow "
actions = [
2026-09-17 19:15:05 +00:00
" glue:* " ,
2026-09-17 18:48:25 +00:00
]
resources = [
" arn:aws:glue: ${ var . aws_region } : ${ local . account_id } :catalog " ,
" arn:aws:glue: ${ var . aws_region } : ${ local . account_id } :database/ ${ local . glue_database_name } " ,
" arn:aws:glue: ${ var . aws_region } : ${ local . account_id } :table/ ${ local . glue_database_name } /* " ,
]
}
statement {
sid = " AthenaWorkgroup "
effect = " Allow "
actions = [
2026-09-17 19:15:05 +00:00
" athena:* " ,
2026-09-17 18:48:25 +00:00
]
resources = [
" arn:aws:athena: ${ var . aws_region } : ${ local . account_id } :workgroup/ ${ local . athena_workgroup } " ,
]
}
2026-09-16 21:29:43 +00:00
statement {
sid = " CloudWatchAlarms "
effect = " Allow "
actions = [
" cloudwatch:PutMetricAlarm " ,
" cloudwatch:DeleteAlarms " ,
" cloudwatch:DescribeAlarms " ,
" cloudwatch:TagResource " ,
" cloudwatch:UntagResource " ,
" cloudwatch:ListTagsForResource " ,
]
resources = [
" arn:aws:cloudwatch: ${ var . aws_region } : ${ local . account_id } :alarm:Syslog-* " ,
" arn:aws:cloudwatch: ${ var . aws_region } : ${ local . account_id } :alarm:EC2-StatusCheck*syslog* " ,
]
}
statement {
sid = " CloudWatchDescribeAlarms "
effect = " Allow "
actions = [ " cloudwatch:DescribeAlarms " ]
resources = [ " * " ]
}
statement {
sid = " SnsPublishSiteAlerts "
effect = " Allow "
actions = [
" sns:Publish " ,
" sns:GetTopicAttributes " ,
" sns:ListTagsForResource " ,
]
resources = [ local . site_alerts_arn ]
}
statement {
sid = " ManageTfManagedBoundary "
effect = " Allow "
actions = [
" iam:GetPolicy " ,
" iam:GetPolicyVersion " ,
" iam:ListPolicyVersions " ,
" iam:ListPolicyTags " ,
" iam:TagPolicy " ,
" iam:UntagPolicy " ,
]
resources = [
" arn:aws:iam:: ${ local . account_id } :policy/tf-managed/ ${ local . stack_prefix } * " ,
]
}
2026-09-17 19:02:16 +00:00
}
2026-09-16 21:29:43 +00:00
2026-09-17 19:02:16 +00:00
data " aws_iam_policy_document " " hcptf_apply_services " {
# checkov:skip=CKV_AWS_111: EC2 describe APIs require Resource=*.
2026-09-16 21:29:43 +00:00
statement {
sid = " Ec2VpcManagement "
effect = " Allow "
actions = [
" ec2:AllocateAddress " ,
" ec2:AssociateAddress " ,
" ec2:AssociateRouteTable " ,
" ec2:AttachInternetGateway " ,
" ec2:AuthorizeSecurityGroupEgress " ,
" ec2:AuthorizeSecurityGroupIngress " ,
" ec2:CreateInternetGateway " ,
" ec2:CreateRoute " ,
" ec2:CreateRouteTable " ,
" ec2:CreateSecurityGroup " ,
" ec2:CreateSubnet " ,
" ec2:CreateTags " ,
" ec2:CreateVpc " ,
" ec2:DeleteInternetGateway " ,
" ec2:DeleteRoute " ,
" ec2:DeleteRouteTable " ,
" ec2:DeleteSecurityGroup " ,
" ec2:DeleteSubnet " ,
" ec2:DeleteTags " ,
" ec2:DeleteVpc " ,
" ec2:DescribeAccountAttributes " ,
" ec2:DescribeAddresses " ,
" ec2:DescribeAddressesAttribute " ,
" ec2:DescribeAvailabilityZones " ,
" ec2:DescribeInternetGateways " ,
" ec2:DescribeNetworkInterfaces " ,
" ec2:DescribeRouteTables " ,
" ec2:DescribeSecurityGroupRules " ,
" ec2:DescribeSecurityGroups " ,
" ec2:DescribeSubnets " ,
" ec2:DescribeTags " ,
" ec2:DescribeVpcAttribute " ,
" ec2:DescribeVpcs " ,
" ec2:DescribePrefixLists " ,
2026-09-17 18:48:25 +00:00
" ec2:DescribeVpnConnections " ,
" ec2:DescribeVpnGateways " ,
" ec2:DescribeCustomerGateways " ,
" ec2:CreateVpnGateway " ,
" ec2:DeleteVpnGateway " ,
" ec2:AttachVpnGateway " ,
" ec2:DetachVpnGateway " ,
" ec2:CreateCustomerGateway " ,
" ec2:DeleteCustomerGateway " ,
" ec2:CreateVpnConnection " ,
" ec2:DeleteVpnConnection " ,
" ec2:CreateVpnConnectionRoute " ,
" ec2:DeleteVpnConnectionRoute " ,
" ec2:ModifyVpnConnection " ,
" ec2:ModifyVpnConnectionOptions " ,
" ec2:ModifyVpnTunnelOptions " ,
2026-09-16 21:29:43 +00:00
" ec2:DetachInternetGateway " ,
" ec2:DisassociateAddress " ,
" ec2:DisassociateRouteTable " ,
" ec2:ModifySecurityGroupRules " ,
" ec2:ModifySubnetAttribute " ,
" ec2:ModifyVpcAttribute " ,
" ec2:ReleaseAddress " ,
" ec2:RevokeSecurityGroupEgress " ,
" ec2:RevokeSecurityGroupIngress " ,
" ec2:UpdateSecurityGroupRuleDescriptionsEgress " ,
" ec2:UpdateSecurityGroupRuleDescriptionsIngress " ,
]
resources = [ " * " ]
}
statement {
sid = " Ec2InstanceManagement "
effect = " Allow "
actions = [
" ec2:AssociateIamInstanceProfile " ,
" ec2:AttachVolume " ,
" ec2:CreateVolume " ,
" ec2:DeleteVolume " ,
" ec2:DescribeIamInstanceProfileAssociations " ,
" ec2:DescribeImages " ,
" ec2:DescribeInstanceAttribute " ,
" ec2:DescribeInstanceCreditSpecifications " ,
2026-09-16 21:48:35 +00:00
" ec2:DescribeInstanceRecoveryAttribute " ,
2026-09-16 21:29:43 +00:00
" ec2:DescribeInstanceStatus " ,
" ec2:DescribeInstanceTypes " ,
" ec2:DescribeInstances " ,
" ec2:DescribeVolumes " ,
" ec2:DescribeVolumeAttribute " ,
" ec2:DescribeVolumeStatus " ,
" ec2:DetachVolume " ,
" ec2:DisassociateIamInstanceProfile " ,
" ec2:GetConsoleOutput " ,
" ec2:ModifyInstanceAttribute " ,
" ec2:ModifyVolume " ,
" ec2:MonitorInstances " ,
" ec2:RebootInstances " ,
2026-09-16 21:48:35 +00:00
" ec2:RecoverInstances " ,
2026-09-16 21:29:43 +00:00
" ec2:ReplaceIamInstanceProfileAssociation " ,
" ec2:RunInstances " ,
" ec2:StartInstances " ,
" ec2:StopInstances " ,
" ec2:TerminateInstances " ,
" ec2:UnmonitorInstances " ,
]
resources = [ " * " ]
}
2026-09-16 21:48:35 +00:00
statement {
sid = " CloudWatchEc2RecoverServiceLinkedRole "
effect = " Allow "
actions = [
" iam:CreateServiceLinkedRole " ,
]
resources = [
" arn:aws:iam:: ${ local . account_id } :role/aws-service-role/events.amazonaws.com/AWSServiceRoleForCloudWatchEvents " ,
]
condition {
test = " StringEquals "
variable = " iam:AWSServiceName "
values = [ " events.amazonaws.com " ]
}
}
2026-09-16 21:29:43 +00:00
}
data " aws_iam_policy_document " " hcptf_plan_refresh " {
statement {
sid = " RefreshIamRoles "
effect = " Allow "
actions = [
" iam:GetRole " ,
" iam:GetRolePolicy " ,
" iam:GetInstanceProfile " ,
" iam:ListRolePolicies " ,
" iam:ListAttachedRolePolicies " ,
" iam:ListInstanceProfilesForRole " ,
" iam:ListRoleTags " ,
]
resources = [
" arn:aws:iam:: ${ local . account_id } :role/tf-managed/ ${ local . stack_prefix } * " ,
" arn:aws:iam:: ${ local . account_id } :instance-profile/tf-managed/ ${ local . stack_prefix } * " ,
" arn:aws:iam:: ${ local . account_id } :role/ ${ local . apply_role } " ,
" arn:aws:iam:: ${ local . account_id } :role/ ${ local . plan_role } " ,
]
}
statement {
sid = " RefreshManagedPolicies "
effect = " Allow "
actions = [
" iam:GetPolicy " ,
" iam:GetPolicyVersion " ,
]
resources = [ " * " ]
}
statement {
2026-09-17 18:48:25 +00:00
sid = " RefreshS3 "
2026-09-16 21:29:43 +00:00
effect = " Allow "
actions = [
2026-09-17 18:48:25 +00:00
" s3:GetAccelerateConfiguration " ,
" s3:GetBucketAcl " ,
" s3:GetBucketCORS " ,
" s3:GetBucketLocation " ,
" s3:GetBucketLogging " ,
" s3:GetBucketNotification " ,
" s3:GetBucketObjectLockConfiguration " ,
" s3:GetBucketOwnershipControls " ,
" s3:GetBucketPolicy " ,
" s3:GetBucketPolicyStatus " ,
" s3:GetBucketPublicAccessBlock " ,
" s3:GetBucketRequestPayment " ,
" s3:GetBucketTagging " ,
" s3:GetBucketVersioning " ,
" s3:GetBucketWebsite " ,
" s3:GetEncryptionConfiguration " ,
" s3:GetLifecycleConfiguration " ,
" s3:GetReplicationConfiguration " ,
" s3:ListBucket " ,
]
resources = [ " arn:aws:s3::: ${ local . bucket_name } " ]
}
statement {
sid = " RefreshFirehoseList "
effect = " Allow "
actions = [ " firehose:ListDeliveryStreams " ]
2026-09-16 21:29:43 +00:00
resources = [ " * " ]
}
2026-09-17 18:48:25 +00:00
statement {
sid = " RefreshFirehose "
effect = " Allow "
actions = [
" firehose:DescribeDeliveryStream " ,
" firehose:ListTagsForDeliveryStream " ,
]
resources = [
" arn:aws:firehose: ${ var . aws_region } : ${ local . account_id } :deliverystream/ ${ local . firehose_name } " ,
]
}
statement {
sid = " RefreshGlue "
effect = " Allow "
actions = [
" glue:GetDatabase " ,
" glue:GetDatabases " ,
" glue:GetTable " ,
" glue:GetTables " ,
" glue:GetTags " ,
]
resources = [
" arn:aws:glue: ${ var . aws_region } : ${ local . account_id } :catalog " ,
" arn:aws:glue: ${ var . aws_region } : ${ local . account_id } :database/ ${ local . glue_database_name } " ,
" arn:aws:glue: ${ var . aws_region } : ${ local . account_id } :table/ ${ local . glue_database_name } /* " ,
]
}
statement {
sid = " RefreshAthena "
effect = " Allow "
actions = [
" athena:GetWorkGroup " ,
" athena:GetNamedQuery " ,
" athena:ListNamedQueries " ,
" athena:ListTagsForResource " ,
]
resources = [
" arn:aws:athena: ${ var . aws_region } : ${ local . account_id } :workgroup/ ${ local . athena_workgroup } " ,
]
}
2026-09-16 21:29:43 +00:00
statement {
sid = " RefreshAlarms "
effect = " Allow "
actions = [
" cloudwatch:DescribeAlarms " ,
" cloudwatch:ListTagsForResource " ,
]
resources = [ " * " ]
}
statement {
sid = " RefreshSns "
effect = " Allow "
actions = [
" sns:GetTopicAttributes " ,
" sns:ListTagsForResource " ,
]
resources = [ local . site_alerts_arn ]
}
statement {
sid = " RefreshEc2 "
effect = " Allow "
actions = [
" ec2:DescribeAccountAttributes " ,
" ec2:DescribeAddresses " ,
" ec2:DescribeAddressesAttribute " ,
" ec2:DescribeAvailabilityZones " ,
" ec2:DescribeIamInstanceProfileAssociations " ,
" ec2:DescribeImages " ,
" ec2:DescribeInstanceAttribute " ,
" ec2:DescribeInstanceCreditSpecifications " ,
2026-09-16 21:48:35 +00:00
" ec2:DescribeInstanceRecoveryAttribute " ,
2026-09-16 21:29:43 +00:00
" ec2:DescribeInstanceStatus " ,
" ec2:DescribeInstanceTypes " ,
" ec2:DescribeInstances " ,
" ec2:DescribeInternetGateways " ,
" ec2:DescribeNetworkInterfaces " ,
" ec2:DescribePrefixLists " ,
" ec2:DescribeRouteTables " ,
" ec2:DescribeSecurityGroupRules " ,
" ec2:DescribeSecurityGroups " ,
" ec2:DescribeSubnets " ,
" ec2:DescribeTags " ,
" ec2:DescribeVolumeAttribute " ,
" ec2:DescribeVolumeStatus " ,
" ec2:DescribeVolumes " ,
" ec2:DescribeVpcAttribute " ,
" ec2:DescribeVpcs " ,
2026-09-17 18:48:25 +00:00
" ec2:DescribeVpnConnections " ,
" ec2:DescribeVpnGateways " ,
" ec2:DescribeCustomerGateways " ,
2026-09-16 21:29:43 +00:00
" ec2:GetConsoleOutput " ,
]
resources = [ " * " ]
}
}
resource " aws_iam_role " " hcptf_apply " {
name = local . apply_role
assume_role_policy = data . aws_iam_policy_document . hcptf_apply_trust . json
max_session_duration = 3600
tags = {
Owner = " adam@seahavenind.com "
ManagedBy = " terraform "
}
}
resource " aws_iam_role " " hcptf_plan " {
name = local . plan_role
assume_role_policy = data . aws_iam_policy_document . hcptf_plan_trust . json
max_session_duration = 3600
tags = {
Owner = " adam@seahavenind.com "
ManagedBy = " terraform "
}
}
resource " aws_iam_role_policy " " hcptf_scoped_iam " {
name = " scoped-iam-management "
role = aws_iam_role . hcptf_apply . id
policy = data . aws_iam_policy_document . hcptf_scoped_iam . json
}
2026-09-17 19:02:16 +00:00
resource " aws_iam_role_policy " " hcptf_apply_archive " {
# checkov:skip=CKV_AWS_111: Glue catalog ARNs require Resource=*. S3, Firehose, Athena, and SNS writes are ARN-prefixed.
name = " syslog-server-archive "
role = aws_iam_role . hcptf_apply . id
policy = data . aws_iam_policy_document . hcptf_apply_archive . json
}
2026-09-16 21:29:43 +00:00
resource " aws_iam_role_policy " " hcptf_apply_services " {
2026-09-17 19:02:16 +00:00
# checkov:skip=CKV_AWS_111: EC2 VPC/instance lifecycle and describe APIs require Resource=*.
2026-09-16 21:29:43 +00:00
name = " syslog-server-services "
role = aws_iam_role . hcptf_apply . id
policy = data . aws_iam_policy_document . hcptf_apply_services . json
}
resource " aws_iam_role_policy " " hcptf_plan_refresh " {
# checkov:skip=CKV_AWS_107: ViewOnlyAccess plus this sidecar is the org HCP plan-role pattern (PLAT-144). Sidecar Get* is named (GetRole, GetPolicy, GetInstanceProfile, GetConsoleOutput, GetTopicAttributes) and scoped to this stack. It does not add iam:CreateAccessKey, secretsmanager:GetSecretValue, or ssm:GetParameter on *.
name = " syslog-server-plan-refresh "
role = aws_iam_role . hcptf_plan . id
policy = data . aws_iam_policy_document . hcptf_plan_refresh . json
}
resource " aws_iam_role_policy_attachment " " hcptf_plan_view_only " {
role = aws_iam_role . hcptf_plan . name
policy_arn = " arn:aws:iam::aws:policy/job-function/ViewOnlyAccess "
}
resource " aws_iam_role_policy_attachments_exclusive " " hcptf_apply " {
role_name = aws_iam_role . hcptf_apply . name
policy_arns = [ ]
}
resource " aws_iam_role_policy_attachments_exclusive " " hcptf_plan " {
role_name = aws_iam_role . hcptf_plan . name
policy_arns = [
" arn:aws:iam::aws:policy/job-function/ViewOnlyAccess " ,
]
}