# HCP plan/apply roles imported from seahaven-terraform-substrate (PLAT-146). # Import, do not recreate. Role names stay hcptf-procurement-ingest / hcptf-procurement-ingest-plan. # # Live seahaven-hcptf-iam-management DenySelfMutation blocks DetachRolePolicy # and PutRolePolicy on hcptf-* (including this role). Import apply sequence: # 1. seahaven-org-baseline scripts/create-hcptf-bootstrap-roles.sh # --account prod --allow-workspace procurement-ingest-prod # 2. Point this workspace's TFC_AWS_* at hcptf-bootstrap / # hcptf-bootstrap-plan (workspace vars, never a project set). # 3. One Manual apply (import + detach seahaven-hcptf-iam-management + # put scoped IAM as a customer-managed policy). # 4. Point TFC_AWS_* back at hcptf-procurement-ingest / hcptf-procurement-ingest-plan. # 5. Re-run the script without --allow-workspace to pin trust back to # iam-bootstrap-prod only. # seahaven-lambda-execution-boundary remains seahaven-lambda-execution-boundary-procurement-ingest. import { to = aws_iam_role.hcptf_apply id = "hcptf-procurement-ingest" } import { to = aws_iam_role.hcptf_plan id = "hcptf-procurement-ingest-plan" } import { to = aws_iam_role_policy.hcptf_apply_services id = "hcptf-procurement-ingest:procurement-ingest-services" } import { to = aws_iam_role_policy.hcptf_plan_refresh id = "hcptf-procurement-ingest-plan:procurement-ingest-plan-refresh" } import { to = aws_iam_role_policy_attachments_exclusive.hcptf_apply id = "hcptf-procurement-ingest" } import { to = aws_iam_role_policy_attachment.hcptf_plan_viewonly id = "hcptf-procurement-ingest-plan/arn:aws:iam::aws:policy/job-function/ViewOnlyAccess" } import { to = aws_iam_role_policy_attachments_exclusive.hcptf_plan id = "hcptf-procurement-ingest-plan" } 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:seahaven-prod:workspace:procurement-ingest-prod: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:seahaven-prod:workspace:procurement-ingest-prod:run_phase:plan", ] } } } data "aws_iam_policy_document" "hcptf_scoped_iam" { statement { sid = "DenyCreatePolicy" effect = "Deny" actions = ["iam:CreatePolicy", "iam:CreatePolicyVersion"] resources = ["*"] } statement { sid = "CreateExecRoleWithBoundary" effect = "Allow" actions = ["iam:CreateRole"] resources = ["arn:aws:iam::${local.account_id}:role/tf-managed/po-*", "arn:aws:iam::${local.account_id}:role/tf-managed/workorder-*", "arn:aws:iam::${local.account_id}:role/tf-managed/procurement-api"] condition { test = "StringLike" variable = "iam:PermissionsBoundary" values = [ "arn:aws:iam::${local.account_id}:policy/tf-managed/po-*", "arn:aws:iam::${local.account_id}:policy/tf-managed/workorder-*", "arn:aws:iam::${local.account_id}:policy/tf-managed/procurement-api", "arn:aws:iam::${local.account_id}:policy/seahaven-lambda-execution-boundary-procurement-ingest" ] } } statement { sid = "MutateExecRoleWithBoundary" effect = "Allow" actions = [ "iam:AttachRolePolicy", "iam:PutRolePolicy", "iam:PutRolePermissionsBoundary", ] resources = ["arn:aws:iam::${local.account_id}:role/tf-managed/po-*", "arn:aws:iam::${local.account_id}:role/tf-managed/workorder-*", "arn:aws:iam::${local.account_id}:role/tf-managed/procurement-api"] condition { test = "StringLike" variable = "iam:PermissionsBoundary" values = [ "arn:aws:iam::${local.account_id}:policy/tf-managed/po-*", "arn:aws:iam::${local.account_id}:policy/tf-managed/workorder-*", "arn:aws:iam::${local.account_id}:policy/tf-managed/procurement-api", "arn:aws:iam::${local.account_id}:policy/seahaven-lambda-execution-boundary-procurement-ingest" ] } } 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/po-*", "arn:aws:iam::${local.account_id}:role/tf-managed/workorder-*", "arn:aws:iam::${local.account_id}:role/tf-managed/procurement-api"] } statement { sid = "PassExecRolesToLambda" effect = "Allow" actions = ["iam:PassRole"] resources = ["arn:aws:iam::${local.account_id}:role/tf-managed/po-*", "arn:aws:iam::${local.account_id}:role/tf-managed/workorder-*", "arn:aws:iam::${local.account_id}:role/tf-managed/procurement-api"] condition { test = "StringEquals" variable = "iam:PassedToService" values = ["lambda.amazonaws.com"] } } statement { sid = "IamReadOnly" effect = "Allow" actions = [ "iam:GetPolicy", "iam:GetPolicyVersion", "iam:GetRole", "iam:GetRolePolicy", "iam:ListAttachedRolePolicies", "iam:ListInstanceProfilesForRole", "iam:ListPolicies", "iam:ListPolicyTags", "iam:ListPolicyVersions", "iam:ListRolePolicies", "iam:ListRoles", "iam:ListRoleTags", ] 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-*"] } } resource "aws_iam_role_policy" "hcptf_apply_services" { name = "procurement-ingest-services" role = aws_iam_role.hcptf_apply.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = [ "lambda:*", ] Resource = [ "arn:aws:lambda:us-east-1:${local.account_id}:function:po-*", "arn:aws:lambda:us-east-1:${local.account_id}:function:workorder-*", "arn:aws:lambda:us-east-1:${local.account_id}:function:procurement-api", ] Effect = "Allow" Sid = "LambdaAll" }, { Action = [ "lambda:GetEventSourceMapping", "lambda:ListTags", "lambda:TagResource", "lambda:UntagResource", ] Resource = "*" Effect = "Allow" Sid = "LambdaEventSourceMappingRead" }, { Condition = { "ForAnyValue:StringLike" = { "lambda:FunctionArn" = [ "arn:aws:lambda:us-east-1:${local.account_id}:function:po-*", "arn:aws:lambda:us-east-1:${local.account_id}:function:workorder-*", "arn:aws:lambda:us-east-1:${local.account_id}:function:procurement-api", ] } } Action = [ "lambda:CreateEventSourceMapping", "lambda:DeleteEventSourceMapping", "lambda:UpdateEventSourceMapping", ] Resource = "*" Effect = "Allow" Sid = "LambdaEventSourceMappings" }, { Action = [ "lambda:ListFunctions", "lambda:ListEventSourceMappings", "lambda:GetAccountSettings", ] Resource = "*" Effect = "Allow" Sid = "LambdaList" }, { Action = [ "ssm:GetParameter", "ssm:GetParameters", ] Resource = [ "arn:aws:ssm:us-east-1:${local.account_id}:parameter/seahaven/dynamodb/cmk-arn", "arn:aws:ssm:us-east-1:${local.account_id}:parameter/procurement-api/custom-domain/certificate-arn", ] Effect = "Allow" Sid = "SsmRead" }, { Action = [ "logs:CreateLogGroup", "logs:DeleteLogGroup", "logs:PutRetentionPolicy", "logs:DeleteRetentionPolicy", "logs:TagResource", "logs:UntagResource", "logs:ListTagsForResource", "logs:PutMetricFilter", "logs:DeleteMetricFilter", "logs:DescribeMetricFilters", ] Resource = [ "arn:aws:logs:us-east-1:${local.account_id}:log-group:/aws/lambda/po-*", "arn:aws:logs:us-east-1:${local.account_id}:log-group:/aws/lambda/workorder-*", "arn:aws:logs:us-east-1:${local.account_id}:log-group:/aws/lambda/procurement-api*", ] Effect = "Allow" Sid = "CloudWatchLogs" }, { Action = [ "logs:DescribeLogGroups", ] Resource = "*" Effect = "Allow" Sid = "CloudWatchLogsDescribe" }, { Action = [ "s3:*", ] Resource = [ "arn:aws:s3:::procurement-ingest-artifacts-${local.account_id}", "arn:aws:s3:::procurement-ingest-artifacts-${local.account_id}/*", ] Effect = "Allow" Sid = "ArtifactsBucket" }, { Action = [ "s3:*", ] Resource = [ "arn:aws:s3:::po-ingest-emails-${local.account_id}", "arn:aws:s3:::po-ingest-emails-${local.account_id}/*", "arn:aws:s3:::workorder-ingest-emails-${local.account_id}", "arn:aws:s3:::workorder-ingest-emails-${local.account_id}/*", ] Effect = "Allow" Sid = "EmailBuckets" }, { Action = [ "dynamodb:*", ] Resource = [ "arn:aws:dynamodb:us-east-1:${local.account_id}:table/purchase-orders", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/purchase-orders/*", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/verified-sites", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/verified-sites/*", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/pending-site-review", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/pending-site-review/*", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/work-orders", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/work-orders/*", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/work-order-comments", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/work-order-comments/*", ] Effect = "Allow" Sid = "DynamoDBTables" }, { Action = [ "dynamodb:ListTables", "dynamodb:ListStreams", ] Resource = "*" Effect = "Allow" Sid = "DynamoDBList" }, { Action = [ "sqs:*", ] Resource = [ "arn:aws:sqs:us-east-1:${local.account_id}:po-ingest-*", "arn:aws:sqs:us-east-1:${local.account_id}:WorkorderIngestStack-*", "arn:aws:sqs:us-east-1:${local.account_id}:workorder-shoc-emitter-*", ] Effect = "Allow" Sid = "SqsQueues" }, { Action = [ "cloudwatch:*", ] Resource = [ "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:po-*", "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:workorder-*", "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:procurement-api-*", "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:purchase-orders-*", "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:verified-sites-*", "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:pending-site-review-*", "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:work-orders-*", "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:work-order-comments-*", ] Effect = "Allow" Sid = "CloudWatchAlarms" }, { Action = [ "sns:Publish", "sns:GetTopicAttributes", "sns:ListTagsForResource", ] Resource = [ "arn:aws:sns:us-east-1:${local.account_id}:site-alerts", ] Effect = "Allow" Sid = "SiteAlertsSns" }, { Action = [ "apigateway:*", ] Resource = [ "arn:aws:apigateway:us-east-1::/restapis/mvul1efda2", "arn:aws:apigateway:us-east-1::/restapis/mvul1efda2/*", "arn:aws:apigateway:us-east-1::/domainnames/procurement-api.seahaven.com", "arn:aws:apigateway:us-east-1::/domainnames/procurement-api.seahaven.com/*", "arn:aws:apigateway:us-east-1::/tags/*", ] Effect = "Allow" Sid = "ApiGateway" }, { Action = [ "ses:CreateReceiptRule", "ses:UpdateReceiptRule", "ses:DeleteReceiptRule", "ses:DescribeReceiptRule", "ses:SetReceiptRulePosition", ] Resource = [ "arn:aws:ses:us-east-1:${local.account_id}:receipt-rule-set/INBOUND_MAIL:receipt-rule/ExistingRuleSetPoEmailRuleAC8E9C87-qwGDj9lBoL1G", "arn:aws:ses:us-east-1:${local.account_id}:receipt-rule-set/INBOUND_MAIL:receipt-rule/ExistingRuleSetWorkorderEmailRuleEA29F845-PKtaDBvIg61a", ] Effect = "Allow" Sid = "SesReceiptRules" }, { Action = [ "ses:DescribeReceiptRuleSet", ] Resource = "*" Effect = "Allow" Sid = "SesDescribeRuleSet" }, { Action = [ "kms:DescribeKey", "kms:GetKeyPolicy", "kms:GetKeyRotationStatus", "kms:ListResourceTags", "kms:PutKeyPolicy", "kms:EnableKeyRotation", "kms:DisableKeyRotation", "kms:ScheduleKeyDeletion", "kms:CancelKeyDeletion", "kms:TagResource", "kms:UntagResource", "kms:EnableKey", "kms:DisableKey", ] Resource = [ "arn:aws:kms:us-east-1:${local.account_id}:key/d10fd1f0-a61a-4405-8568-85e9fd11ba18", ] Effect = "Allow" Sid = "ShocKms" }, { Action = [ "kms:ListAliases", "kms:ListKeys", ] Resource = "*" Effect = "Allow" Sid = "KmsList" }, { Action = [ "kms:CreateAlias", "kms:DeleteAlias", "kms:UpdateAlias", ] Resource = [ "arn:aws:kms:us-east-1:${local.account_id}:alias/workorder-ingest-shoc-webhook-kms", "arn:aws:kms:us-east-1:${local.account_id}:key/d10fd1f0-a61a-4405-8568-85e9fd11ba18", ] Effect = "Allow" Sid = "ShocKmsAlias" }, { Action = [ "secretsmanager:DeleteSecret", "secretsmanager:DescribeSecret", "secretsmanager:GetResourcePolicy", "secretsmanager:PutResourcePolicy", "secretsmanager:DeleteResourcePolicy", "secretsmanager:TagResource", "secretsmanager:UntagResource", "secretsmanager:RotateSecret", "secretsmanager:CancelRotateSecret", "secretsmanager:UpdateSecretVersionStage", ] Resource = [ "arn:aws:secretsmanager:us-east-1:${local.account_id}:secret:workorder-ingest/shoc-webhook-hmac-*", ] Effect = "Allow" Sid = "ShocSecretShell" }, { Condition = { StringEquals = { "secretsmanager:Name" = "workorder-ingest/shoc-webhook-hmac" } } Action = [ "secretsmanager:CreateSecret", ] Resource = "*" Effect = "Allow" Sid = "ShocSecretCreate" }, { Action = [ "secretsmanager:DescribeSecret", "secretsmanager:GetResourcePolicy", ] Resource = [ "arn:aws:secretsmanager:us-east-1:${local.account_id}:secret:procurement-ingest/web-ui-auth-token-*", ] Effect = "Allow" Sid = "WebUiSecretDescribe" }, ] }) } resource "aws_iam_role_policy" "hcptf_plan_refresh" { name = "procurement-ingest-plan-refresh" role = aws_iam_role.hcptf_plan.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = [ "iam:GetRole", "iam:GetRolePolicy", "iam:ListRolePolicies", "iam:ListAttachedRolePolicies", ] Resource = [ "arn:aws:iam::${local.account_id}:role/tf-managed/po-*", "arn:aws:iam::${local.account_id}:role/tf-managed/workorder-*", "arn:aws:iam::${local.account_id}:role/tf-managed/procurement-api", "arn:aws:iam::${local.account_id}:role/hcptf-procurement-ingest", "arn:aws:iam::${local.account_id}:role/hcptf-procurement-ingest-plan", ] Effect = "Allow" Sid = "RefreshIamRoles" }, { Action = [ "iam:GetPolicy", "iam:GetPolicyVersion", "iam:ListPolicyTags", ] Resource = "*" Effect = "Allow" Sid = "RefreshManagedPolicies" }, { Action = [ "lambda:Get*", ] Resource = [ "arn:aws:lambda:us-east-1:${local.account_id}:function:po-*", "arn:aws:lambda:us-east-1:${local.account_id}:function:workorder-*", "arn:aws:lambda:us-east-1:${local.account_id}:function:procurement-api", ] Effect = "Allow" Sid = "RefreshLambda" }, { Action = [ "lambda:ListFunctions", "lambda:ListEventSourceMappings", "lambda:GetEventSourceMapping", "lambda:GetAccountSettings", ] Resource = "*" Effect = "Allow" Sid = "RefreshLambdaList" }, { Action = [ "s3:Get*", "s3:ListBucket", ] Resource = [ "arn:aws:s3:::procurement-ingest-artifacts-${local.account_id}", "arn:aws:s3:::procurement-ingest-artifacts-${local.account_id}/*", ] Effect = "Allow" Sid = "RefreshArtifactsBucket" }, { Action = [ "s3:Get*", "s3:ListBucket", "s3:GetBucketNotification", "s3:GetBucketPolicy", "s3:GetEncryptionConfiguration", "s3:GetBucketTagging", "s3:GetBucketVersioning", "s3:GetBucketPublicAccessBlock", ] Resource = [ "arn:aws:s3:::po-ingest-emails-${local.account_id}", "arn:aws:s3:::po-ingest-emails-${local.account_id}/*", "arn:aws:s3:::workorder-ingest-emails-${local.account_id}", "arn:aws:s3:::workorder-ingest-emails-${local.account_id}/*", ] Effect = "Allow" Sid = "RefreshEmailBuckets" }, { Action = [ "dynamodb:DescribeTable", "dynamodb:DescribeTimeToLive", "dynamodb:DescribeContinuousBackups", "dynamodb:DescribeStream", "dynamodb:ListTagsOfResource", ] Resource = [ "arn:aws:dynamodb:us-east-1:${local.account_id}:table/purchase-orders", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/purchase-orders/*", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/verified-sites", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/pending-site-review", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/work-orders", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/work-orders/*", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/work-order-comments", "arn:aws:dynamodb:us-east-1:${local.account_id}:table/work-order-comments/*", ] Effect = "Allow" Sid = "RefreshDynamoDB" }, { Action = [ "dynamodb:ListStreams", "dynamodb:ListTables", ] Resource = "*" Effect = "Allow" Sid = "RefreshDynamoDBList" }, { Action = [ "sqs:GetQueueAttributes", "sqs:GetQueueUrl", "sqs:ListQueueTags", ] Resource = [ "arn:aws:sqs:us-east-1:${local.account_id}:po-ingest-*", "arn:aws:sqs:us-east-1:${local.account_id}:WorkorderIngestStack-*", "arn:aws:sqs:us-east-1:${local.account_id}:workorder-shoc-emitter-*", ] Effect = "Allow" Sid = "RefreshSqs" }, { Action = [ "cloudwatch:DescribeAlarms", "cloudwatch:ListTagsForResource", ] Resource = [ "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:po-*", "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:workorder-*", "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:procurement-api-*", "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:purchase-orders-*", "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:verified-sites-*", "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:pending-site-review-*", "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:work-orders-*", "arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:work-order-comments-*", ] Effect = "Allow" Sid = "RefreshCloudWatchAlarms" }, { Action = [ "apigateway:GET", ] Resource = [ "arn:aws:apigateway:us-east-1::/restapis/mvul1efda2", "arn:aws:apigateway:us-east-1::/restapis/mvul1efda2/*", "arn:aws:apigateway:us-east-1::/domainnames/procurement-api.seahaven.com", "arn:aws:apigateway:us-east-1::/domainnames/procurement-api.seahaven.com/*", ] Effect = "Allow" Sid = "RefreshApiGateway" }, { Action = [ "kms:DescribeKey", "kms:GetKeyPolicy", "kms:GetKeyRotationStatus", "kms:ListResourceTags", ] Resource = [ "arn:aws:kms:us-east-1:${local.account_id}:key/*", "arn:aws:kms:us-east-1:${local.account_id}:alias/workorder-ingest-shoc-webhook-kms", ] Effect = "Allow" Sid = "RefreshKms" }, { Action = [ "kms:ListAliases", "kms:ListKeys", ] Resource = "*" Effect = "Allow" Sid = "RefreshKmsList" }, { Action = [ "secretsmanager:DescribeSecret", "secretsmanager:GetResourcePolicy", "secretsmanager:ListSecretVersionIds", ] Resource = [ "arn:aws:secretsmanager:us-east-1:${local.account_id}:secret:workorder-ingest/shoc-webhook-hmac-*", "arn:aws:secretsmanager:us-east-1:${local.account_id}:secret:procurement-ingest/web-ui-auth-token-*", ] Effect = "Allow" Sid = "RefreshSecrets" }, { Action = [ "ssm:GetParameter", "ssm:GetParameters", ] Resource = [ "arn:aws:ssm:us-east-1:${local.account_id}:parameter/seahaven/dynamodb/cmk-arn", "arn:aws:ssm:us-east-1:${local.account_id}:parameter/procurement-api/custom-domain/certificate-arn", ] Effect = "Allow" Sid = "RefreshSsm" }, { Action = [ "ses:DescribeReceiptRule", "ses:DescribeReceiptRuleSet", ] Resource = "*" Effect = "Allow" Sid = "RefreshSes" }, { Action = [ "logs:DescribeLogGroups", "logs:DescribeMetricFilters", "logs:ListTagsForResource", ] Resource = "*" Effect = "Allow" Sid = "RefreshLogs" }, ] }) } resource "aws_iam_role" "hcptf_apply" { name = "hcptf-procurement-ingest" assume_role_policy = data.aws_iam_policy_document.hcptf_apply_trust.json max_session_duration = 3600 tags = { Project = "procurement-ingest" Owner = "adam@seahavenind.com" ManagedBy = "terraform" } } # Services inline is 6894 bytes; a second inline for scoped IAM exceeds the # 10240 role quota. Attach scoped IAM as a customer-managed policy instead. # Exclusive set keeps seahaven-hcptf-iam-management detached. resource "aws_iam_role_policy_attachments_exclusive" "hcptf_apply" { role_name = aws_iam_role.hcptf_apply.name policy_arns = [ aws_iam_policy.hcptf_scoped_iam.arn, ] } resource "aws_iam_role" "hcptf_plan" { name = "hcptf-procurement-ingest-plan" assume_role_policy = data.aws_iam_policy_document.hcptf_plan_trust.json max_session_duration = 3600 tags = { Project = "procurement-ingest" Owner = "adam@seahavenind.com" ManagedBy = "terraform" } } resource "aws_iam_role_policy_attachment" "hcptf_plan_viewonly" { 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_plan" { role_name = aws_iam_role.hcptf_plan.name policy_arns = [ aws_iam_role_policy_attachment.hcptf_plan_viewonly.policy_arn, ] } resource "aws_iam_policy" "hcptf_scoped_iam" { name = "hcptf-procurement-ingest-scoped-iam" path = "/tf-managed/" policy = data.aws_iam_policy_document.hcptf_scoped_iam.json tags = { Project = "procurement-ingest" Owner = "adam@seahavenind.com" ManagedBy = "terraform" } } resource "aws_iam_role_policy_attachment" "hcptf_scoped_iam" { role = aws_iam_role.hcptf_apply.name policy_arn = aws_iam_policy.hcptf_scoped_iam.arn }