Skip to content

Commit ce4d106

Browse files
authored
ci: Add workflow to launch a tools container. (#30)
1 parent e712dc9 commit ce4d106

File tree

13 files changed

+268
-106
lines changed

13 files changed

+268
-106
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Setup OpenTofu
2+
description: Sets up OpenTofu and related environment variables
3+
inputs:
4+
config:
5+
description: OpenTofu configuration to initialize.
6+
required: true
7+
default: service
8+
runs:
9+
using: composite
10+
steps:
11+
- name: Cache OpenTofu
12+
uses: actions/cache@v4
13+
with:
14+
path: ./tofu/config/${{ inputs.config }}/.terraform
15+
key: ${{ runner.os }}-tofu-${{ hashFiles('./tofu/config/${{ inputs.config }}/.terraform.lock.hcl') }}
16+
restore-keys: |
17+
${{ runner.os }}-tofu-
18+
- name: Setup OpenTofu
19+
uses: opentofu/setup-opentofu@v1
20+
with:
21+
tofu_wrapper: false
22+
- name: Display OpenTofu version
23+
shell: bash
24+
run: tofu version
25+
- name: Set optional variables
26+
shell: bash
27+
run: |
28+
variables=(
29+
"apply_database_updates_immediately" "consumer_container_count"
30+
"consumer_cpu" "consumer_memory" "database_instance_count"
31+
"database_skip_final_snapshot" "deletion_protection"
32+
"deployment_environments" "environment" "export_expiration"
33+
"image_tags_mutable" "key_recovery_period" "program" "project" "repository"
34+
)
35+
for var in ${variables[@]}; do
36+
name="TF_VAR_$(echo $var | tr '[:lower:]' '[:upper:]')"
37+
if [ -n "${!name}" ]; then
38+
echo "Setting TF_VAR_$var"
39+
echo "TF_VAR_$var=${!name}" >> $GITHUB_ENV
40+
else
41+
echo "$name is not set"
42+
fi
43+
done
44+
- name: Initialize OpenTofu
45+
shell: bash
46+
working-directory: ./tofu/config/${{ inputs.config }}
47+
run: tofu init

.github/workflows/deploy.yaml

Lines changed: 24 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -80,55 +80,35 @@ jobs:
8080
aws-region: ${{ secrets.AWS_REGION || 'us-west-1' }}
8181
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
8282
role-session-name: GitHub_to_AWS_via_FederatedOIDC
83-
- name: Setup OpenTofu
84-
uses: opentofu/setup-opentofu@v1
85-
with:
86-
tofu_wrapper: false
87-
- name: Display OpenTofu version
88-
run: tofu version
89-
- name: Set optional variables
90-
env:
91-
# For any of these that have a value, the corresponding TF_VAR_*
92-
# environment variable will be set.
93-
APPLY_DATABASE_UPDATES_IMMEDIATELY: ${{ secrets.TF_VAR_APPLY_DATABASE_UPDATES_IMMEDIATELY }}
94-
TF_VAR_CONSUMER_CONTAINER_COUNT: ${{ secrets.TF_VAR_CONSUMER_CONTAINER_COUNT }}
95-
CONSUMER_CPU: ${{ secrets.TF_VAR_CONSUMER_CPU }}
96-
CONSUMER_MEMORY: ${{ secrets.TF_VAR_CONSUMER_MEMORY }}
97-
DATABASE_SKIP_FINAL_SNAPSHOT: ${{ secrets.TF_VAR_DATABASE_SKIP_FINAL_SNAPSHOT }}
98-
DELETION_PROTECTION: ${{ secrets.TF_VAR_DELETION_PROTECTION }}
99-
DEPLOYMENT_ENVIRONMENTS: ${{ secrets.TF_VAR_DEPLOYMENT_ENVIRONMENTS }}
100-
ENVIRONMENT: ${{ secrets.TF_VAR_ENVIRONMENT }}
101-
EXPORT_EXPIRATION: ${{ secrets.TF_VAR_EXPORT_EXPIRATION }}
102-
IMAGE_TAGS_MUTABLE: ${{ secrets.TF_VAR_IMAGE_TAGS_MUTABLE }}
103-
KEY_RECOVERY_PERIOD: ${{ secrets.TF_VAR_KEY_RECOVERY_PERIOD }}
104-
PROGRAM: ${{ secrets.TF_VAR_PROGRAM }}
105-
PROJECT: ${{ secrets.TF_VAR_PROJECT }}
106-
REPOSITORY: ${{ secrets.TF_VAR_REPOSITORY }}
107-
run: |
108-
variables=(
109-
"apply_database_updates_immediately" "consumer_container_count"
110-
"consumer_cpu" "consumer_memory" "database_skip_final_snapshot"
111-
"deletion_protection" "deployment_environments" "environment"
112-
"export_expiration" "image_tags_mutable" "key_recovery_period"
113-
"program" "project" "repository"
114-
)
115-
for var in ${variables[@]}; do
116-
name="$(echo $var | tr '[:lower:]' '[:upper:]')"
117-
if [ -n "${!name}" ]; then
118-
echo "Setting TF_VAR_$var"
119-
echo "TF_VAR_$var=${!name}" >> $GITHUB_ENV
120-
else
121-
echo "$name is not set"
122-
fi
123-
done
12483
- name: Download plan file
12584
uses: actions/download-artifact@v4
12685
with:
12786
name: ${{ inputs.config }}-tfplan
12887
path: ./tofu/config/${{ inputs.config }}
129-
- name: Initialize OpenTofu
130-
working-directory: ./tofu/config/${{ inputs.config }}
131-
run: tofu init
88+
- name: Setup OpenTofu
89+
uses: ./.github/actions/setup-opentofu
90+
env:
91+
TF_VAR_APPLY_DATABASE_UPDATES_IMMEDIATELY: ${{ secrets.TF_VAR_APPLY_DATABASE_UPDATES_IMMEDIATELY }}
92+
TF_VAR_CONSUMER_CONTAINER_COUNT: ${{ secrets.TF_VAR_CONSUMER_CONTAINER_COUNT }}
93+
TF_VAR_CONSUMER_CPU: ${{ secrets.TF_VAR_CONSUMER_CPU }}
94+
TF_VAR_CONSUMER_MEMORY: ${{ secrets.TF_VAR_CONSUMER_MEMORY }}
95+
TF_VAR_DATABASE_SKIP_FINAL_SNAPSHOT: ${{ secrets.TF_VAR_DATABASE_SKIP_FINAL_SNAPSHOT }}
96+
TF_VAR_DATABASE_INSTANCE_COUNT: ${{ secrets.TF_VAR_DATABASE_INSTANCE_COUNT }}
97+
TF_VAR_DELETION_PROTECTION: ${{ secrets.TF_VAR_DELETION_PROTECTION }}
98+
TF_VAR_DEPLOYMENT_ENVIRONMENTS: ${{ secrets.TF_VAR_DEPLOYMENT_ENVIRONMENTS }}
99+
TF_VAR_ENVIRONMENT: ${{ inputs.environment }}
100+
TF_VAR_EXPORT_EXPIRATION: ${{ secrets.TF_VAR_EXPORT_EXPIRATION }}
101+
TF_VAR_IMAGE_TAGS_MUTABLE: ${{ secrets.TF_VAR_IMAGE_TAGS_MUTABLE }}
102+
TF_VAR_KEY_RECOVERY_PERIOD: ${{ secrets.TF_VAR_KEY_RECOVERY_PERIOD }}
103+
TF_VAR_PROJECT: ${{ secrets.TF_VAR_PROJECT }}
104+
TF_VAR_PROGRAM: ${{ secrets.TF_VAR_PROGRAM }}
105+
TF_VAR_REPO_OIDC_ARN: ${{ secrets.TF_VAR_REPO_OIDC_ARN }}
106+
TF_VAR_REPOSITORY: ${{ secrets.TF_VAR_REPOSITORY }}
107+
TF_VAR_VPC_CIDR: ${{ secrets.TF_VAR_VPC_CIDR }}
108+
TF_VAR_VPC_PRIVATE_SUBNET_CIDRS: ${{ secrets.TF_VAR_VPC_PRIVATE_SUBNET_CIDRS }}
109+
TF_VAR_VPC_PUBLIC_SUBNET_CIDRS: ${{ secrets.TF_VAR_VPC_PUBLIC_SUBNET_CIDRS }}
110+
with:
111+
config: ${{ inputs.config }}
132112
- name: Deploy changes
133113
working-directory: ./tofu/config/${{ inputs.config }}
134114
run: tofu apply tfplan
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
name: Launch tools container
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
environment:
7+
description: Environment to destroy.
8+
default: development
9+
required: true
10+
type: environment
11+
command:
12+
description: |
13+
Command to run in the tools container in the CMD format: executable,
14+
param1, param2, ...
15+
default: "echo,hello world"
16+
required: true
17+
type: string
18+
19+
permissions:
20+
contents: read
21+
id-token: write
22+
23+
jobs:
24+
launch:
25+
name: Launch tools container in ${{ inputs.environment }}
26+
runs-on: ubuntu-latest
27+
environment: ${{ inputs.environment }}
28+
env:
29+
# Set required variables.
30+
TF_VAR_repo_oidc_arn: ${{ secrets.TF_VAR_REPO_OIDC_ARN }}
31+
TF_VAR_vpc_cidr: ${{ secrets.TF_VAR_VPC_CIDR }}
32+
TF_VAR_vpc_private_subnet_cidrs: ${{ secrets.TF_VAR_VPC_PRIVATE_SUBNET_CIDRS }}
33+
TF_VAR_vpc_public_subnet_cidrs: ${{ secrets.TF_VAR_VPC_PUBLIC_SUBNET_CIDRS }}
34+
steps:
35+
- name: Checkout code
36+
uses: actions/checkout@v4
37+
- name: Set up AWS credentials
38+
uses: aws-actions/configure-aws-credentials@v4
39+
with:
40+
aws-region: ${{ secrets.AWS_REGION || 'us-west-1' }}
41+
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
42+
role-session-name: GitHub_to_AWS_via_FederatedOIDC
43+
- name: Setup OpenTofu
44+
uses: ./.github/actions/setup-opentofu
45+
env:
46+
TF_VAR_APPLY_DATABASE_UPDATES_IMMEDIATELY: ${{ secrets.TF_VAR_APPLY_DATABASE_UPDATES_IMMEDIATELY }}
47+
TF_VAR_CONSUMER_CONTAINER_COUNT: ${{ secrets.TF_VAR_CONSUMER_CONTAINER_COUNT }}
48+
TF_VAR_CONSUMER_CPU: ${{ secrets.TF_VAR_CONSUMER_CPU }}
49+
TF_VAR_CONSUMER_MEMORY: ${{ secrets.TF_VAR_CONSUMER_MEMORY }}
50+
TF_VAR_DATABASE_SKIP_FINAL_SNAPSHOT: ${{ secrets.TF_VAR_DATABASE_SKIP_FINAL_SNAPSHOT }}
51+
TF_VAR_DATABASE_INSTANCE_COUNT: ${{ secrets.TF_VAR_DATABASE_INSTANCE_COUNT }}
52+
TF_VAR_DELETION_PROTECTION: ${{ secrets.TF_VAR_DELETION_PROTECTION }}
53+
TF_VAR_DEPLOYMENT_ENVIRONMENTS: ${{ secrets.TF_VAR_DEPLOYMENT_ENVIRONMENTS }}
54+
TF_VAR_ENVIRONMENT: ${{ inputs.environment }}
55+
TF_VAR_EXPORT_EXPIRATION: ${{ secrets.TF_VAR_EXPORT_EXPIRATION }}
56+
TF_VAR_IMAGE_TAGS_MUTABLE: ${{ secrets.TF_VAR_IMAGE_TAGS_MUTABLE }}
57+
TF_VAR_KEY_RECOVERY_PERIOD: ${{ secrets.TF_VAR_KEY_RECOVERY_PERIOD }}
58+
TF_VAR_PROJECT: ${{ secrets.TF_VAR_PROJECT }}
59+
TF_VAR_PROGRAM: ${{ secrets.TF_VAR_PROGRAM }}
60+
TF_VAR_REPO_OIDC_ARN: ${{ secrets.TF_VAR_REPO_OIDC_ARN }}
61+
TF_VAR_REPOSITORY: ${{ secrets.TF_VAR_REPOSITORY }}
62+
TF_VAR_VPC_CIDR: ${{ secrets.TF_VAR_VPC_CIDR }}
63+
TF_VAR_VPC_PRIVATE_SUBNET_CIDRS: ${{ secrets.TF_VAR_VPC_PRIVATE_SUBNET_CIDRS }}
64+
TF_VAR_VPC_PUBLIC_SUBNET_CIDRS: ${{ secrets.TF_VAR_VPC_PUBLIC_SUBNET_CIDRS }}
65+
with:
66+
config: service
67+
- name: Get OpenTofu outputs
68+
id: outputs
69+
working-directory: ./tofu/config/service
70+
run: |
71+
OUTPUTS=$(tofu output -json | jq -c)
72+
echo "OUTPUTS=$OUTPUTS"
73+
echo "outputs=$OUTPUTS" >> $GITHUB_OUTPUT
74+
- name: Parse subnets
75+
id: subnets
76+
env:
77+
SUBNETS: ${{ toJson(fromJson(steps.outputs.outputs.outputs).container_subnets.value) }}
78+
run: |
79+
SUBNET_STRING=$(echo "$SUBNETS" | jq -r '.[]')
80+
echo "subnets<<EOF" >> $GITHUB_OUTPUT
81+
echo "$SUBNET_STRING" >> $GITHUB_OUTPUT
82+
echo "EOF" >> $GITHUB_OUTPUT
83+
- name: Parse command
84+
id: command
85+
env:
86+
COMMAND: ${{ inputs.command }}
87+
run: |
88+
IFS=',' read -ra parts <<< "$COMMAND"
89+
COMMAND_STRING=$(printf "%s\n" "${parts[@]}")
90+
echo "command<<EOF" >> $GITHUB_OUTPUT
91+
echo "$COMMAND_STRING" >> $GITHUB_OUTPUT
92+
echo "EOF" >> $GITHUB_OUTPUT
93+
- name: Launch container
94+
id: run-task
95+
uses: geekcell/github-action-aws-ecs-run-task@v5
96+
with:
97+
cluster: ${{ secrets.TF_VAR_PROJECT }}-${{ secrets.TF_VAR_ENVIRONMENT }}
98+
task-definition: ${{ secrets.TF_VAR_PROJECT }}-${{ secrets.TF_VAR_ENVIRONMENT }}-tools
99+
override-container: ${{ secrets.TF_VAR_PROJECT }}-${{ secrets.TF_VAR_ENVIRONMENT }}-tools
100+
assign-public-ip: DISABLED
101+
tail-logs: true
102+
task-wait-until-stopped: true
103+
# The block style indicator (|) is necessary to tell YAML to preserve
104+
# newlines.
105+
override-container-command: |
106+
${{ steps.command.outputs.command }}
107+
subnet-ids: |
108+
${{ steps.subnets.outputs.subnets }}
109+
security-group-ids: |
110+
${{ fromJson(steps.outputs.outputs.outputs).task_security_group_id.value }}

.github/workflows/plan.yaml

Lines changed: 25 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ on:
6868
default: development
6969
required: true
7070
type: environment
71+
image_tag:
72+
description: (Optional) Image tag to use for the OpenTofu containers. Defaults to latest SHA.
73+
required: false
74+
type: string
7175

7276
permissions:
7377
contents: read
@@ -95,49 +99,29 @@ jobs:
9599
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
96100
role-session-name: GitHub_to_AWS_via_FederatedOIDC
97101
- name: Setup OpenTofu
98-
uses: opentofu/setup-opentofu@v1
99-
with:
100-
tofu_wrapper: false
101-
- name: Display OpenTofu version
102-
run: tofu version
103-
- name: Set optional variables
102+
uses: ./.github/actions/setup-opentofu
104103
env:
105-
# For any of these that have a value, the corresponding TF_VAR_*
106-
# environment variable will be set.
107-
APPLY_DATABASE_UPDATES_IMMEDIATELY: ${{ secrets.TF_VAR_APPLY_DATABASE_UPDATES_IMMEDIATELY }}
104+
TF_VAR_APPLY_DATABASE_UPDATES_IMMEDIATELY: ${{ secrets.TF_VAR_APPLY_DATABASE_UPDATES_IMMEDIATELY }}
108105
TF_VAR_CONSUMER_CONTAINER_COUNT: ${{ secrets.TF_VAR_CONSUMER_CONTAINER_COUNT }}
109-
CONSUMER_CPU: ${{ secrets.TF_VAR_CONSUMER_CPU }}
110-
CONSUMER_MEMORY: ${{ secrets.TF_VAR_CONSUMER_MEMORY }}
111-
DATABASE_SKIP_FINAL_SNAPSHOT: ${{ secrets.TF_VAR_DATABASE_SKIP_FINAL_SNAPSHOT }}
112-
DELETION_PROTECTION: ${{ secrets.TF_VAR_DELETION_PROTECTION }}
113-
DEPLOYMENT_ENVIRONMENTS: ${{ secrets.TF_VAR_DEPLOYMENT_ENVIRONMENTS }}
114-
ENVIRONMENT: ${{ secrets.TF_VAR_ENVIRONMENT }}
115-
EXPORT_EXPIRATION: ${{ secrets.TF_VAR_EXPORT_EXPIRATION }}
116-
IMAGE_TAGS_MUTABLE: ${{ secrets.TF_VAR_IMAGE_TAGS_MUTABLE }}
117-
KEY_RECOVERY_PERIOD: ${{ secrets.TF_VAR_KEY_RECOVERY_PERIOD }}
118-
PROGRAM: ${{ secrets.TF_VAR_PROGRAM }}
119-
PROJECT: ${{ secrets.TF_VAR_PROJECT }}
120-
REPOSITORY: ${{ secrets.TF_VAR_REPOSITORY }}
121-
run: |
122-
variables=(
123-
"apply_database_updates_immediately" "consumer_container_count"
124-
"consumer_cpu" "consumer_memory" "database_skip_final_snapshot"
125-
"deletion_protection" "deployment_environments" "environment"
126-
"export_expiration" "image_tags_mutable" "key_recovery_period"
127-
"program" "project" "repository"
128-
)
129-
for var in ${variables[@]}; do
130-
name="$(echo $var | tr '[:lower:]' '[:upper:]')"
131-
if [ -n "${!name}" ]; then
132-
echo "Setting TF_VAR_$var"
133-
echo "TF_VAR_$var=${!name}" >> $GITHUB_ENV
134-
else
135-
echo "$name is not set"
136-
fi
137-
done
138-
- name: Initialize OpenTofu
139-
working-directory: ./tofu/config/${{ inputs.config }}
140-
run: tofu init
106+
TF_VAR_CONSUMER_CPU: ${{ secrets.TF_VAR_CONSUMER_CPU }}
107+
TF_VAR_CONSUMER_MEMORY: ${{ secrets.TF_VAR_CONSUMER_MEMORY }}
108+
TF_VAR_DATABASE_SKIP_FINAL_SNAPSHOT: ${{ secrets.TF_VAR_DATABASE_SKIP_FINAL_SNAPSHOT }}
109+
TF_VAR_DATABASE_INSTANCE_COUNT: ${{ secrets.TF_VAR_DATABASE_INSTANCE_COUNT }}
110+
TF_VAR_DELETION_PROTECTION: ${{ secrets.TF_VAR_DELETION_PROTECTION }}
111+
TF_VAR_DEPLOYMENT_ENVIRONMENTS: ${{ secrets.TF_VAR_DEPLOYMENT_ENVIRONMENTS }}
112+
TF_VAR_ENVIRONMENT: ${{ inputs.environment }}
113+
TF_VAR_EXPORT_EXPIRATION: ${{ secrets.TF_VAR_EXPORT_EXPIRATION }}
114+
TF_VAR_IMAGE_TAGS_MUTABLE: ${{ secrets.TF_VAR_IMAGE_TAGS_MUTABLE }}
115+
TF_VAR_KEY_RECOVERY_PERIOD: ${{ secrets.TF_VAR_KEY_RECOVERY_PERIOD }}
116+
TF_VAR_PROJECT: ${{ secrets.TF_VAR_PROJECT }}
117+
TF_VAR_PROGRAM: ${{ secrets.TF_VAR_PROGRAM }}
118+
TF_VAR_REPO_OIDC_ARN: ${{ secrets.TF_VAR_REPO_OIDC_ARN }}
119+
TF_VAR_REPOSITORY: ${{ secrets.TF_VAR_REPOSITORY }}
120+
TF_VAR_VPC_CIDR: ${{ secrets.TF_VAR_VPC_CIDR }}
121+
TF_VAR_VPC_PRIVATE_SUBNET_CIDRS: ${{ secrets.TF_VAR_VPC_PRIVATE_SUBNET_CIDRS }}
122+
TF_VAR_VPC_PUBLIC_SUBNET_CIDRS: ${{ secrets.TF_VAR_VPC_PUBLIC_SUBNET_CIDRS }}
123+
with:
124+
config: ${{ inputs.config }}
141125
- name: Plan changes
142126
working-directory: ./tofu/config/${{ inputs.config }}
143127
run: tofu plan -concise -no-color -out tfplan > plan.txt

tofu/config/service/.terraform.lock.hcl

Lines changed: 16 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tofu/config/service/locals.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
locals {
2+
image_tag = var.image_tag != null ? var.image_tag : sha256(timestamp())
3+
}

tofu/config/service/main.tf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ module "system" {
3030
container_subnets = split(",", module.inputs.values["vpc/private_subnets"])
3131

3232
apply_database_updates_immediately = var.apply_database_updates_immediately
33+
database_instance_count = var.database_instance_count
3334
database_skip_final_snapshot = var.database_skip_final_snapshot
3435
deletion_protection = var.deletion_protection
35-
image_tag = var.image_tag != null ? var.image_tag : sha256(timestamp())
36+
image_tag = local.image_tag
3637
image_tags_mutable = var.image_tags_mutable
3738

3839
consumer_container_count = var.consumer_container_count

0 commit comments

Comments
 (0)