Recently been doing a fair bit of work in GitHub Actions, our chosen tool for CI at Patient Pattern. I've written a few event-based workflows, reusable workflows, manually-triggered workflows, and docker container actions. The next step I'd like to take is to share an action. So here's my first for rendering JSON based on values provided in a workflow:
github.com/marketplace/actions/render-json-..
For a motivating example, let's say you're using AWS Elastic Container Service (ECS) as your orchestration platform, and you want to create multiple task definitions, each with its own docker command. You could start with a base task definition JSON file, say ecs/tasks/app.json
:
{
"containerDefinitions": [
{
"name": "django-app",
"image": "docker-org/your-repository",
"repositoryCredentials": {
"credentialsParameter": "arn:aws:secretsmanager:us-east-1:123456789:secret:some/dockerhub/secret-ABC123"
},
"cpu": 1,
"memory": 1024,
"linuxParameters": {
"initProcessEnabled": true
},
"command": [],
"environment": [],
"portMappings": [
{
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "app",
"awslogs-stream-prefix": "ecs",
"awslogs-create-group": "true",
"awslogs-region": "us-east-1"
}
}
}
],
"family": "",
"executionRoleArn": "arn:aws:iam::123456789:role/ExecutionRole",
"taskRoleArn": "arn:aws:iam::123456789:role/TaskRole",
"networkMode": "awsvpc",
"requiresCompatibilities": [
"FARGATE"
],
"cpu": "1024",
"memory": "1024"
}
Now in a GitHub workflow, let's say main.yaml
, you could render a couple ECS task definitions for two services to deploy, using the rendered results in the actual deployment. For demonstration purposes, this example workflow simply displays the results to see in the GitHub Action UI:
on:
push:
branches:
- main
jobs:
deploy-staging-api:
name: Deploy API
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- id: render
uses: christherama/render-json-template@v1
with:
json-file-path: ecs/tasks/app.json
field-value-pairs: |
$.containerDefinitions[0].name: "api"
$.containerDefinitions[0].command: ["uwsgi", "--ini", "conf/api.uwsgi.ini"]
$.containerDefinitions[0].logConfiguration.options["awslogs-group"]: "staging/api"
- name: Show rendered API task
run: cat ${{ steps.render.outputs.rendered-json-file }}
deploy-staging-user-service:
name: Deploy User Service
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- id: render
uses: christherama/render-json-template@v1
with:
json-file-path: ecs/tasks/app.json
field-value-pairs: |
$.containerDefinitions[0].name: "user"
$.containerDefinitions[0].command: ["uwsgi", "--ini", "conf/user-service.uwsgi.ini"]
$.containerDefinitions[0].logConfiguration.options["awslogs-group"]: "staging/user-service"
- name: Show rendered user service task
run: cat ${{ steps.render.outputs.rendered-json-file }}
Might you find this useful? If so, leave a comment or take it for a spin yourself. I'd love to hear your feedback!