├── tests ├── terragrunt │ ├── terragrunt.hcl │ └── terraform.tfvars └── terraform │ ├── 0.xx │ └── main.tf │ └── 0.11 │ └── main.tf ├── .gitignore ├── .github ├── dependabot.yml ├── labels.yml ├── workflows │ ├── release-drafter.yml │ ├── repository.yml │ ├── lint.yml │ ├── action_pull_request.yml │ ├── action_schedule.yml │ ├── action_branch.yml │ └── params.yml └── release-drafter.yml ├── .yamllint ├── LICENSE ├── Dockerfiles ├── data │ └── docker-entrypoint.sh └── Dockerfile ├── Makefile └── README.md /tests/terragrunt/terragrunt.hcl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile.docker 2 | Makefile.lint 3 | -------------------------------------------------------------------------------- /tests/terragrunt/terraform.tfvars: -------------------------------------------------------------------------------- 1 | terragrunt = { 2 | terraform { 3 | source = "./" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | # Maintain dependencies for GitHub Actions 5 | - package-ecosystem: "github-actions" 6 | directory: "/" 7 | schedule: 8 | interval: "daily" 9 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | ignore: | 5 | .yamllint 6 | 7 | 8 | rules: 9 | truthy: 10 | allowed-values: ['true', 'false'] 11 | check-keys: False 12 | level: error 13 | line-length: disable 14 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | # The labels in this file are automatically synced with the repository 2 | # using the micnncim/action-label-syncer action. 3 | --- 4 | - name: C-dependency 5 | color: 1abc9c 6 | description: "Category: Dependency" 7 | - name: PR-block 8 | color: 3498db 9 | description: "Pull Request: Do not merge" 10 | - name: PR-merge 11 | color: 3498db 12 | description: "Pull Request: Merge when ready" 13 | -------------------------------------------------------------------------------- /tests/terraform/0.xx/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_iam_role" "roles" { 2 | name = "my-role" 3 | path = "/" 4 | description = "my-role description" 5 | 6 | # This policy defines who/what is allowed to use the current role 7 | assume_role_policy = file("policy.json") 8 | 9 | # Allow session for X seconds 10 | max_session_duration = "3600" 11 | force_detach_policies = true 12 | 13 | tags = { 14 | Name = "my-role" 15 | Owner = "terraform" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/terraform/0.11/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_iam_role" "roles" { 2 | name = "my-role" 3 | path = "/" 4 | description = "my-role description" 5 | 6 | # This policy defines who/what is allowed to use the current role 7 | assume_role_policy = "${file("policy.json")}" 8 | 9 | # Allow session for X seconds 10 | max_session_duration = "3600" 11 | force_detach_policies = true 12 | 13 | tags = { 14 | Name = "my-role" 15 | Owner = "terraform" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Release Drafter 3 | 4 | on: 5 | push: 6 | # branches to consider in the event; optional, defaults to all 7 | branches: 8 | - master 9 | 10 | jobs: 11 | update_release_draft: 12 | runs-on: ubuntu-latest 13 | steps: 14 | # Drafts your next Release notes as Pull Requests are merged into "master" 15 | - uses: release-drafter/release-drafter@v6 16 | with: 17 | publish: true 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.RELEASE_DRAFTER_TOKEN }} 20 | -------------------------------------------------------------------------------- /.github/workflows/repository.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Repository 3 | 4 | on: 5 | push: 6 | branches: 7 | - master 8 | paths: 9 | - .github/labels.yml 10 | 11 | jobs: 12 | labels: 13 | name: Labels 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Checkout code 18 | uses: actions/checkout@v5 19 | 20 | - name: Sync labels 21 | uses: micnncim/action-label-syncer@v1 22 | env: 23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 24 | with: 25 | manifest: .github/labels.yml 26 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name-template: '$RESOLVED_VERSION 🌈' 3 | tag-template: '$RESOLVED_VERSION' 4 | version-template: '$MAJOR.$MINOR' 5 | categories: 6 | - title: '🚀 Features' 7 | labels: 8 | - 'feature' 9 | - 'enhancement' 10 | - title: '🐛 Bug Fixes' 11 | labels: 12 | - 'fix' 13 | - 'bugfix' 14 | - 'bug' 15 | - title: '🧰 Maintenance' 16 | label: 'chore' 17 | change-template: '- $TITLE @$AUTHOR (#$NUMBER)' 18 | change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. 19 | version-resolver: 20 | major: 21 | labels: 22 | - 'major' 23 | minor: 24 | labels: 25 | - 'minor' 26 | patch: 27 | labels: 28 | - 'patch' 29 | default: minor 30 | template: | 31 | ## Changes 32 | 33 | $CHANGES 34 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # ------------------------------------------------------------------------------------------------- 4 | # Job Name 5 | # ------------------------------------------------------------------------------------------------- 6 | name: lint 7 | 8 | 9 | # ------------------------------------------------------------------------------------------------- 10 | # When to run 11 | # ------------------------------------------------------------------------------------------------- 12 | on: 13 | # Runs on Pull Requests 14 | pull_request: 15 | 16 | 17 | # ------------------------------------------------------------------------------------------------- 18 | # What to run 19 | # ------------------------------------------------------------------------------------------------- 20 | jobs: 21 | lint: 22 | uses: devilbox/github-actions/.github/workflows/lint-generic.yml@master 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 cytopia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/action_pull_request.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # ------------------------------------------------------------------------------------------------- 4 | # Job Name 5 | # ------------------------------------------------------------------------------------------------- 6 | name: build 7 | 8 | 9 | # ------------------------------------------------------------------------------------------------- 10 | # When to run 11 | # ------------------------------------------------------------------------------------------------- 12 | on: 13 | pull_request: 14 | 15 | 16 | jobs: 17 | 18 | # (1/2) Determine repository params 19 | params: 20 | uses: ./.github/workflows/params.yml 21 | # Only run for forks (contributor) 22 | if: github.event.pull_request.head.repo.fork 23 | 24 | # (2/2) Build 25 | docker: 26 | needs: [params] 27 | uses: devilbox/github-actions/.github/workflows/docker-name-version-flavour-arch.yml@master 28 | with: 29 | enabled: true 30 | can_deploy: false 31 | matrix: ${{ needs.params.outputs.matrix }} 32 | refs: ${{ needs.params.outputs.refs }} 33 | secrets: 34 | dockerhub_username: "" 35 | dockerhub_password: "" 36 | -------------------------------------------------------------------------------- /.github/workflows/action_schedule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # ------------------------------------------------------------------------------------------------- 4 | # Job Name 5 | # ------------------------------------------------------------------------------------------------- 6 | name: nightly 7 | 8 | 9 | # ------------------------------------------------------------------------------------------------- 10 | # When to run 11 | # ------------------------------------------------------------------------------------------------- 12 | on: 13 | # Runs daily 14 | schedule: 15 | - cron: '0 0 * * *' 16 | 17 | 18 | jobs: 19 | 20 | # (1/2) Determine repository params 21 | params: 22 | uses: ./.github/workflows/params.yml 23 | 24 | # (2/2) Build 25 | docker: 26 | needs: [params] 27 | uses: devilbox/github-actions/.github/workflows/docker-name-version-flavour-arch.yml@master 28 | with: 29 | enabled: true 30 | can_deploy: true 31 | matrix: ${{ needs.params.outputs.matrix }} 32 | refs: ${{ needs.params.outputs.refs }} 33 | secrets: 34 | dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }} 35 | dockerhub_password: ${{ secrets.DOCKERHUB_PASSWORD }} 36 | -------------------------------------------------------------------------------- /Dockerfiles/data/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -eu 4 | 5 | ### 6 | ### Default values 7 | ### 8 | DEFAULT_UID=1000 9 | DEFAULT_GID=1000 10 | DEFAULT_USER=cytopia 11 | DEFAULT_HOME=/home/cytopia 12 | RUN_ROOT=1 13 | 14 | 15 | ### 16 | ### Get environment variables 17 | ### 18 | if env | grep -q '^RUN_NON_ROOT='; then 19 | RUN_NON_ROOT="$( env | grep '^RUN_NON_ROOT=' | awk -F'=' '{print $2}' )" 20 | if [ "${RUN_NON_ROOT}" = "1" ]; then 21 | RUN_ROOT=0 22 | fi 23 | fi 24 | if env | grep -q '^UID='; then 25 | DEFAULT_UID="$( env | grep '^UID=' | awk -F'=' '{print $2}' )" 26 | fi 27 | if env | grep -q '^GID='; then 28 | DEFAULT_GID="$( env | grep '^GID=' | awk -F'=' '{print $2}' )" 29 | fi 30 | 31 | 32 | if [ "${RUN_ROOT}" = "0" ]; then 33 | ### 34 | ### Add user and adjust permissions 35 | ### 36 | >&2 echo "Creating user '${DEFAULT_USER}' (uid: ${DEFAULT_UID} gid: ${DEFAULT_GID}) in '${DEFAULT_HOME}'" 37 | echo "${DEFAULT_USER}:x:${DEFAULT_UID}:${DEFAULT_GID}:${DEFAULT_USER}:${DEFAULT_HOME}:/bin/sh" >> /etc/passwd 38 | mkdir -p "${DEFAULT_HOME}" 39 | chown -R "${DEFAULT_UID}:${DEFAULT_GID}" "${DEFAULT_HOME}" 40 | 41 | >&2 printf "\\e[0;92m%s> %s\\e[0m\\n" "${DEFAULT_USER}" "${*}" 42 | exec su "${DEFAULT_USER}" -c "${*}" 43 | else 44 | >&2 printf "\\e[0;91m%s> %s\\e[0m\\n" "root" "${*}" 45 | exec "${@}" 46 | fi 47 | -------------------------------------------------------------------------------- /.github/workflows/action_branch.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # ------------------------------------------------------------------------------------------------- 4 | # Job Name 5 | # ------------------------------------------------------------------------------------------------- 6 | name: build 7 | 8 | 9 | # ------------------------------------------------------------------------------------------------- 10 | # When to run 11 | # ------------------------------------------------------------------------------------------------- 12 | on: 13 | push: 14 | paths: 15 | - 'Makefile' 16 | - 'Dockerfiles/**' 17 | - 'tests/**' 18 | - '.github/workflows/action*.yml' 19 | - '.github/workflows/params.yml' 20 | 21 | jobs: 22 | 23 | # (1/2) Determine repository params 24 | params: 25 | uses: ./.github/workflows/params.yml 26 | 27 | # (2/2) Build 28 | docker: 29 | needs: [params] 30 | uses: devilbox/github-actions/.github/workflows/docker-name-version-flavour-arch.yml@master 31 | with: 32 | enabled: true 33 | can_deploy: ${{ github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/heads/release-') }} 34 | matrix: ${{ needs.params.outputs.matrix }} 35 | refs: ${{ needs.params.outputs.refs }} 36 | secrets: 37 | dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }} 38 | dockerhub_password: ${{ secrets.DOCKERHUB_PASSWORD }} 39 | -------------------------------------------------------------------------------- /Dockerfiles/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.16 as builder 2 | 3 | # Install build dependencies 4 | RUN set -eux \ 5 | && apk --no-cache add \ 6 | coreutils \ 7 | curl \ 8 | dpkg \ 9 | git \ 10 | unzip 11 | 12 | # Get Terraform 13 | ARG TF_VERSION=latest 14 | RUN set -eux \ 15 | && if [ "${TF_VERSION}" = "latest" ]; then \ 16 | VERSION="$( curl -sS https://releases.hashicorp.com/terraform/ \ 17 | | tac | tac \ 18 | | grep -Eo '/terraform/[.0-9]+/\"' \ 19 | | grep -Eo '[.0-9]+' \ 20 | | sort -V \ 21 | | tail -1 )"; \ 22 | else \ 23 | VERSION="$( curl -sS https://releases.hashicorp.com/terraform/ \ 24 | | tac | tac \ 25 | | grep -Eo "/terraform/${TF_VERSION}\.[.0-9]+/\"" \ 26 | | grep -Eo '[.0-9]+' \ 27 | | sort -V \ 28 | | tail -1 )"; \ 29 | fi \ 30 | \ 31 | # Get correct architecture 32 | && if [ "$(dpkg --print-architecture | awk -F'-' '{print $NF}' )" = "i386" ]; then\ 33 | ARCH=386; \ 34 | elif [ "$(uname -m)" = "x86_64" ]; then \ 35 | ARCH=amd64; \ 36 | elif [ "$(uname -m)" = "aarch64" ]; then \ 37 | ARCH=arm64; \ 38 | elif [ "$(uname -m)" = "armv7l" ]; then \ 39 | ARCH=arm; \ 40 | fi \ 41 | \ 42 | && curl --fail -sS -L -O \ 43 | https://releases.hashicorp.com/terraform/${VERSION}/terraform_${VERSION}_linux_${ARCH}.zip \ 44 | && unzip terraform_${VERSION}_linux_${ARCH}.zip \ 45 | && mv terraform /usr/bin/terraform \ 46 | && chmod +x /usr/bin/terraform 47 | 48 | # Get Terragrunt 49 | ARG TG_VERSION=latest 50 | RUN set -eux \ 51 | && git clone https://github.com/gruntwork-io/terragrunt /terragrunt \ 52 | && cd /terragrunt \ 53 | && if [ "${TG_VERSION}" = "latest" ]; then \ 54 | VERSION="$( git describe --abbrev=0 --tags )"; \ 55 | else \ 56 | VERSION="$( git tag | grep -E "v${TG_VERSION}\.[.0-9]+" | sort -Vu | tail -1 )" ;\ 57 | fi \ 58 | # Get correct architecture 59 | && if [ "$(dpkg --print-architecture | awk -F'-' '{print $NF}' )" = "i386" ]; then\ 60 | ARCH=386; \ 61 | elif [ "$(uname -m)" = "x86_64" ]; then \ 62 | ARCH=amd64; \ 63 | elif [ "$(uname -m)" = "aarch64" ]; then \ 64 | ARCH=arm64; \ 65 | elif [ "$(uname -m)" = "armv7l" ]; then \ 66 | ARCH=arm; \ 67 | fi \ 68 | \ 69 | && curl --fail -sS -L \ 70 | https://github.com/gruntwork-io/terragrunt/releases/download/${VERSION}/terragrunt_linux_${ARCH} \ 71 | -o /usr/bin/terragrunt \ 72 | && chmod +x /usr/bin/terragrunt \ 73 | \ 74 | && terraform --version \ 75 | && terragrunt --version 76 | 77 | 78 | # Use a clean tiny image to store artifacts in 79 | FROM alpine:3.16 80 | LABEL \ 81 | maintainer="cytopia " \ 82 | repo="https://github.com/cytopia/docker-terragrunt" 83 | RUN set -eux \ 84 | && apk add --no-cache \ 85 | git \ 86 | openssh-client 87 | 88 | COPY --from=builder /usr/bin/terraform /usr/bin/terraform 89 | COPY --from=builder /usr/bin/terragrunt /usr/bin/terragrunt 90 | COPY data/docker-entrypoint.sh /docker-entrypoint.sh 91 | 92 | WORKDIR /data 93 | CMD ["terragrunt", "--version"] 94 | ENTRYPOINT ["/docker-entrypoint.sh"] 95 | -------------------------------------------------------------------------------- /.github/workflows/params.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # ------------------------------------------------------------------------------------------------- 4 | # Job Name 5 | # ------------------------------------------------------------------------------------------------- 6 | name: params 7 | 8 | 9 | # ------------------------------------------------------------------------------------------------- 10 | # Custom Variables 11 | # ------------------------------------------------------------------------------------------------- 12 | env: 13 | MATRIX: >- 14 | [ 15 | { 16 | "NAME": "tg", 17 | "VERSION": [ 18 | "latest", 19 | 20 | "TF-1.13 TG-0.92", 21 | "TF-1.12 TG-0.92", 22 | "TF-1.11 TG-0.92", 23 | "TF-1.10 TG-0.92", 24 | "TF-1.9 TG-0.92", 25 | "TF-1.8 TG-0.92", 26 | 27 | "TF-1.13 TG-0.91", 28 | "TF-1.12 TG-0.91", 29 | "TF-1.11 TG-0.91", 30 | "TF-1.10 TG-0.91", 31 | "TF-1.9 TG-0.91", 32 | "TF-1.8 TG-0.91", 33 | 34 | "TF-1.13 TG-0.90", 35 | "TF-1.12 TG-0.90", 36 | "TF-1.11 TG-0.90", 37 | "TF-1.10 TG-0.90", 38 | "TF-1.9 TG-0.90", 39 | "TF-1.8 TG-0.90", 40 | 41 | "TF-1.13 TG-0.89", 42 | "TF-1.12 TG-0.89", 43 | "TF-1.11 TG-0.89", 44 | "TF-1.10 TG-0.89", 45 | "TF-1.9 TG-0.89", 46 | "TF-1.8 TG-0.89", 47 | 48 | "TF-1.13 TG-0.88", 49 | "TF-1.12 TG-0.88", 50 | "TF-1.11 TG-0.88", 51 | "TF-1.10 TG-0.88", 52 | "TF-1.9 TG-0.88", 53 | "TF-1.8 TG-0.88", 54 | 55 | "TF-1.13 TG-0.87", 56 | "TF-1.12 TG-0.87", 57 | "TF-1.11 TG-0.87", 58 | "TF-1.10 TG-0.87", 59 | "TF-1.9 TG-0.87", 60 | "TF-1.8 TG-0.87", 61 | 62 | "TF-1.13 TG-0.86", 63 | "TF-1.12 TG-0.86", 64 | "TF-1.11 TG-0.86", 65 | "TF-1.10 TG-0.86", 66 | "TF-1.9 TG-0.86", 67 | "TF-1.8 TG-0.86", 68 | 69 | "TF-1.12 TG-0.82", 70 | "TF-1.11 TG-0.82", 71 | "TF-1.10 TG-0.82", 72 | "TF-1.9 TG-0.82", 73 | "TF-1.8 TG-0.82", 74 | 75 | "TF-1.8 TG-0.73", 76 | 77 | "TF-1.7 TG-0.73", 78 | 79 | "TF-1.6 TG-0.55", 80 | "TF-1.6 TG-0.54", 81 | "TF-1.6 TG-0.53", 82 | 83 | "TF-1.5 TG-0.53", 84 | "TF-1.5 TG-0.52", 85 | "TF-1.5 TG-0.51", 86 | "TF-1.5 TG-0.50", 87 | "TF-1.5 TG-0.49", 88 | "TF-1.5 TG-0.48", 89 | "TF-1.5 TG-0.47", 90 | "TF-1.5 TG-0.46", 91 | 92 | "TF-1.4 TG-0.50", 93 | "TF-1.4 TG-0.49", 94 | "TF-1.4 TG-0.48", 95 | "TF-1.4 TG-0.47", 96 | "TF-1.4 TG-0.46", 97 | 98 | "TF-1.3 TG-0.50", 99 | "TF-1.3 TG-0.49", 100 | "TF-1.3 TG-0.48", 101 | "TF-1.3 TG-0.47", 102 | "TF-1.3 TG-0.46" 103 | ], 104 | "FLAVOUR": ["latest"], 105 | "ARCH": ["linux/amd64", "linux/386", "linux/arm64"] 106 | }, 107 | { 108 | "NAME": "tg", 109 | "VERSION": [ 110 | "TF-0.12 TG-0.24", 111 | "TF-0.12 TG-0.23", 112 | "TF-0.12 TG-0.22", 113 | "TF-0.12 TG-0.21", 114 | "TF-0.12 TG-0.20", 115 | "TF-0.12 TG-0.19", 116 | 117 | "TF-0.11 TG-0.18" 118 | ], 119 | "FLAVOUR": ["latest"], 120 | "ARCH": ["linux/amd64", "linux/386"] 121 | } 122 | ] 123 | 124 | 125 | # ------------------------------------------------------------------------------------------------- 126 | # When to run 127 | # ------------------------------------------------------------------------------------------------- 128 | on: 129 | workflow_call: 130 | outputs: 131 | matrix: 132 | description: "The determined version matrix" 133 | value: ${{ jobs.params.outputs.matrix }} 134 | refs: 135 | description: "The determined git ref matrix (only during scheduled run)" 136 | value: ${{ jobs.params.outputs.refs }} 137 | 138 | jobs: 139 | params: 140 | runs-on: ubuntu-latest 141 | 142 | outputs: 143 | matrix: ${{ steps.set-matrix.outputs.matrix }} 144 | refs: ${{ steps.set-refs.outputs.matrix }} 145 | 146 | steps: 147 | - name: "[Set-Output] Matrix" 148 | id: set-matrix 149 | run: | 150 | echo "matrix=$( echo '${{ env.MATRIX }}' | jq -M -c )" >> $GITHUB_OUTPUT 151 | 152 | - name: "[Set-Output] Matrix 'Refs' (master branch and latest tag)" 153 | id: set-refs 154 | uses: cytopia/git-ref-matrix-action@v0.1.13 155 | with: 156 | repository_default_branch: master 157 | branches: master 158 | num_latest_tags: 0 159 | if: github.event_name == 'schedule' 160 | 161 | - name: "[DEBUG] Show settings'" 162 | run: | 163 | echo 'Matrix' 164 | echo '--------------------' 165 | echo '${{ steps.set-matrix.outputs.matrix }}' 166 | echo 167 | 168 | echo 'Matrix: Refs' 169 | echo '--------------------' 170 | echo '${{ steps.set-matrix-refs.outputs.matrix }}' 171 | echo 172 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifneq (,) 2 | .error This Makefile requires GNU Make. 3 | endif 4 | 5 | # Ensure additional Makefiles are present 6 | MAKEFILES = Makefile.docker Makefile.lint 7 | $(MAKEFILES): URL=https://raw.githubusercontent.com/devilbox/makefiles/master/$(@) 8 | $(MAKEFILES): 9 | @if ! (curl --fail -sS -o $(@) $(URL) || wget -O $(@) $(URL)); then \ 10 | echo "Error, curl or wget required."; \ 11 | echo "Exiting."; \ 12 | false; \ 13 | fi 14 | include $(MAKEFILES) 15 | 16 | # Set default Target 17 | .DEFAULT_GOAL := help 18 | 19 | 20 | # ------------------------------------------------------------------------------------------------- 21 | # Default configuration 22 | # ------------------------------------------------------------------------------------------------- 23 | # Own vars 24 | TAG = latest 25 | 26 | # Makefile.docker overwrites 27 | NAME = tg 28 | VERSION = latest 29 | IMAGE = cytopia/terragrunt 30 | FLAVOUR = latest 31 | FILE = Dockerfile 32 | DIR = Dockerfiles 33 | 34 | # Extract TF- and TG- version from VERSION string 35 | ifeq ($(strip $(VERSION)),latest) 36 | TF_VERSION = latest 37 | TG_VERSION = latest 38 | else 39 | TF_VERSION = $(subst TF-,,$(word 1, $(VERSION))) 40 | TG_VERSION = $(subst TG-,,$(word 2, $(VERSION))) 41 | endif 42 | 43 | # Building from master branch: Tag == 'latest' 44 | ifeq ($(strip $(TAG)),latest) 45 | ifeq ($(strip $(VERSION)),latest) 46 | DOCKER_TAG = $(FLAVOUR) 47 | else 48 | ifeq ($(strip $(FLAVOUR)),latest) 49 | DOCKER_TAG = $(TF_VERSION)-$(TG_VERSION) 50 | else 51 | DOCKER_TAG = $(FLAVOUR)-$(TF_VERSION)-$(TG_VERSION) 52 | endif 53 | endif 54 | # Building from any other branch or tag: Tag == '' 55 | else 56 | ifeq ($(strip $(VERSION)),latest) 57 | ifeq ($(strip $(FLAVOUR)),latest) 58 | DOCKER_TAG = latest-$(TAG) 59 | else 60 | DOCKER_TAG = $(FLAVOUR)-latest-$(TAG) 61 | endif 62 | else 63 | ifeq ($(strip $(FLAVOUR)),latest) 64 | DOCKER_TAG = $(TF_VERSION)-$(TG_VERSION)-$(TAG) 65 | else 66 | DOCKER_TAG = $(FLAVOUR)-$(TF_VERSION)-$(TG_VERSION)-$(TAG) 67 | endif 68 | endif 69 | endif 70 | 71 | # Makefile.lint overwrites 72 | FL_IGNORES = .git/,.github/,tests/ 73 | SC_IGNORES = .git/,.github/,tests/ 74 | JL_IGNORES = .git/,.github/ 75 | 76 | 77 | # ------------------------------------------------------------------------------------------------- 78 | # Default Target 79 | # ------------------------------------------------------------------------------------------------- 80 | .PHONY: help 81 | help: 82 | @echo "lint Lint project files and repository" 83 | @echo 84 | @echo "build [ARCH=...] [TAG=...] Build Docker image" 85 | @echo "rebuild [ARCH=...] [TAG=...] Build Docker image without cache" 86 | @echo "push [ARCH=...] [TAG=...] Push Docker image to Docker hub" 87 | @echo 88 | @echo "manifest-create [ARCHES=...] [TAG=...] Create multi-arch manifest" 89 | @echo "manifest-push [TAG=...] Push multi-arch manifest" 90 | @echo 91 | @echo "test [ARCH=...] Test built Docker image" 92 | @echo 93 | 94 | 95 | # ------------------------------------------------------------------------------------------------- 96 | # Docker Targets 97 | # ------------------------------------------------------------------------------------------------- 98 | .PHONY: build 99 | build: ARGS+=--build-arg TF_VERSION=$(TF_VERSION) 100 | build: ARGS+=--build-arg TG_VERSION=$(TG_VERSION) 101 | build: docker-arch-build 102 | 103 | .PHONY: rebuild 104 | rebuild: ARGS+=--build-arg TF_VERSION=$(TF_VERSION) 105 | rebuild: ARGS+=--build-arg TG_VERSION=$(TG_VERSION) 106 | rebuild: docker-arch-rebuild 107 | 108 | .PHONY: push 109 | push: docker-arch-push 110 | 111 | 112 | # ------------------------------------------------------------------------------------------------- 113 | # Manifest Targets 114 | # ------------------------------------------------------------------------------------------------- 115 | .PHONY: manifest-create 116 | manifest-create: docker-manifest-create 117 | 118 | .PHONY: manifest-push 119 | manifest-push: docker-manifest-push 120 | 121 | 122 | # ------------------------------------------------------------------------------------------------- 123 | # Test Targets 124 | # ------------------------------------------------------------------------------------------------- 125 | .PHONY: test 126 | test: _test-tf-version 127 | test: _test-tg-version 128 | test: _test-tf 129 | test: _test-tg 130 | 131 | .PHONY: _test-tf-version 132 | _test-tf-version: 133 | @echo "------------------------------------------------------------" 134 | @echo "- Testing correct Terraform version" 135 | @echo "------------------------------------------------------------" 136 | @if [ "$(TF_VERSION)" = "latest" ]; then \ 137 | echo "Fetching latest version from HashiCorp release page"; \ 138 | LATEST="$$( \ 139 | curl -L -sS https://releases.hashicorp.com/terraform/ \ 140 | | tac | tac \ 141 | | grep -Eo '/terraform/[.0-9]+/\"' \ 142 | | grep -Eo '[.0-9]+' \ 143 | | sort -u \ 144 | | sort -V \ 145 | | tail -1 \ 146 | )"; \ 147 | echo "Testing for latest: $${LATEST}"; \ 148 | if ! docker run --rm --platform $(ARCH) $(IMAGE):$(DOCKER_TAG) terraform --version | grep -E "^Terraform[[:space:]]*v?$${LATEST}$$"; then \ 149 | echo "Failed"; \ 150 | exit 1; \ 151 | fi; \ 152 | else \ 153 | echo "Testing for tag: $(TF_VERSION)"; \ 154 | if ! docker run --rm --platform $(ARCH) $(IMAGE):$(DOCKER_TAG) terraform --version | grep -E "^Terraform[[:space:]]*v?$(TF_VERSION)\.[.0-9]+$$"; then \ 155 | echo "Failed"; \ 156 | exit 1; \ 157 | fi; \ 158 | fi; \ 159 | echo "Success"; \ 160 | 161 | .PHONY: _test-tg-version 162 | _test-tg-version: 163 | @echo "------------------------------------------------------------" 164 | @echo "- Testing correct Terragrunt version" 165 | @echo "------------------------------------------------------------" 166 | @if [ "$(TG_VERSION)" = "latest" ]; then \ 167 | echo "Fetching latest version from GitHub"; \ 168 | LATEST="$$( \ 169 | curl -L -sS https://github.com/gruntwork-io/terragrunt/releases \ 170 | | tac | tac \ 171 | | grep -Eo '/v[.0-9]+"' \ 172 | | grep -Eo 'v[.0-9]+' \ 173 | | sort -u \ 174 | | sort -V \ 175 | | tail -1 \ 176 | )"; \ 177 | echo "Testing for latest: $${LATEST}"; \ 178 | if ! docker run --rm --platform $(ARCH) $(IMAGE):$(DOCKER_TAG) terragrunt --version | grep -E "^terragrunt[[:space:]]*version[[:space:]]*v?$${LATEST}$$"; then \ 179 | echo "Failed"; \ 180 | exit 1; \ 181 | fi; \ 182 | else \ 183 | echo "Testing for tag: $(TG_VERSION)"; \ 184 | if ! docker run --rm --platform $(ARCH) $(IMAGE):$(DOCKER_TAG) terragrunt --version | grep -E "^terragrunt[[:space:]]*version[[:space:]]*v?$(TG_VERSION)\.[.0-9]+(-[-a-z0-9]+)?$$"; then \ 185 | echo "Failed"; \ 186 | exit 1; \ 187 | fi; \ 188 | fi; \ 189 | echo "Success"; \ 190 | 191 | .PHONY: _test-tf 192 | _test-tf: 193 | @echo "------------------------------------------------------------" 194 | @echo "- Testing Terraform" 195 | @echo "------------------------------------------------------------" 196 | @if [ "$(TF_VERSION)" = "0.11" ]; then \ 197 | if ! docker run --rm --platform $(ARCH) -v $(CURRENT_DIR)/tests/terraform/0.11:/data $(IMAGE):$(DOCKER_TAG) terraform fmt; then \ 198 | echo "Failed"; \ 199 | exit 1; \ 200 | fi; \ 201 | else \ 202 | if ! docker run --rm --platform $(ARCH) -v $(CURRENT_DIR)/tests/terraform/0.xx:/data $(IMAGE):$(DOCKER_TAG) terraform fmt; then \ 203 | echo "Failed"; \ 204 | exit 1; \ 205 | fi; \ 206 | fi; \ 207 | echo "Success"; 208 | 209 | .PHONY: _test-tg 210 | _test-tg: 211 | @echo "------------------------------------------------------------" 212 | @echo "- Testing Terragrunt" 213 | @echo "------------------------------------------------------------" 214 | @CURRENT_VERSION="$$( \ 215 | docker run --rm --platform $(ARCH) $(IMAGE):$(DOCKER_TAG) terragrunt --version \ 216 | | grep -Eo 'v[0-9]+\.[0-9]+\.[0-9]+$$' \ 217 | | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+$$' \ 218 | )"; \ 219 | if [ "$$(printf '%s\n%s\n' "0.86.0" "$${CURRENT_VERSION}" | sort -V | tail -n1)" = "$${CURRENT_VERSION}" ]; then \ 220 | if ! docker run --rm --platform $(ARCH) -v $(CURRENT_DIR)/tests/terragrunt:/data $(IMAGE):$(DOCKER_TAG) terragrunt info print; then \ 221 | docker run --rm --platform $(ARCH) -v $(CURRENT_DIR)/tests/terragrunt:/data $(IMAGE):$(DOCKER_TAG) sh -c "if test -d .terragrunt-cache; then rm -rf .terragrunt-cache; fi"; \ 222 | echo "Failed"; \ 223 | exit 1; \ 224 | fi; \ 225 | else \ 226 | if ! docker run --rm --platform $(ARCH) -v $(CURRENT_DIR)/tests/terragrunt:/data $(IMAGE):$(DOCKER_TAG) terragrunt terragrunt-info; then \ 227 | docker run --rm --platform $(ARCH) -v $(CURRENT_DIR)/tests/terragrunt:/data $(IMAGE):$(DOCKER_TAG) sh -c "if test -d .terragrunt-cache; then rm -rf .terragrunt-cache; fi"; \ 228 | echo "Failed"; \ 229 | exit 1; \ 230 | fi; \ 231 | fi; \ 232 | docker run --rm --platform $(ARCH) -v $(CURRENT_DIR)/tests/terragrunt:/data $(IMAGE):$(DOCKER_TAG) sh -c "if test -d .terragrunt-cache; then rm -rf .terragrunt-cache; fi"; \ 233 | echo "Success"; 234 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker image for `terragrunt` 2 | 3 | [![Tag](https://img.shields.io/github/tag/cytopia/docker-terragrunt.svg)](https://github.com/cytopia/docker-terragrunt/releases) 4 | [![](https://img.shields.io/badge/github-cytopia%2Fdocker--terragrunt-red.svg)](https://github.com/cytopia/docker-terragrunt "github.com/cytopia/docker-terragrunt") 5 | [![License](https://img.shields.io/badge/license-MIT-%233DA639.svg)](https://opensource.org/licenses/MIT) 6 | 7 | [![lint](https://github.com/cytopia/docker-terragrunt/workflows/lint/badge.svg)](https://github.com/cytopia/docker-terragrunt/actions?query=workflow%3Alint) 8 | [![build](https://github.com/cytopia/docker-terragrunt/workflows/build/badge.svg)](https://github.com/cytopia/docker-terragrunt/actions?query=workflow%3Abuild) 9 | [![nightly](https://github.com/cytopia/docker-terragrunt/workflows/nightly/badge.svg)](https://github.com/cytopia/docker-terragrunt/actions?query=workflow%3Anightly) 10 | 11 | 12 | > #### All [#awesome-ci](https://github.com/topics/awesome-ci) Docker images 13 | > 14 | > [ansible-lint][alint-git-lnk] **•** 15 | > [ansible][ansible-git-lnk] **•** 16 | > [awesome-ci][aci-git-lnk] **•** 17 | > [bandit][bandit-git-lnk] **•** 18 | > [black][black-git-lnk] **•** 19 | > [checkmake][cm-git-lnk] **•** 20 | > [eslint][elint-git-lnk] **•** 21 | > [file-lint][flint-git-lnk] **•** 22 | > [gofmt][gfmt-git-lnk] **•** 23 | > [goimports][gimp-git-lnk] **•** 24 | > [golint][glint-git-lnk] **•** 25 | > [jsonlint][jlint-git-lnk] **•** 26 | > [kubeval][kubeval-git-lnk] **•** 27 | > [linkcheck][linkcheck-git-lnk] **•** 28 | > [mypy][mypy-git-lnk] **•** 29 | > [php-cs-fixer][pcsf-git-lnk] **•** 30 | > [phpcbf][pcbf-git-lnk] **•** 31 | > [phpcs][pcs-git-lnk] **•** 32 | > [phplint][plint-git-lnk] **•** 33 | > [pycodestyle][pycs-git-lnk] **•** 34 | > [pydocstyle][pyds-git-lnk] **•** 35 | > [pylint][pylint-git-lnk] **•** 36 | > [terraform-docs][tfdocs-git-lnk] **•** 37 | > [terragrunt-fmt][tgfmt-git-lnk] **•** 38 | > [terragrunt][tg-git-lnk] **•** 39 | > [yamlfmt][yfmt-git-lnk] **•** 40 | > [yamllint][ylint-git-lnk] 41 | 42 | View **[Dockerfiles](https://github.com/cytopia/docker-terragrunt/blob/master/Dockerfiles/)** on GitHub. 43 | 44 | 45 | **Available Architectures:** `amd64`, `i386`, `arm64` 46 | 47 | Tiny Alpine-based multistage-build dockerized version of [Terragrunt](https://github.com/gruntwork-io/terragrunt)[1] 48 | and its compatible version of [Terraform](https://github.com/hashicorp/terraform)[2]. 49 | 50 | * [1] Official project: https://github.com/gruntwork-io/terragrunt 51 | * [2] Official project: https://github.com/hashicorp/terraform 52 | 53 | 54 | ## :whale: Available Docker image versions 55 | 56 | [![](https://img.shields.io/docker/pulls/cytopia/terragrunt.svg)](https://hub.docker.com/r/cytopia/terragrunt) 57 | [![Docker](https://badgen.net/badge/icon/:latest?icon=docker&label=cytopia/terragrunt)](https://hub.docker.com/r/cytopia/terragrunt) 58 | 59 | #### Rolling releaess 60 | 61 | The following Docker image tags are rolling releases and are built and updated every night. 62 | 63 | [![nightly](https://github.com/cytopia/docker-terragrunt/workflows/nightly/badge.svg)](https://github.com/cytopia/docker-terragrunt/actions?query=workflow%3Anightly) 64 | 65 | 66 | | Docker Tag | Git Ref | Terraform | Terragrunt | Available Architectures | 67 | |-------------|-----------|--------------|--------------|----------------------------------------------| 68 | | `latest` | master | latest | latest | `amd64`, `i386`, `arm64` | 69 | | | | | | | 70 | | `1.13-0.86` | master | **`1.13.x`** | **`0.92.x`** | `amd64`, `i386`, `arm64` | 71 | | `1.12-0.86` | master | **`1.12.x`** | **`0.92.x`** | `amd64`, `i386`, `arm64` | 72 | | `1.11-0.86` | master | **`1.11.x`** | **`0.92.x`** | `amd64`, `i386`, `arm64` | 73 | | `1.10-0.86` | master | **`1.10.x`** | **`0.92.x`** | `amd64`, `i386`, `arm64` | 74 | | `1.9-0.86` | master | **`1.9.x`** | **`0.92.x`** | `amd64`, `i386`, `arm64` | 75 | | `1.8-0.86` | master | **`1.8.x`** | **`0.92.x`** | `amd64`, `i386`, `arm64` | 76 | | | | | | | 77 | | `1.13-0.86` | master | **`1.13.x`** | **`0.91.x`** | `amd64`, `i386`, `arm64` | 78 | | `1.12-0.86` | master | **`1.12.x`** | **`0.91.x`** | `amd64`, `i386`, `arm64` | 79 | | `1.11-0.86` | master | **`1.11.x`** | **`0.91.x`** | `amd64`, `i386`, `arm64` | 80 | | `1.10-0.86` | master | **`1.10.x`** | **`0.91.x`** | `amd64`, `i386`, `arm64` | 81 | | `1.9-0.86` | master | **`1.9.x`** | **`0.91.x`** | `amd64`, `i386`, `arm64` | 82 | | `1.8-0.86` | master | **`1.8.x`** | **`0.91.x`** | `amd64`, `i386`, `arm64` | 83 | | | | | | | 84 | | `1.13-0.86` | master | **`1.13.x`** | **`0.90.x`** | `amd64`, `i386`, `arm64` | 85 | | `1.12-0.86` | master | **`1.12.x`** | **`0.90.x`** | `amd64`, `i386`, `arm64` | 86 | | `1.11-0.86` | master | **`1.11.x`** | **`0.90.x`** | `amd64`, `i386`, `arm64` | 87 | | `1.10-0.86` | master | **`1.10.x`** | **`0.90.x`** | `amd64`, `i386`, `arm64` | 88 | | `1.9-0.86` | master | **`1.9.x`** | **`0.90.x`** | `amd64`, `i386`, `arm64` | 89 | | `1.8-0.86` | master | **`1.8.x`** | **`0.90.x`** | `amd64`, `i386`, `arm64` | 90 | | | | | | | 91 | | `1.13-0.86` | master | **`1.13.x`** | **`0.89.x`** | `amd64`, `i386`, `arm64` | 92 | | `1.12-0.86` | master | **`1.12.x`** | **`0.89.x`** | `amd64`, `i386`, `arm64` | 93 | | `1.11-0.86` | master | **`1.11.x`** | **`0.89.x`** | `amd64`, `i386`, `arm64` | 94 | | `1.10-0.86` | master | **`1.10.x`** | **`0.89.x`** | `amd64`, `i386`, `arm64` | 95 | | `1.9-0.86` | master | **`1.9.x`** | **`0.89.x`** | `amd64`, `i386`, `arm64` | 96 | | `1.8-0.86` | master | **`1.8.x`** | **`0.89.x`** | `amd64`, `i386`, `arm64` | 97 | | | | | | | 98 | | `1.13-0.86` | master | **`1.13.x`** | **`0.88.x`** | `amd64`, `i386`, `arm64` | 99 | | `1.12-0.86` | master | **`1.12.x`** | **`0.88.x`** | `amd64`, `i386`, `arm64` | 100 | | `1.11-0.86` | master | **`1.11.x`** | **`0.88.x`** | `amd64`, `i386`, `arm64` | 101 | | `1.10-0.86` | master | **`1.10.x`** | **`0.88.x`** | `amd64`, `i386`, `arm64` | 102 | | `1.9-0.86` | master | **`1.9.x`** | **`0.88.x`** | `amd64`, `i386`, `arm64` | 103 | | `1.8-0.86` | master | **`1.8.x`** | **`0.88.x`** | `amd64`, `i386`, `arm64` | 104 | | | | | | | 105 | | `1.13-0.86` | master | **`1.13.x`** | **`0.87.x`** | `amd64`, `i386`, `arm64` | 106 | | `1.12-0.86` | master | **`1.12.x`** | **`0.87.x`** | `amd64`, `i386`, `arm64` | 107 | | `1.11-0.86` | master | **`1.11.x`** | **`0.87.x`** | `amd64`, `i386`, `arm64` | 108 | | `1.10-0.86` | master | **`1.10.x`** | **`0.87.x`** | `amd64`, `i386`, `arm64` | 109 | | `1.9-0.86` | master | **`1.9.x`** | **`0.87.x`** | `amd64`, `i386`, `arm64` | 110 | | `1.8-0.86` | master | **`1.8.x`** | **`0.87.x`** | `amd64`, `i386`, `arm64` | 111 | | | | | | | 112 | | `1.13-0.86` | master | **`1.13.x`** | **`0.86.x`** | `amd64`, `i386`, `arm64` | 113 | | `1.12-0.86` | master | **`1.12.x`** | **`0.86.x`** | `amd64`, `i386`, `arm64` | 114 | | `1.11-0.86` | master | **`1.11.x`** | **`0.86.x`** | `amd64`, `i386`, `arm64` | 115 | | `1.10-0.86` | master | **`1.10.x`** | **`0.86.x`** | `amd64`, `i386`, `arm64` | 116 | | `1.9-0.86` | master | **`1.9.x`** | **`0.86.x`** | `amd64`, `i386`, `arm64` | 117 | | `1.8-0.86` | master | **`1.8.x`** | **`0.86.x`** | `amd64`, `i386`, `arm64` | 118 | | | | | | | 119 | | `1.12-0.82` | master | **`1.12.x`** | **`0.82.x`** | `amd64`, `i386`, `arm64` | 120 | | `1.11-0.82` | master | **`1.11.x`** | **`0.82.x`** | `amd64`, `i386`, `arm64` | 121 | | `1.10-0.82` | master | **`1.10.x`** | **`0.82.x`** | `amd64`, `i386`, `arm64` | 122 | | `1.9-0.82` | master | **`1.9.x`** | **`0.82.x`** | `amd64`, `i386`, `arm64` | 123 | | `1.8-0.82` | master | **`1.8.x`** | **`0.82.x`** | `amd64`, `i386`, `arm64` | 124 | | | | | | | 125 | | `1.8-0.73` | master | **`1.8.x`** | **`0.73.x`** | `amd64`, `i386`, `arm64` | 126 | | | | | | | 127 | | `1.7-0.73` | master | **`1.7.x`** | **`0.73.x`** | `amd64`, `i386`, `arm64` | 128 | | | | | | | 129 | | `1.6-0.55` | master | **`1.6.x`** | **`0.55.x`** | `amd64`, `i386`, `arm64` | 130 | | `1.6-0.54` | master | **`1.6.x`** | **`0.54.x`** | `amd64`, `i386`, `arm64` | 131 | | `1.6-0.53` | master | **`1.6.x`** | **`0.53.x`** | `amd64`, `i386`, `arm64` | 132 | | | | | | | 133 | | `1.5-0.53` | master | **`1.5.x`** | **`0.53.x`** | `amd64`, `i386`, `arm64` | 134 | | `1.5-0.52` | master | **`1.5.x`** | **`0.52.x`** | `amd64`, `i386`, `arm64` | 135 | | `1.5-0.51` | master | **`1.5.x`** | **`0.51.x`** | `amd64`, `i386`, `arm64` | 136 | | `1.5-0.50` | master | **`1.5.x`** | **`0.50.x`** | `amd64`, `i386`, `arm64` | 137 | | `1.5-0.49` | master | **`1.5.x`** | **`0.49.x`** | `amd64`, `i386`, `arm64` | 138 | | `1.5-0.48` | master | **`1.5.x`** | **`0.48.x`** | `amd64`, `i386`, `arm64` | 139 | | `1.5-0.47` | master | **`1.5.x`** | **`0.47.x`** | `amd64`, `i386`, `arm64` | 140 | | `1.5-0.46` | master | **`1.5.x`** | **`0.46.x`** | `amd64`, `i386`, `arm64` | 141 | | | | | | | 142 | | `1.4-0.50` | master | **`1.4.x`** | **`0.50.x`** | `amd64`, `i386`, `arm64` | 143 | | `1.4-0.49` | master | **`1.4.x`** | **`0.49.x`** | `amd64`, `i386`, `arm64` | 144 | | `1.4-0.48` | master | **`1.4.x`** | **`0.48.x`** | `amd64`, `i386`, `arm64` | 145 | | `1.4-0.47` | master | **`1.4.x`** | **`0.47.x`** | `amd64`, `i386`, `arm64` | 146 | | `1.4-0.46` | master | **`1.4.x`** | **`0.46.x`** | `amd64`, `i386`, `arm64` | 147 | | | | | | | 148 | | `1.3-0.50` | master | **`1.3.x`** | **`0.50.x`** | `amd64`, `i386`, `arm64` | 149 | | `1.3-0.49` | master | **`1.3.x`** | **`0.49.x`** | `amd64`, `i386`, `arm64` | 150 | | `1.3-0.48` | master | **`1.3.x`** | **`0.48.x`** | `amd64`, `i386`, `arm64` | 151 | | `1.3-0.47` | master | **`1.3.x`** | **`0.47.x`** | `amd64`, `i386`, `arm64` | 152 | | `1.3-0.46` | master | **`1.3.x`** | **`0.46.x`** | `amd64`, `i386`, `arm64` | 153 | | | | | | | 154 | | `1.2-0.41` | master | **`1.2.x`** | **`0.41.x`** | `amd64`, `i386`, `arm64` | 155 | | `1.2-0.40` | master | **`1.2.x`** | **`0.40.x`** | `amd64`, `i386`, `arm64` | 156 | | `1.2-0.39` | master | **`1.2.x`** | **`0.39.x`** | `amd64`, `i386`, `arm64` | 157 | | `1.2-0.38` | master | **`1.2.x`** | **`0.38.x`** | `amd64`, `i386`, `arm64` | 158 | | `1.2-0.37` | master | **`1.2.x`** | **`0.37.x`** | `amd64`, `i386`, `arm64` | 159 | | | | | | | 160 | | `1.1-0.38` | master | **`1.1.x`** | **`0.38.x`** | `amd64`, `i386`, `arm64` | 161 | | `1.1-0.38` | master | **`1.1.x`** | **`0.38.x`** | `amd64`, `i386`, `arm64` | 162 | | `1.1-0.37` | master | **`1.1.x`** | **`0.37.x`** | `amd64`, `i386`, `arm64` | 163 | | `1.1-0.36` | master | **`1.1.x`** | **`0.36.x`** | `amd64`, `i386`, `arm64` | 164 | | `1.1-0.35` | master | **`1.1.x`** | **`0.35.x`** | `amd64`, `i386`, `arm64` | 165 | | | | | | | 166 | | `1.0-0.38` | master | **`1.0.x`** | **`0.38.x`** | `amd64`, `i386`, `arm64` | 167 | | `1.0-0.37` | master | **`1.0.x`** | **`0.37.x`** | `amd64`, `i386`, `arm64` | 168 | | `1.0-0.36` | master | **`1.0.x`** | **`0.36.x`** | `amd64`, `i386`, `arm64` | 169 | | `1.0-0.35` | master | **`1.0.x`** | **`0.35.x`** | `amd64`, `i386`, `arm64` | 170 | | `1.0-0.34` | master | **`1.0.x`** | **`0.34.x`** | `amd64`, `i386`, `arm64` | 171 | | | | | | | 172 | | `0.15-0.34` | master | **`0.15.x`** | **`0.34.x`** | `amd64`, `i386`, `arm64` | 173 | | `0.15-0.33` | master | **`0.15.x`** | **`0.33.x`** | `amd64`, `i386`, `arm64` | 174 | | `0.15-0.32` | master | **`0.15.x`** | **`0.32.x`** | `amd64`, `i386`, `arm64` | 175 | | `0.15-0.31` | master | **`0.15.x`** | **`0.31.x`** | `amd64`, `i386`, `arm64` | 176 | | `0.15-0.30` | master | **`0.15.x`** | **`0.30.x`** | `amd64`, `i386`, `arm64` | 177 | | | | | | | 178 | | `0.14-0.34` | master | **`0.14.x`** | **`0.34.x`** | `amd64`, `i386`, `arm64` | 179 | | `0.14-0.33` | master | **`0.14.x`** | **`0.33.x`** | `amd64`, `i386`, `arm64` | 180 | | `0.14-0.32` | master | **`0.14.x`** | **`0.32.x`** | `amd64`, `i386`, `arm64` | 181 | | `0.14-0.31` | master | **`0.14.x`** | **`0.31.x`** | `amd64`, `i386`, `arm64` | 182 | | `0.14-0.30` | master | **`0.14.x`** | **`0.30.x`** | `amd64`, `i386`, `arm64` | 183 | | | | | | | 184 | | `0.13-0.34` | master | **`0.13.x`** | **`0.34.x`** | `amd64`, `i386`, `arm64` | 185 | | `0.13-0.33` | master | **`0.13.x`** | **`0.33.x`** | `amd64`, `i386`, `arm64` | 186 | | `0.13-0.32` | master | **`0.13.x`** | **`0.32.x`** | `amd64`, `i386`, `arm64` | 187 | | `0.13-0.31` | master | **`0.13.x`** | **`0.31.x`** | `amd64`, `i386`, `arm64` | 188 | | `0.13-0.30` | master | **`0.13.x`** | **`0.30.x`** | `amd64`, `i386`, `arm64` | 189 | | | | | | | 190 | | `0.12-0.24` | master | **`0.12.x`** | **`0.24.x`** | `amd64`, `i386` | 191 | | `0.12-0.23` | master | **`0.12.x`** | **`0.23.x`** | `amd64`, `i386` | 192 | | `0.12-0.22` | master | **`0.12.x`** | **`0.22.x`** | `amd64`, `i386` | 193 | | `0.12-0.21` | master | **`0.12.x`** | **`0.21.x`** | `amd64`, `i386` | 194 | | `0.12-0.20` | master | **`0.12.x`** | **`0.20.x`** | `amd64`, `i386` | 195 | | `0.12-0.19` | master | **`0.12.x`** | **`0.19.x`** | `amd64`, `i386` | 196 | | | | | | | 197 | | `0.11-0.18` | master | **`0.11.x`** | **`0.18.x`** | `amd64`, `i386` | 198 | 199 | 200 | #### Point in time releases 201 | 202 | The following Docker image tags are built once and can be used for reproducible builds. Its version never changes so you will have to update tags in your pipelines from time to time in order to stay up-to-date. 203 | 204 | [![build](https://github.com/cytopia/docker-terragrunt/workflows/build/badge.svg)](https://github.com/cytopia/docker-terragrunt/actions?query=workflow%3Abuild) 205 | 206 | | Docker Tag | Git Ref | Terraform | Terragrunt | Available Architectures | 207 | |-------------------|--------------|---------------|--------------|----------------------------------------------| 208 | | `latest-` | tag: `` | latest | latest | `amd64`, `i386`, `arm64` | 209 | | | | | | | 210 | | `1.5-0.50-` | tag: `` | **`1.5.x`** | **`0.50.x`** | `amd64`, `i386`, `arm64` | 211 | | `1.5-0.49-` | tag: `` | **`1.5.x`** | **`0.49.x`** | `amd64`, `i386`, `arm64` | 212 | | `1.5-0.48-` | tag: `` | **`1.5.x`** | **`0.48.x`** | `amd64`, `i386`, `arm64` | 213 | | `1.5-0.47-` | tag: `` | **`1.5.x`** | **`0.47.x`** | `amd64`, `i386`, `arm64` | 214 | | `1.5-0.46-` | tag: `` | **`1.5.x`** | **`0.46.x`** | `amd64`, `i386`, `arm64` | 215 | | | | | | | 216 | | `1.4-0.50-` | tag: `` | **`1.4.x`** | **`0.50.x`** | `amd64`, `i386`, `arm64` | 217 | | `1.4-0.49-` | tag: `` | **`1.4.x`** | **`0.49.x`** | `amd64`, `i386`, `arm64` | 218 | | `1.4-0.48-` | tag: `` | **`1.4.x`** | **`0.48.x`** | `amd64`, `i386`, `arm64` | 219 | | `1.4-0.47-` | tag: `` | **`1.4.x`** | **`0.47.x`** | `amd64`, `i386`, `arm64` | 220 | | `1.4-0.46-` | tag: `` | **`1.4.x`** | **`0.46.x`** | `amd64`, `i386`, `arm64` | 221 | | | | | | | 222 | | `1.3-0.50-` | tag: `` | **`1.3.x`** | **`0.50.x`** | `amd64`, `i386`, `arm64` | 223 | | `1.3-0.49-` | tag: `` | **`1.3.x`** | **`0.49.x`** | `amd64`, `i386`, `arm64` | 224 | | `1.3-0.48-` | tag: `` | **`1.3.x`** | **`0.48.x`** | `amd64`, `i386`, `arm64` | 225 | | `1.3-0.47-` | tag: `` | **`1.3.x`** | **`0.47.x`** | `amd64`, `i386`, `arm64` | 226 | | `1.3-0.46-` | tag: `` | **`1.3.x`** | **`0.46.x`** | `amd64`, `i386`, `arm64` | 227 | | | | | | | 228 | | `1.2-0.41-` | tag: `` | **`1.2.x`** | **`0.41.x`** | `amd64`, `i386`, `arm64` | 229 | | `1.2-0.40-` | tag: `` | **`1.2.x`** | **`0.40.x`** | `amd64`, `i386`, `arm64` | 230 | | `1.2-0.39-` | tag: `` | **`1.2.x`** | **`0.39.x`** | `amd64`, `i386`, `arm64` | 231 | | `1.2-0.38-` | tag: `` | **`1.2.x`** | **`0.38.x`** | `amd64`, `i386`, `arm64` | 232 | | `1.2-0.37-` | tag: `` | **`1.2.x`** | **`0.37.x`** | `amd64`, `i386`, `arm64` | 233 | | | | | | | 234 | | `1.1-0.39-` | tag: `` | **`1.1.x`** | **`0.39.x`** | `amd64`, `i386`, `arm64` | 235 | | `1.1-0.38-` | tag: `` | **`1.1.x`** | **`0.38.x`** | `amd64`, `i386`, `arm64` | 236 | | `1.1-0.37-` | tag: `` | **`1.1.x`** | **`0.37.x`** | `amd64`, `i386`, `arm64` | 237 | | `1.1-0.36-` | tag: `` | **`1.1.x`** | **`0.36.x`** | `amd64`, `i386`, `arm64` | 238 | | `1.1-0.35-` | tag: `` | **`1.1.x`** | **`0.35.x`** | `amd64`, `i386`, `arm64` | 239 | | | | | | | 240 | | `1.0-0.38-` | tag: `` | **`1.0.x`** | **`0.38.x`** | `amd64`, `i386`, `arm64` | 241 | | `1.0-0.37-` | tag: `` | **`1.0.x`** | **`0.37.x`** | `amd64`, `i386`, `arm64` | 242 | | `1.0-0.36-` | tag: `` | **`1.0.x`** | **`0.36.x`** | `amd64`, `i386`, `arm64` | 243 | | `1.0-0.35-` | tag: `` | **`1.0.x`** | **`0.35.x`** | `amd64`, `i386`, `arm64` | 244 | | `1.0-0.34-` | tag: `` | **`1.0.x`** | **`0.34.x`** | `amd64`, `i386`, `arm64` | 245 | | | | | | | 246 | | `0.15-0.34-` | tag: `` | **`0.15.x`** | **`0.34.x`** | `amd64`, `i386`, `arm64` | 247 | | `0.15-0.33-` | tag: `` | **`0.15.x`** | **`0.33.x`** | `amd64`, `i386`, `arm64` | 248 | | `0.15-0.32-` | tag: `` | **`0.15.x`** | **`0.32.x`** | `amd64`, `i386`, `arm64` | 249 | | `0.15-0.31-` | tag: `` | **`0.15.x`** | **`0.31.x`** | `amd64`, `i386`, `arm64` | 250 | | `0.15-0.30-` | tag: `` | **`0.15.x`** | **`0.30.x`** | `amd64`, `i386`, `arm64` | 251 | | | | | | | 252 | | `0.14-0.34-` | tag: `` | **`0.14.x`** | **`0.34.x`** | `amd64`, `i386`, `arm64` | 253 | | `0.14-0.33-` | tag: `` | **`0.14.x`** | **`0.33.x`** | `amd64`, `i386`, `arm64` | 254 | | `0.14-0.32-` | tag: `` | **`0.14.x`** | **`0.32.x`** | `amd64`, `i386`, `arm64` | 255 | | `0.14-0.31-` | tag: `` | **`0.14.x`** | **`0.31.x`** | `amd64`, `i386`, `arm64` | 256 | | `0.14-0.30-` | tag: `` | **`0.14.x`** | **`0.30.x`** | `amd64`, `i386`, `arm64` | 257 | | | | | | | 258 | | `0.13-0.34-` | tag: `` | **`0.13.x`** | **`0.34.x`** | `amd64`, `i386`, `arm64` | 259 | | `0.13-0.33-` | tag: `` | **`0.13.x`** | **`0.33.x`** | `amd64`, `i386`, `arm64` | 260 | | `0.13-0.32-` | tag: `` | **`0.13.x`** | **`0.32.x`** | `amd64`, `i386`, `arm64` | 261 | | `0.13-0.31-` | tag: `` | **`0.13.x`** | **`0.31.x`** | `amd64`, `i386`, `arm64` | 262 | | `0.13-0.30-` | tag: `` | **`0.13.x`** | **`0.30.x`** | `amd64`, `i386`, `arm64` | 263 | | | | | | | 264 | | `0.12-0.24-` | tag: `` | **`0.12.x`** | **`0.24.x`** | `amd64`, `i386` | 265 | | `0.12-0.23-` | tag: `` | **`0.12.x`** | **`0.23.x`** | `amd64`, `i386` | 266 | | `0.12-0.22-` | tag: `` | **`0.12.x`** | **`0.22.x`** | `amd64`, `i386` | 267 | | `0.12-0.21-` | tag: `` | **`0.12.x`** | **`0.21.x`** | `amd64`, `i386` | 268 | | `0.12-0.20-` | tag: `` | **`0.12.x`** | **`0.20.x`** | `amd64`, `i386` | 269 | | `0.12-0.19-` | tag: `` | **`0.12.x`** | **`0.19.x`** | `amd64`, `i386` | 270 | | | | | | | 271 | | `0.11-0.18-` | tag: `` | **`0.11.x`** | **`0.18.x`** | `amd64`, `i386` | 272 | 273 | Where `` refers to the chosen git tag from this repository. 274 | 275 | 276 | ## :open_file_folder: Docker mounts 277 | 278 | The working directory inside the Docker container is **`/data/`** and should be mounted to your local filesystem where your Terragrant project resides. 279 | (See [Examples](#examples) for mount location usage.) 280 | 281 | 282 | ## :computer: Usage 283 | 284 | ```bash 285 | docker run --rm -v $(pwd):/data cytopia/terragrunt terragrunt 286 | docker run --rm -v $(pwd):/data cytopia/terragrunt terraform 287 | ``` 288 | 289 | ## :capital_abcd: Environment variables 290 | 291 | The following environment variables will ease your life when mounting directories into the docker container by maintaining file system permissions. 292 | 293 | | Variables | Default | Description | 294 | |----------------|---------|-------------| 295 | | `RUN_NON_ROOT` | `0` | Set to `1` to run commands as user instead of root. | 296 | | `UID` | `1000` | Set to the uid of your local user (`id -u`) if you want to run as non root. | 297 | | `GID` | `1000` | Set to the gid of your local user (`id -g`) if you want to run as non root. | 298 | 299 | 300 | ## :information_source: Examples 301 | 302 | ### 1. Simple: Provision single sub-project on AWS 303 | 304 | #### 1.1 Project overview 305 | Let's assume your Terragrunt project setup is as follows: 306 | ```bash 307 | /my/tf # Terragrunt project root 308 | ├── backend-app 309 | │ ├── main.tf 310 | │ └── terragrunt.hcl 311 | ├── frontend-app 312 | │ ├── main.tf 313 | │ └── terragrunt.hcl 314 | ├── mysql # MySQL sub-project directory 315 | │ ├── main.tf 316 | │ └── terragrunt.hcl 317 | ├── redis 318 | │ ├── main.tf 319 | │ └── terragrunt.hcl 320 | └── vpc 321 | ├── main.tf 322 | └── terragrunt.hcl 323 | ``` 324 | The **MySQL** sub-project you want to provision is at the releative path `mysql/`. 325 | 326 | #### 1.2 To consider 327 | 1. Mount the terragrunt root project dir (`/my/tf/`) into `/data/` into the container 328 | 2. Use the workding dir (`-w` or `--workdir`) to point to your project inside the container 329 | 3. Add AWS credentials from your environment to the container 330 | 331 | #### 1.3 Docker commands 332 | ```bash 333 | # Initialize the MySQL project 334 | docker run --rm \ 335 | -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \ 336 | -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ 337 | -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN \ 338 | -u $(id -u):$(id -g) \ 339 | -v /my/tf:/data \ 340 | -w /data/mysql \ 341 | cytopia/terragrunt terragrunt init 342 | 343 | # Plan the MySQL project 344 | docker run --rm \ 345 | -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \ 346 | -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ 347 | -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN \ 348 | -u $(id -u):$(id -g) \ 349 | -v /my/tf:/data \ 350 | -w /data/mysql \ 351 | cytopia/terragrunt terragrunt plan 352 | 353 | # Apply the MySQL project 354 | docker run --rm \ 355 | -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \ 356 | -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ 357 | -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN \ 358 | -u $(id -u):$(id -g) \ 359 | -v /my/tf:/data \ 360 | -w /data/mysql \ 361 | cytopia/terragrunt terragrunt --terragrunt-non-interactive apply 362 | ``` 363 | 364 | 365 | ### 2. Complex: Provision single sub-project on AWS 366 | 367 | #### 2.1 Project overview 368 | Let's assume your Terragrunt project setup is as follows: 369 | ```bash 370 | /my/tf # Terragrunt project root 371 | └── envs 372 |    └── aws 373 |    ├── dev 374 |    │   ├── eu-central-1 375 |    │   │   ├── infra 376 |    │   │   │   └── vpc-k8s # VPC sub-project directory 377 |    │   │   │   ├── terraform.tfvars 378 |    │   │   │   └── terragrunt.hcl 379 |    │   │   ├── microservices 380 |    │   │   │   └── api-gateway 381 |    │   │   │   ├── terraform.tfvars 382 |    │   │   │   └── terragrunt.hcl 383 |    │   │   └── region.tfvars 384 |    │   ├── global 385 |    │   │   └── region.tfvars 386 |    │   └── terragrunt.hcl 387 |    └── _provider_include 388 |    └── include_providers.tf 389 | ``` 390 | The **VPC** sub-project you want to provision is at the relative path `envs/aws/dev/eu-centra-1/infra/vpc-k8s/`. 391 | 392 | #### 2.2 To consider 393 | 1. Mount the terragrunt root project dir (`/my/tf/`) into `/data/` into the container 394 | 2. Use the workding dir (`-w` or `--workdir`) to point to your project inside the container 395 | 3. Add AWS credentials from your environment to the container 396 | 397 | #### 2.3 Docker commands 398 | ```bash 399 | # Initialize the VPC project 400 | docker run --rm \ 401 | -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \ 402 | -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ 403 | -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN \ 404 | -u $(id -u):$(id -g) \ 405 | -v /my/tf:/data \ 406 | -w /data/envs/aws/dev/eu-central-1/infra/vpc-k8s \ 407 | cytopia/terragrunt terragrunt init 408 | 409 | # Plan the VPC project 410 | docker run --rm \ 411 | -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \ 412 | -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ 413 | -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN \ 414 | -u $(id -u):$(id -g) \ 415 | -v /my/tf:/data \ 416 | -w /data/envs/aws/dev/eu-central-1/infra/vpc-k8s \ 417 | cytopia/terragrunt terragrunt plan 418 | 419 | # Apply the VPC project 420 | docker run --rm \ 421 | -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \ 422 | -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ 423 | -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN \ 424 | -u $(id -u):$(id -g) \ 425 | -v /my/tf:/data \ 426 | -w /data/envs/aws/dev/eu-central-1/infra/vpc-k8s \ 427 | cytopia/terragrunt terragrunt --terragrunt-non-interactive apply 428 | ``` 429 | 430 | 431 | 432 | 433 | ## :arrows_counterclockwise: Related [#awesome-ci](https://github.com/topics/awesome-ci) projects 434 | 435 | ### Docker images 436 | 437 | Save yourself from installing lot's of dependencies and pick a dockerized version of your favourite 438 | linter below for reproducible local or remote CI tests: 439 | 440 | | GitHub | DockerHub | Type | Description | 441 | |--------|-----------|------|-------------| 442 | | [awesome-ci][aci-git-lnk] | [![aci-hub-img]][aci-hub-lnk] | Basic | Tools for git, file and static source code analysis | 443 | | [file-lint][flint-git-lnk] | [![flint-hub-img]][flint-hub-lnk] | Basic | Baisc source code analysis | 444 | | [linkcheck][linkcheck-git-lnk] | [![linkcheck-hub-img]][flint-hub-lnk] | Basic | Search for URLs in files and validate their HTTP status code | 445 | | [ansible][ansible-git-lnk] | [![ansible-hub-img]][ansible-hub-lnk] | Ansible | Multiple versions and flavours of Ansible | 446 | | [ansible-lint][alint-git-lnk] | [![alint-hub-img]][alint-hub-lnk] | Ansible | Lint Ansible | 447 | | [gofmt][gfmt-git-lnk] | [![gfmt-hub-img]][gfmt-hub-lnk] | Go | Format Go source code **[1]** | 448 | | [goimports][gimp-git-lnk] | [![gimp-hub-img]][gimp-hub-lnk] | Go | Format Go source code **[1]** | 449 | | [golint][glint-git-lnk] | [![glint-hub-img]][glint-hub-lnk] | Go | Lint Go code | 450 | | [eslint][elint-git-lnk] | [![elint-hub-img]][elint-hub-lnk] | Javascript | Lint Javascript code | 451 | | [jsonlint][jlint-git-lnk] | [![jlint-hub-img]][jlint-hub-lnk] | JSON | Lint JSON files **[1]** | 452 | | [kubeval][kubeval-git-lnk] | [![kubeval-hub-img]][kubeval-hub-lnk] | K8s | Lint Kubernetes files | 453 | | [checkmake][cm-git-lnk] | [![cm-hub-img]][cm-hub-lnk] | Make | Lint Makefiles | 454 | | [phpcbf][pcbf-git-lnk] | [![pcbf-hub-img]][pcbf-hub-lnk] | PHP | PHP Code Beautifier and Fixer | 455 | | [phpcs][pcs-git-lnk] | [![pcs-hub-img]][pcs-hub-lnk] | PHP | PHP Code Sniffer | 456 | | [phplint][plint-git-lnk] | [![plint-hub-img]][plint-hub-lnk] | PHP | PHP Code Linter **[1]** | 457 | | [php-cs-fixer][pcsf-git-lnk] | [![pcsf-hub-img]][pcsf-hub-lnk] | PHP | PHP Coding Standards Fixer | 458 | | [bandit][bandit-git-lnk] | [![bandit-hub-img]][bandit-hub-lnk] | Python | A security linter from PyCQA 459 | | [black][black-git-lnk] | [![black-hub-img]][black-hub-lnk] | Python | The uncompromising Python code formatter | 460 | | [mypy][mypy-git-lnk] | [![mypy-hub-img]][mypy-hub-lnk] | Python | Static source code analysis | 461 | | [pycodestyle][pycs-git-lnk] | [![pycs-hub-img]][pycs-hub-lnk] | Python | Python style guide checker | 462 | | [pydocstyle][pyds-git-lnk] | [![pyds-hub-img]][pyds-hub-lnk] | Python | Python docstyle checker | 463 | | [pylint][pylint-git-lnk] | [![pylint-hub-img]][pylint-hub-lnk] | Python | Python source code, bug and quality checker | 464 | | [terraform-docs][tfdocs-git-lnk] | [![tfdocs-hub-img]][tfdocs-hub-lnk] | Terraform | Terraform doc generator (TF 0.12 ready) **[1]** | 465 | | [terragrunt][tg-git-lnk] | [![tg-hub-img]][tg-hub-lnk] | Terraform | Terragrunt and Terraform | 466 | | [terragrunt-fmt][tgfmt-git-lnk] | [![tgfmt-hub-img]][tgfmt-hub-lnk] | Terraform | `terraform fmt` for Terragrunt files **[1]** | 467 | | [yamlfmt][yfmt-git-lnk] | [![yfmt-hub-img]][yfmt-hub-lnk] | Yaml | Format Yaml files **[1]** | 468 | | [yamllint][ylint-git-lnk] | [![ylint-hub-img]][ylint-hub-lnk] | Yaml | Lint Yaml files | 469 | 470 | > **[1]** Uses a shell wrapper to add **enhanced functionality** not available by original project. 471 | 472 | [aci-git-lnk]: https://github.com/cytopia/awesome-ci 473 | [aci-hub-img]: https://img.shields.io/docker/pulls/cytopia/awesome-ci.svg 474 | [aci-hub-lnk]: https://hub.docker.com/r/cytopia/awesome-ci 475 | 476 | [flint-git-lnk]: https://github.com/cytopia/docker-file-lint 477 | [flint-hub-img]: https://img.shields.io/docker/pulls/cytopia/file-lint.svg 478 | [flint-hub-lnk]: https://hub.docker.com/r/cytopia/file-lint 479 | 480 | [linkcheck-git-lnk]: https://github.com/cytopia/docker-linkcheck 481 | [linkcheck-hub-img]: https://img.shields.io/docker/pulls/cytopia/linkcheck.svg 482 | [linkcheck-hub-lnk]: https://hub.docker.com/r/cytopia/linkcheck 483 | 484 | [jlint-git-lnk]: https://github.com/cytopia/docker-jsonlint 485 | [jlint-hub-img]: https://img.shields.io/docker/pulls/cytopia/jsonlint.svg 486 | [jlint-hub-lnk]: https://hub.docker.com/r/cytopia/jsonlint 487 | 488 | [ansible-git-lnk]: https://github.com/cytopia/docker-ansible 489 | [ansible-hub-img]: https://img.shields.io/docker/pulls/cytopia/ansible.svg 490 | [ansible-hub-lnk]: https://hub.docker.com/r/cytopia/ansible 491 | 492 | [alint-git-lnk]: https://github.com/cytopia/docker-ansible-lint 493 | [alint-hub-img]: https://img.shields.io/docker/pulls/cytopia/ansible-lint.svg 494 | [alint-hub-lnk]: https://hub.docker.com/r/cytopia/ansible-lint 495 | 496 | [kubeval-git-lnk]: https://github.com/cytopia/docker-kubeval 497 | [kubeval-hub-img]: https://img.shields.io/docker/pulls/cytopia/kubeval.svg 498 | [kubeval-hub-lnk]: https://hub.docker.com/r/cytopia/kubeval 499 | 500 | [gfmt-git-lnk]: https://github.com/cytopia/docker-gofmt 501 | [gfmt-hub-img]: https://img.shields.io/docker/pulls/cytopia/gofmt.svg 502 | [gfmt-hub-lnk]: https://hub.docker.com/r/cytopia/gofmt 503 | 504 | [gimp-git-lnk]: https://github.com/cytopia/docker-goimports 505 | [gimp-hub-img]: https://img.shields.io/docker/pulls/cytopia/goimports.svg 506 | [gimp-hub-lnk]: https://hub.docker.com/r/cytopia/goimports 507 | 508 | [glint-git-lnk]: https://github.com/cytopia/docker-golint 509 | [glint-hub-img]: https://img.shields.io/docker/pulls/cytopia/golint.svg 510 | [glint-hub-lnk]: https://hub.docker.com/r/cytopia/golint 511 | 512 | [elint-git-lnk]: https://github.com/cytopia/docker-eslint 513 | [elint-hub-img]: https://img.shields.io/docker/pulls/cytopia/eslint.svg 514 | [elint-hub-lnk]: https://hub.docker.com/r/cytopia/eslint 515 | 516 | [cm-git-lnk]: https://github.com/cytopia/docker-checkmake 517 | [cm-hub-img]: https://img.shields.io/docker/pulls/cytopia/checkmake.svg 518 | [cm-hub-lnk]: https://hub.docker.com/r/cytopia/checkmake 519 | 520 | [pcbf-git-lnk]: https://github.com/cytopia/docker-phpcbf 521 | [pcbf-hub-img]: https://img.shields.io/docker/pulls/cytopia/phpcbf.svg 522 | [pcbf-hub-lnk]: https://hub.docker.com/r/cytopia/phpcbf 523 | 524 | [pcs-git-lnk]: https://github.com/cytopia/docker-phpcs 525 | [pcs-hub-img]: https://img.shields.io/docker/pulls/cytopia/phpcs.svg 526 | [pcs-hub-lnk]: https://hub.docker.com/r/cytopia/phpcs 527 | 528 | [plint-git-lnk]: https://github.com/cytopia/docker-phplint 529 | [plint-hub-img]: https://img.shields.io/docker/pulls/cytopia/phplint.svg 530 | [plint-hub-lnk]: https://hub.docker.com/r/cytopia/phplint 531 | 532 | [pcsf-git-lnk]: https://github.com/cytopia/docker-php-cs-fixer 533 | [pcsf-hub-img]: https://img.shields.io/docker/pulls/cytopia/php-cs-fixer.svg 534 | [pcsf-hub-lnk]: https://hub.docker.com/r/cytopia/php-cs-fixer 535 | 536 | [bandit-git-lnk]: https://github.com/cytopia/docker-bandit 537 | [bandit-hub-img]: https://img.shields.io/docker/pulls/cytopia/bandit.svg 538 | [bandit-hub-lnk]: https://hub.docker.com/r/cytopia/bandit 539 | 540 | [black-git-lnk]: https://github.com/cytopia/docker-black 541 | [black-hub-img]: https://img.shields.io/docker/pulls/cytopia/black.svg 542 | [black-hub-lnk]: https://hub.docker.com/r/cytopia/black 543 | 544 | [mypy-git-lnk]: https://github.com/cytopia/docker-mypy 545 | [mypy-hub-img]: https://img.shields.io/docker/pulls/cytopia/mypy.svg 546 | [mypy-hub-lnk]: https://hub.docker.com/r/cytopia/mypy 547 | 548 | [pycs-git-lnk]: https://github.com/cytopia/docker-pycodestyle 549 | [pycs-hub-img]: https://img.shields.io/docker/pulls/cytopia/pycodestyle.svg 550 | [pycs-hub-lnk]: https://hub.docker.com/r/cytopia/pycodestyle 551 | 552 | [pyds-git-lnk]: https://github.com/cytopia/docker-pydocstyle 553 | [pyds-hub-img]: https://img.shields.io/docker/pulls/cytopia/pydocstyle.svg 554 | [pyds-hub-lnk]: https://hub.docker.com/r/cytopia/pydocstyle 555 | 556 | [pylint-git-lnk]: https://github.com/cytopia/docker-pylint 557 | [pylint-hub-img]: https://img.shields.io/docker/pulls/cytopia/pylint.svg 558 | [pylint-hub-lnk]: https://hub.docker.com/r/cytopia/pylint 559 | 560 | [tfdocs-git-lnk]: https://github.com/cytopia/docker-terraform-docs 561 | [tfdocs-hub-img]: https://img.shields.io/docker/pulls/cytopia/terraform-docs.svg 562 | [tfdocs-hub-lnk]: https://hub.docker.com/r/cytopia/terraform-docs 563 | 564 | [tg-git-lnk]: https://github.com/cytopia/docker-terragrunt 565 | [tg-hub-img]: https://img.shields.io/docker/pulls/cytopia/terragrunt.svg 566 | [tg-hub-lnk]: https://hub.docker.com/r/cytopia/terragrunt 567 | 568 | [tgfmt-git-lnk]: https://github.com/cytopia/docker-terragrunt-fmt 569 | [tgfmt-hub-img]: https://img.shields.io/docker/pulls/cytopia/terragrunt-fmt.svg 570 | [tgfmt-hub-lnk]: https://hub.docker.com/r/cytopia/terragrunt-fmt 571 | 572 | [yfmt-git-lnk]: https://github.com/cytopia/docker-yamlfmt 573 | [yfmt-hub-img]: https://img.shields.io/docker/pulls/cytopia/yamlfmt.svg 574 | [yfmt-hub-lnk]: https://hub.docker.com/r/cytopia/yamlfmt 575 | 576 | [ylint-git-lnk]: https://github.com/cytopia/docker-yamllint 577 | [ylint-hub-img]: https://img.shields.io/docker/pulls/cytopia/yamllint.svg 578 | [ylint-hub-lnk]: https://hub.docker.com/r/cytopia/yamllint 579 | 580 | 581 | ### Makefiles 582 | 583 | Visit **[cytopia/makefiles](https://github.com/cytopia/makefiles)** for dependency-less, seamless project integration and minimum required best-practice code linting for CI. 584 | The provided Makefiles will only require GNU Make and Docker itself removing the need to install anything else. 585 | 586 | 587 | ## :page_facing_up: License 588 | 589 | 590 | **[MIT License](LICENSE)** 591 | 592 | Copyright (c) 2019 [cytopia](https://github.com/cytopia) 593 | --------------------------------------------------------------------------------