# GitHub Actions OIDC role for .github/workflows/deploy.yaml. # # Trust is pinned three ways: aud, sub to Environment prod (immutable and # classic subject forms), and job_workflow_ref to deploy.yaml at # refs/heads/main only. Live GitHub Actions presented the classic sub; both # forms are listed. No v* tags until a later release ticket. # # Not a Lambda execution role: no permissions_boundary. Path /tf-managed/ so # seahaven-hcptf-iam-management DenySelfMutation (role/githubdeploy-*) does not # match. data "aws_iam_policy_document" "github_deploy_assume" { statement { sid = "GithubDeployOidc" effect = "Allow" actions = ["sts:AssumeRoleWithWebIdentity"] principals { type = "Federated" identifiers = [local.github_oidc_provider_arn] } condition { test = "StringEquals" variable = "token.actions.githubusercontent.com:aud" values = ["sts.amazonaws.com"] } condition { test = "StringEquals" variable = "token.actions.githubusercontent.com:sub" values = [ local.github_oidc_sub, "repo:${var.github_repo}:environment:prod", ] } condition { test = "StringEquals" variable = "token.actions.githubusercontent.com:job_workflow_ref" values = [ "${var.github_repo}/.github/workflows/deploy.yaml@refs/heads/${var.github_deploy_branch}", ] } } } resource "aws_iam_role" "github_deploy" { name = local.deploy_role path = "/tf-managed/" description = "GitHub Actions deploy role for ${var.github_repo} Environment prod" assume_role_policy = data.aws_iam_policy_document.github_deploy_assume.json max_session_duration = 3600 } data "aws_iam_policy_document" "github_deploy" { statement { sid = "ListArtifactsBucket" effect = "Allow" actions = [ "s3:GetBucketLocation", "s3:ListBucket", ] resources = [aws_s3_bucket.artifacts.arn] } statement { sid = "UploadFunctionArtifacts" effect = "Allow" actions = [ "s3:GetObject", "s3:PutObject", ] resources = ["${aws_s3_bucket.artifacts.arn}/functions/*"] } statement { sid = "ListExportsBucket" effect = "Allow" actions = [ "s3:GetBucketLocation", "s3:ListBucket", ] resources = [aws_s3_bucket.exports.arn] } statement { sid = "SyncGrafanaConfig" effect = "Allow" actions = [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject", ] resources = ["${aws_s3_bucket.exports.arn}/${local.grafana_config_prefix}/*"] } statement { sid = "UpdateFunctionCode" effect = "Allow" actions = [ "lambda:GetFunction", "lambda:GetFunctionConfiguration", "lambda:UpdateFunctionCode", ] resources = [for fn in local.functions : "arn:aws:lambda:${var.aws_region}:${local.account_id}:function:${fn.function_name}"] } statement { sid = "DeployParams" effect = "Allow" actions = [ "ssm:GetParameter", ] resources = [ "arn:aws:ssm:${var.aws_region}:${local.account_id}:parameter${local.ssm_prefix}/deploy/*", ] } } resource "aws_iam_role_policy" "github_deploy" { name = "apm-wo-analysis-deploy" role = aws_iam_role.github_deploy.id policy = data.aws_iam_policy_document.github_deploy.json }