shoc-backend/terraform/iam_github_deploy.tf
Adam Moussa 25c2e84e8f feat(terraform): adopt live deployment roles safely
Add import-only dev and staging state with least-privilege HCP authentication and plan safety guards.
2026-08-28 19:12:34 -04:00

145 lines
4.3 KiB
HCL

data "aws_iam_policy_document" "github_deploy_assume" {
statement {
effect = "Allow"
actions = ["sts:AssumeRoleWithWebIdentity"]
principals {
type = "Federated"
identifiers = [data.aws_iam_openid_connect_provider.github.arn]
}
condition {
test = "StringEquals"
variable = "token.actions.githubusercontent.com:aud"
values = ["sts.amazonaws.com"]
}
condition {
test = "StringEquals"
variable = "token.actions.githubusercontent.com:sub"
values = ["repo:${var.github_repo}:environment:${var.github_environment}"]
}
}
}
resource "aws_iam_role" "github_deploy" {
name = var.github_deploy_role_name
path = local.content_role_path
description = "GitHub Actions deploy role for ${var.github_repo} environment ${var.github_environment}"
assume_role_policy = data.aws_iam_policy_document.github_deploy_assume.json
max_session_duration = 3600
permissions_boundary = var.execution_boundary_arn
lifecycle {
ignore_changes = [permissions_boundary]
}
depends_on = [terraform_data.account_guard]
}
locals {
poc_environment_id = aws_elastic_beanstalk_environment.api.id
poc_environment_stack = "awseb-${aws_elastic_beanstalk_environment.api.id}-stack"
poc_application_arn = "arn:aws:elasticbeanstalk:${var.aws_region}:${local.account_id}:application/${var.eb_application_name}"
poc_environment_arn = "arn:aws:elasticbeanstalk:${var.aws_region}:${local.account_id}:environment/${var.eb_application_name}/${var.eb_environment_name}"
}
data "aws_iam_policy_document" "github_deploy" {
statement {
sid = "DescribeDiscovery"
effect = "Allow"
actions = [
"autoscaling:Describe*",
"ec2:Describe*",
"elasticbeanstalk:DescribeEnvironments",
"elasticbeanstalk:DescribeApplicationVersions",
"elasticbeanstalk:DescribeEvents",
"elasticloadbalancing:Describe*",
]
resources = ["*"]
}
statement {
sid = "CreateApplicationVersion"
effect = "Allow"
actions = [
"elasticbeanstalk:CreateApplicationVersion",
]
resources = [
local.poc_application_arn,
"arn:aws:elasticbeanstalk:${var.aws_region}:${local.account_id}:applicationversion/${var.eb_application_name}/*",
]
}
statement {
sid = "UpdatePocEnvironment"
effect = "Allow"
actions = ["elasticbeanstalk:UpdateEnvironment"]
resources = [local.poc_environment_arn]
}
statement {
sid = "PocManagedCfn"
effect = "Allow"
actions = [
"cloudformation:DescribeStackEvents",
"cloudformation:DescribeStackResource",
"cloudformation:GetTemplate",
"cloudformation:DescribeStackResources",
"cloudformation:DescribeStacks",
"cloudformation:ListStackResources",
"cloudformation:CancelUpdateStack",
"cloudformation:UpdateStack",
]
resources = [
"arn:aws:cloudformation:${var.aws_region}:${local.account_id}:stack/${local.poc_environment_stack}/*",
]
}
statement {
sid = "PocAsgProcess"
effect = "Allow"
actions = [
"autoscaling:PutNotificationConfiguration",
"autoscaling:ResumeProcesses",
"autoscaling:SuspendProcesses",
]
resources = [
"arn:aws:autoscaling:${var.aws_region}:${local.account_id}:autoScalingGroup:*:autoScalingGroupName/${local.poc_environment_stack}-*",
]
}
statement {
sid = "EbServiceObjects"
effect = "Allow"
actions = ["s3:PutObject"]
resources = [
"arn:aws:s3:::elasticbeanstalk-${var.aws_region}-${local.account_id}/${var.eb_application_name}/*",
]
}
statement {
sid = "EbServiceBuckets"
effect = "Allow"
actions = [
"s3:GetBucketLocation",
"s3:ListBucket",
]
resources = ["arn:aws:s3:::elasticbeanstalk-${var.aws_region}-${local.account_id}"]
}
statement {
sid = "DenyLiveEnvironment"
effect = "Deny"
actions = ["elasticbeanstalk:*"]
resources = [
"arn:aws:elasticbeanstalk:${var.aws_region}:${local.account_id}:environment/shoc-backend/shoc-backend-dev",
]
}
}
resource "aws_iam_role_policy" "github_deploy" {
name = "${var.github_deploy_role_name}-eb"
role = aws_iam_role.github_deploy.id
policy = data.aws_iam_policy_document.github_deploy.json
}