Oof, this one was tough. I've used Github quite a lot before, but never the actions. I didn't want to use the access key route, I wanted to treat this more
as a service account, something you would use in the business world. So I created the OIDC policy and permissions in AWS. I struggled with this for a while
with Terraform not wanting to take what I had... Then of course there was the obligatory missing bracket that I had to hunt down and delete. Thankfully IDE's
generally make that much easier these days. Eventually I actually created the OIDC via the GUI because at this point I can't wrap my head around how often they
would be dynamically created via terraform, but I will research that later.
I moved on to creating the IAM Role, which proved easier, but still required research. One thing to be sure of though, I am still not quite certain what
everything in these terraform scripts means. Resources are great to use, but as I'm getting started I'm still trying to learn all of these values. I can't get
held up trying to be perfect and no it all or I will never make progress.
data "aws_iam_openid_connect_provider" "github_actions" {
url = "https://token.actions.githubusercontent.com"
}
data "aws_iam_policy_document" "github_actions_trust" {
statement {
effect = "Allow"
actions = ["sts:AssumeRoleWithWebIdentity"]
principals {
type = "Federated"
identifiers = [data.aws_iam_openid_connect_provider.github_actions.arn]
}
condition {
test = "StringEquals"
variable = "token.actions.githubusercontent.com:aud"
values = ["sts.amazonaws.com"]
}
condition {
test = "StringLike"
variable = "token.actions.githubusercontent.com:sub"
values = ["repo:--My-Redacted-Account-Name@--My-Redacted-Account-ID/resume@--Redacted-Repo-ID:ref:refs/heads/main"]
}
}
}
resource "aws_iam_role" "github_actions_deploy" {
name = "github-actions-s3-deploy"
assume_role_policy = data.aws_iam_policy_document.github_actions_trust.json
}
One issue I had here actually was that the documentation I found was incorrect, or outdated rather. Instead of just having my github account name and repository name, I also needed to include the IDs in them. I had to look through the Cloudtrail logs to find that AWS was expecting just the account name and repo name, but github was sending the names with the appended IDs. So that was definitely a learning experience I won't forget.
Finally I setup the permission policy to allow github to touch only this bucket. That actually turned out to be the easier of the things I learned today.
data "aws_iam_policy_document" "github_actions_s3_deploy" {
statement {
sid = "ListBucket"
effect = "Allow"
actions = ["s3:ListBucket"]
resources = [aws_s3_bucket.bucketname.arn]
}
statement {
sid = "WriteObjects"
effect = "Allow"
actions = ["s3:PutObject", "s3:DeleteObject"]
resources = ["${aws_s3_bucket.bucketname.arn}/*"]
}
}
resource "aws_iam_role_policy" "github_actions_s3_deploy" {
name = "s3-deploy-policy"
role = aws_iam_role.github_actions_deploy.id
policy = data.aws_iam_policy_document.github_actions_s3_deploy.json
}
output "github_actions_role_arn" {
value = aws_iam_role.github_actions_deploy.arn
}I feel like I have learned a lot. I'll need to review it more though so it sticks.