Skip to content

Commit

Permalink
Merge pull request #17 from liatrio/make-more-dry
Browse files Browse the repository at this point in the history
  • Loading branch information
jburns24 authored Sep 21, 2023
2 parents 53f7778 + 9eac371 commit 14deffb
Show file tree
Hide file tree
Showing 15 changed files with 153 additions and 42 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/build-infra.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@ on:
- main
workflow_dispatch: {}

# permissions:
# id-token: write # Needed to modify JWT token for OIDC
# contents: read # Needed for actions/checkout


jobs:
run:
name: run
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v3

Expand All @@ -26,6 +32,7 @@ jobs:
aws-access-key-id: ${{ secrets.PERSONAL_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.PERSONAL_SECRET_ACCESS_KEY }}
role-to-assume: ${{ secrets.ROLE_TO_ASSUME }}
# role-to-assume: ${{ vars.OIDC_ROLE }}
aws-region: ${{ vars.AWS_REGION }}
role-skip-session-tagging: true

Expand Down
6 changes: 3 additions & 3 deletions terraform/_outputs.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
output "ecr_repository_url" {
value = aws_ecr_repository.knowledgeshare_ui_ecr.repository_url
value = aws_ecr_repository.knowledgeshare_ui_ecr.repository_url
description = "URL of the ECR repository"
}

Expand All @@ -14,11 +14,11 @@ output "ecs_cluster_arn" {
}

output "ecs_task_arn" {
value = aws_ecs_task_definition.knowledgeshare_ui_task.arn
value = data.aws_ecs_task_definition.current_task.arn
description = "ARN of the ECS task definition"
}

output "ecs_service_arn" {
value = aws_ecs_service.knowledgeshare_ui_service.id
value = aws_ecs_service.knowledgeshare_ui_service.id
description = "ARN of the ECS Service"
}
2 changes: 1 addition & 1 deletion terraform/_terraform.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ terraform {
}

provider "aws" {
region = "us-west-2"
region = var.aws_region
}
8 changes: 7 additions & 1 deletion terraform/_varibales.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
variable "name" {
type = string
description = "The Repository Name"
default = "keyless-workflow-demo"
default = "keyless-workflow-demo"
}

variable "tfstate_bucket" {}

variable "tfstate_dynamodb_table" {}

