Skip to content

Commit 1391123

Browse files
Update
1 parent b803e45 commit 1391123

3 files changed

Lines changed: 177 additions & 19 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ permissions:
1111

1212
jobs:
1313
deploy:
14+
name: Deploy
1415
runs-on: ubuntu-latest
1516

1617
steps:

DEPLOYMENT.md

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ This creates `policyengine-api-v2-terraform-state` with versioning enabled.
2020

2121
**Note**: Only needs to be done once.
2222

23-
## Step 2: Set up GitHub OIDC
23+
## Step 2: Set up GitHub OIDC and IAM role
2424

2525
1. Get your AWS account ID:
2626

@@ -36,27 +36,22 @@ aws iam create-open-id-connect-provider \
3636
--client-id-list sts.amazonaws.com
3737
```
3838

39-
3. Create IAM role for GitHub Actions:
40-
- AWS Console → IAM → Roles → Create role
41-
- Trusted entity type: Web identity
42-
- Identity provider: `token.actions.githubusercontent.com`
43-
- Audience: `sts.amazonaws.com`
44-
- GitHub organization: `PolicyEngine`
45-
- GitHub repository: `policyengine-api-v2-alpha`
46-
- GitHub branch: `main`
47-
- Click Next
39+
3. Create/update the IAM role via Terraform:
4840

49-
4. Attach these policies:
50-
- `AmazonECS_FullAccess`
51-
- `AmazonEC2ContainerRegistryPowerUser`
52-
- `IAMFullAccess`
53-
- `AmazonVPCFullAccess`
54-
- `CloudWatchLogsFullAccess`
55-
- `TerraformStateAccess` (custom policy created earlier)
41+
```bash
42+
cd terraform
43+
terraform init
44+
terraform import aws_iam_role.github_actions GitHubActionsDeployRole 2>/dev/null || echo "Role doesn't exist yet, will be created"
45+
terraform apply -target=aws_iam_role.github_actions -target=aws_iam_role_policy.github_actions_deploy
46+
```
5647

57-
5. Name the role: `GitHubActionsDeployRole`
48+
This creates the `GitHubActionsDeployRole` with all required permissions for ECS, ECR, ElastiCache, Load Balancers, VPC, CloudWatch, IAM, and S3.
5849

59-
6. Copy the role ARN: `arn:aws:iam::YOUR_ACCOUNT_ID:role/GitHubActionsDeployRole`
50+
4. Copy the role ARN from Terraform output:
51+
52+
```bash
53+
terraform output github_actions_role_arn
54+
```
6055

6156
## Step 3: Configure GitHub secrets and variables
6257

@@ -165,6 +160,18 @@ Any push to `main` automatically:
165160

166161
## Troubleshooting
167162

163+
### Account doesn't support creating load balancers
164+
165+
If you see "This AWS account currently does not support creating load balancers":
166+
167+
1. Open AWS Support Center
168+
2. Create case: Service limit increase
169+
3. Select: Elastic Load Balancing
170+
4. Request: Enable Application Load Balancer creation
171+
5. Explain: Need ALB for ECS deployment
172+
173+
This typically takes 24-48 hours for new AWS accounts. Alternatively, check your account has valid payment method and is in good standing.
174+
168175
### GitHub Actions can't assume role
169176

170177
Trust policy must match your repo exactly:

terraform/iam.tf

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# GitHub Actions OIDC provider
2+
data "aws_iam_openid_connect_provider" "github" {
3+
url = "https://token.actions.githubusercontent.com"
4+
}
5+
6+
# IAM role for GitHub Actions
7+
resource "aws_iam_role" "github_actions" {
8+
name = "GitHubActionsDeployRole"
9+
10+
assume_role_policy = jsonencode({
11+
Version = "2012-10-17"
12+
Statement = [
13+
{
14+
Effect = "Allow"
15+
Principal = {
16+
Federated = data.aws_iam_openid_connect_provider.github.arn
17+
}
18+
Action = "sts:AssumeRoleWithWebIdentity"
19+
Condition = {
20+
StringEquals = {
21+
"token.actions.githubusercontent.com:aud" = "sts.amazonaws.com"
22+
}
23+
StringLike = {
24+
"token.actions.githubusercontent.com:sub" = "repo:PolicyEngine/policyengine-api-v2-alpha:*"
25+
}
26+
}
27+
}
28+
]
29+
})
30+
31+
tags = {
32+
Name = "GitHubActionsDeployRole"
33+
}
34+
}
35+
36+
# Custom policy for GitHub Actions with all required permissions
37+
resource "aws_iam_role_policy" "github_actions_deploy" {
38+
name = "GitHubActionsDeployPolicy"
39+
role = aws_iam_role.github_actions.id
40+
41+
policy = jsonencode({
42+
Version = "2012-10-17"
43+
Statement = [
44+
{
45+
Effect = "Allow"
46+
Action = [
47+
# ECR permissions
48+
"ecr:*"
49+
]
50+
Resource = "*"
51+
},
52+
{
53+
Effect = "Allow"
54+
Action = [
55+
# ECS permissions
56+
"ecs:*"
57+
]
58+
Resource = "*"
59+
},
60+
{
61+
Effect = "Allow"
62+
Action = [
63+
# ElastiCache permissions
64+
"elasticache:*"
65+
]
66+
Resource = "*"
67+
},
68+
{
69+
Effect = "Allow"
70+
Action = [
71+
# Load Balancer permissions
72+
"elasticloadbalancing:*"
73+
]
74+
Resource = "*"
75+
},
76+
{
77+
Effect = "Allow"
78+
Action = [
79+
# VPC and networking permissions
80+
"ec2:*"
81+
]
82+
Resource = "*"
83+
},
84+
{
85+
Effect = "Allow"
86+
Action = [
87+
# CloudWatch Logs permissions
88+
"logs:*"
89+
]
90+
Resource = "*"
91+
},
92+
{
93+
Effect = "Allow"
94+
Action = [
95+
# IAM permissions (for creating roles)
96+
"iam:GetRole",
97+
"iam:GetRolePolicy",
98+
"iam:CreateRole",
99+
"iam:DeleteRole",
100+
"iam:AttachRolePolicy",
101+
"iam:DetachRolePolicy",
102+
"iam:PutRolePolicy",
103+
"iam:DeleteRolePolicy",
104+
"iam:TagRole",
105+
"iam:PassRole",
106+
"iam:ListAttachedRolePolicies",
107+
"iam:ListRolePolicies",
108+
"iam:GetPolicyVersion",
109+
"iam:GetPolicy",
110+
"iam:ListPolicyVersions"
111+
]
112+
Resource = "*"
113+
},
114+
{
115+
Effect = "Allow"
116+
Action = [
117+
# S3 permissions for Terraform state
118+
"s3:GetObject",
119+
"s3:PutObject",
120+
"s3:DeleteObject",
121+
"s3:ListBucket",
122+
"s3:GetBucketVersioning",
123+
"s3:PutBucketVersioning"
124+
]
125+
Resource = [
126+
"arn:aws:s3:::policyengine-api-v2-terraform-state",
127+
"arn:aws:s3:::policyengine-api-v2-terraform-state/*"
128+
]
129+
},
130+
{
131+
Effect = "Allow"
132+
Action = [
133+
# DynamoDB for Terraform state locking
134+
"dynamodb:GetItem",
135+
"dynamodb:PutItem",
136+
"dynamodb:DeleteItem",
137+
"dynamodb:DescribeTable",
138+
"dynamodb:CreateTable"
139+
]
140+
Resource = "arn:aws:dynamodb:*:*:table/terraform-state-lock"
141+
}
142+
]
143+
})
144+
}
145+
146+
# Output the role ARN for reference
147+
output "github_actions_role_arn" {
148+
description = "ARN of the GitHub Actions IAM role"
149+
value = aws_iam_role.github_actions.arn
150+
}

0 commit comments

Comments
 (0)