variable "aws_region" {}
8 changes: 4 additions & 4 deletions terraform/backend.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "s3" {
bucket = "keyless-workflow-demo"
dynamodb_table = "tflocks"
bucket = "keyless-workflow-demo-tfstate"
dynamodb_table = "keyless-demo-tflock"
encrypt = true
key = "keyless-workflow-demo/terraform.tfstate"
region = "us-west-2"
key = "./terraform.tfstate"
region = "us-east-2"
}
}
2 changes: 1 addition & 1 deletion terraform/ecr.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
resource "aws_ecr_repository" "knowledgeshare_ui_ecr" {
name = var.name
force_delete = true
force_delete = true
image_tag_mutability = "MUTABLE"

image_scanning_configuration {
Expand Down
32 changes: 18 additions & 14 deletions terraform/ecs.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
resource "aws_ecs_cluster" "knowledgeshare_ui_ecs_cluster" {
name = "knowledgeshare-demo-clster"
setting {
name = "containerInsights"
name = "containerInsights"
value = "enabled"
}
}
Expand Down Expand Up @@ -30,36 +30,40 @@ resource "aws_iam_role_policy_attachment" "ecs_execution_role_attachment" {
}

resource "aws_ecs_task_definition" "knowledgeshare_ui_task" {
family = "keyless-workflow-demo-td"
family = "keyless-workflow-demo-td"
network_mode = "awsvpc" # FARGATE requires awsvpc from what I can tell
requires_compatibilities = ["FARGATE"]
cpu = "1024" # Choose based on your requirements
memory = "2048" # Choose based on your requirements
cpu = "1024" # Choose based on your requirements
memory = "2048" # Choose based on your requirements
execution_role_arn = aws_iam_role.ecs_execution_role.arn # FARGATE also requires this role to fetch images from ECR

container_definitions = jsonencode([{
name = "knowledgeshare-ui" # TODO make this a variable that can be made into output so we can fetch programatically
image = "${aws_ecr_repository.knowledgeshare_ui_ecr.repository_url}:latest"
name = "knowledgeshare-ui" # TODO make this a variable that can be made into output so we can fetch programatically
image = "${aws_ecr_repository.knowledgeshare_ui_ecr.repository_url}:latest"
essential = true
portMappings = [
{
containerPort = 3000
hostPort = 3000
hostPort = 3000
}
]
}])
}

data "aws_ecs_task_definition" "current_task" {
task_definition = aws_ecs_task_definition.knowledgeshare_ui_task.family
}

resource "aws_ecs_service" "knowledgeshare_ui_service" {
name = "knowledgeshare_ui"
launch_type = "FARGATE"
cluster = aws_ecs_cluster.knowledgeshare_ui_ecs_cluster.id
task_definition = aws_ecs_task_definition.knowledgeshare_ui_task.arn
desired_count = 1
name = "knowledgeshare_ui"
launch_type = "FARGATE"
cluster = aws_ecs_cluster.knowledgeshare_ui_ecs_cluster.id
task_definition = data.aws_ecs_task_definition.current_task.arn
desired_count = 1
force_new_deployment = true
network_configuration {
subnets = [aws_subnet.public_subnet_a.id, aws_subnet.public_subnet_b.id]
security_groups = [aws_security_group.keyless_workflow_demo_sg.id]
subnets = [aws_subnet.public_subnet_a.id, aws_subnet.public_subnet_b.id]
security_groups = [aws_security_group.keyless_workflow_demo_sg.id]
assign_public_ip = true
}
# iam_role = aws_iam_role.foo.arn
Expand Down
4 changes: 4 additions & 0 deletions terraform/oidc/_outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "gha_role_arn" {
description = "ARN of the GitHub Action OIDC role"
value = aws_iam_role.gha_role.arn
}
8 changes: 8 additions & 0 deletions terraform/oidc/_variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,11 @@ variable "ecr_repository_arn" {
description = "ARN of the ECR repository"
type = string
}

variable "tfstate_bucket" {}

variable "tfstate_dynamodb_table" {}

variable "aws_region" {}

variable "ecs_service_arn" {}
10 changes: 10 additions & 0 deletions terraform/oidc/backend.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "s3" {
bucket = "keyless-workflow-demo-tfstate"
dynamodb_table = "keyless-demo-tflock"
encrypt = true
key = "oidc/terraform.tfstate"
region = "us-east-2"
}
}
70 changes: 63 additions & 7 deletions terraform/oidc/main.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
data "tls_certificate" "github_thumbprint" {
url = "https://token.actions.githubusercontent.com/.well-known/openid-configuration"
}

## Uncomment this block of code if you are testing this in a personal aws account
## This is a central resource that in my org is not managed via terraform and thus
## including this resouce causes issues.
Expand All @@ -17,6 +13,10 @@ data "tls_certificate" "github_thumbprint" {
# ]
# }

data "tls_certificate" "github_thumbprint" {
url = "https://token.actions.githubusercontent.com/.well-known/openid-configuration"
}

data "aws_iam_openid_connect_provider" "github" {
url = "https://token.actions.githubusercontent.com"
}
Expand All @@ -35,8 +35,32 @@ resource "aws_iam_policy" "ecs_ecr_policy" {
],
Resource = [
var.ecs_cluster_arn, # ARN of the ECS cluster
replace(var.ecs_task_arn, "/:\\d+$/", ":*") # ARN of the ECS task definition
# Add ARNs of other ECS resources if needed
var.ecs_service_arn, # ARN of the ECS service
replace(var.ecs_task_arn, "/:\\d+$/", ":*") # ARN that matches all task-definition revisions for the task definition created in this repo
]
},
{
Effect = "Allow",
Action = [
"ecs:DescribeTaskDefinition",
"ecs:RegisterTaskDefinition"
],
Resource = [ "*" ]
},
{
Effect = "Allow",
Action = [
"iam:PassRole"
],
Resource = [ "*" ]
},
{
Effect = "Allow",
Action = [
"ecr:GetAuthorizationToken",
],
Resource = [
"*"
]
},
{
Expand All @@ -52,6 +76,38 @@ resource "aws_iam_policy" "ecs_ecr_policy" {
})
}

resource "aws_iam_policy" "terraform_read" {
name = "terraform_read"
description = "Policy that gives permissions to access the backend s3 bucket the tf state file is stored"

policy = jsonencode({
"Version": "2012-10-17",
"Statement": [
{
"Sid": "TerraformStateS3ReadPermissions",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::${var.tfstate_bucket}",
"arn:aws:s3:::${var.tfstate_bucket}/*"
]
},
{
"Sid": "TerraformStateDynamoDBReadPermissions",
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:DescribeTable",
],
"Resource": "arn:aws:dynamodb:${var.aws_region}:*:table/${var.tfstate_dynamodb_table}"
}
]
})
}

data "aws_iam_policy_document" "gha_trust_policy" {
statement {
Expand All @@ -77,5 +133,5 @@ data "aws_iam_policy_document" "gha_trust_policy" {
resource "aws_iam_role" "gha_role" {
name = "gha_role"
assume_role_policy = data.aws_iam_policy_document.gha_trust_policy.json
managed_policy_arns = [aws_iam_policy.ecs_ecr_policy.arn]
managed_policy_arns = [aws_iam_policy.ecs_ecr_policy.arn, aws_iam_policy.terraform_read.arn]
}
5 changes: 5 additions & 0 deletions terraform/oidc/terragrunt.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,9 @@ inputs = {
ecs_cluster_arn = dependency.parent_outputs.outputs.ecs_cluster_arn
ecs_task_arn = dependency.parent_outputs.outputs.ecs_task_arn
ecr_repository_arn = dependency.parent_outputs.outputs.ecr_repository_arn
ecs_service_arn = dependency.parent_outputs.outputs.ecs_service_arn
}

include {
path = find_in_parent_folders()
}
3 changes: 3 additions & 0 deletions terraform/shared.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
tfstate_bucket = "keyless-workflow-demo-tfstate"
tfstate_dynamodb_table = "keyless-demo-tflock"
aws_region = "us-east-2"
22 changes: 15 additions & 7 deletions terraform/terragrunt.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ remote_state {
if_exists = "overwrite_terragrunt"
}
config = {
bucket = "keyless-workflow-demo"
key = "keyless-workflow-demo/terraform.tfstate"
bucket = "keyless-workflow-demo-tfstate"
key = "${path_relative_to_include()}/terraform.tfstate"

region = "us-west-2"
dynamodb_table = "tflocks"
region = "us-east-2"
dynamodb_table = "keyless-demo-tflock"
disable_bucket_update = true

# Permissions thing
Expand All @@ -19,6 +19,14 @@ remote_state {
}
}

# terraform {
# source = ".//tf"
# }
# This block will read all variables in shared.tfvars and append them
# to all terrform commands that accept inputs
terraform {
extra_arguments "shared_vars" {
commands = get_terraform_commands_that_need_vars()
optional_var_files = [
"${get_parent_terragrunt_dir()}/shared.tfvars",
"${find_in_parent_folders("shared.tfvars", "ignore")}"
]
}
}
8 changes: 4 additions & 4 deletions terraform/vpc.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ resource "aws_vpc" "keyless_workflow_demo_vpc" {
resource "aws_subnet" "public_subnet_a" {
vpc_id = aws_vpc.keyless_workflow_demo_vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-west-2a" # Adjust as needed
map_public_ip_on_launch = true # This will give instances in this subnet a public IP by default
availability_zone = "${var.aws_region}a" # Adjust as needed
map_public_ip_on_launch = true # This will give instances in this subnet a public IP by default
tags = {
Name = "keyless_workflow_demo_subnet"
}
Expand All @@ -20,8 +20,8 @@ resource "aws_subnet" "public_subnet_a" {
resource "aws_subnet" "public_subnet_b" {
vpc_id = aws_vpc.keyless_workflow_demo_vpc.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-west-2b" # Adjust as needed
map_public_ip_on_launch = true # This will give instances in this subnet a public IP by default
availability_zone = "${var.aws_region}b" # Adjust as needed
map_public_ip_on_launch = true # This will give instances in this subnet a public IP by default
tags = {
Name = "keyless_workflow_demo_subnet"
}
Expand Down

0 comments on commit 14deffb

Please sign in to comment.