Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Global owner
* @bgauduch

# Critical files require explicit review
Dockerfile @bgauduch
.github/workflows/ @bgauduch
security/ @bgauduch
supported_versions.json @bgauduch
16 changes: 16 additions & 0 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ on:
- ".dockerignore"
- "hadolint.yaml"
- ".github/workflows/build-test.yml"
pull_request:
branches:
- master
paths:
- "Dockerfile"
- "supported_versions.json"
- "tests/**"
- ".github/workflows/build-test.yml"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

env:
IMAGE_NAME: "terraform-aws-cli"
Expand Down Expand Up @@ -97,5 +112,6 @@ jobs:
AWS_CLI_VERSION=${{ matrix.awscli_versions }}
tags: ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}
push: false
load: false
cache-from: type=gha
cache-to: type=gha,mode=max
8 changes: 8 additions & 0 deletions .github/workflows/dockerhub-description-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ on:
paths:
- README.md
- .github/workflows/dockerhub-description.yml

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false

permissions:
contents: read

jobs:
dockerHubDescription:
runs-on: ubuntu-22.04
Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/lint-dockerfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,22 @@ on:
- "!master"
paths:
- "Dockerfile"
- "hadolint.yaml"
- ".github/workflows/lint-dockerfile.yml"
pull_request:
branches:
- master
paths:
- "Dockerfile"
- "hadolint.yaml"
- ".github/workflows/lint-dockerfile.yml"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
lint:
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/push-latest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name: push-latest
# trigger on push to master
# only on Dockerfile related modifications
on:
workflow_dispatch:
push:
branches:
- "master"
Expand All @@ -16,6 +17,14 @@ on:
- "supported_platforms.json"
- "tests/**"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false

permissions:
contents: read
packages: write

jobs:
build_push_latest:
runs-on: ubuntu-22.04
Expand Down
32 changes: 32 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ on:
release:
types: [published]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false

permissions:
contents: read
packages: write
id-token: write # required for cosign keyless OIDC signing

jobs:
load_supported_versions:
runs-on: ubuntu-22.04
Expand Down Expand Up @@ -61,3 +70,26 @@ jobs:
push: true
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Generate SBOM
uses: anchore/sbom-action@v0.24.0
with:
image: zenika/terraform-aws-cli:release-${{ env.RELEASE_TAG }}_terraform-${{ matrix.tf_versions }}_awscli-${{ matrix.awscli_versions }}
format: spdx-json
output-file: sbom-tf${{ matrix.tf_versions }}-aws${{ matrix.awscli_versions }}.spdx.json

- name: Upload SBOM to release
uses: anchore/sbom-action/publish-sbom@v0.24.0
with:
sbom-artifact-match: ".*\\.spdx\\.json$"

- name: Install cosign
uses: sigstore/cosign-installer@v4.1.1

- name: Sign published image
env:
COSIGN_EXPERIMENTAL: "true"
run: |
IMAGE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' \
zenika/terraform-aws-cli:release-${{ env.RELEASE_TAG }}_terraform-${{ matrix.tf_versions }}_awscli-${{ matrix.awscli_versions }})
cosign sign --yes "${IMAGE_DIGEST}"
37 changes: 37 additions & 0 deletions .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: scorecard
on:
branch_protection_rule:
schedule:
- cron: "30 1 * * 1"
push:
branches:
- master

permissions: read-all

jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-22.04
permissions:
security-events: write
id-token: write
contents: read
actions: read
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: ossf/scorecard-action@v2.4.3
with:
results_file: results.sarif
results_format: sarif
publish_results: true
- uses: actions/upload-artifact@v4
with:
name: SARIF file
path: results.sarif
retention-days: 5
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
67 changes: 67 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Contributing

Thank you for your interest in contributing to this project!

## How to contribute

1. Fork the repository
2. Create a branch from `master`: `git checkout -b feat/my-feature`
3. Make your changes
4. Ensure tests pass locally: `./dev.sh`
5. Commit using [Conventional Commits](#commit-convention)
6. Push and open a Pull Request targeting `master`

## Commit convention

This project follows the [Conventional Commits](https://www.conventionalcommits.org/) specification.

Format: `<type>(<scope>): <description>`

Common types:
| Type | Use for |
|------|---------|
| `feat` | New feature |
| `fix` | Bug fix |
| `chore` | Maintenance, dependency updates |
| `ci` | CI/CD changes |
| `docs` | Documentation only |
| `refactor` | Code refactoring |
| `test` | Test additions or fixes |
| `security` | Security improvements |

Examples:
```
feat: add support for terraform 2.0
fix(dev.sh): correct platform detection on arm64
chore(deps): update debian base image to bookworm-20250101-slim
ci: add trivy vulnerability scanning
```

PR titles must also follow this convention — the title becomes the squash-merge commit message.

## Local development

Requirements: Docker, `jq`, `envsubst`

```bash
# Build and test with latest supported versions
./dev.sh

# Build and test with specific versions
./dev.sh -a 2.17.0 -t 1.9.0

# Build with a custom tag
./dev.sh -a 2.17.0 -t 1.9.0 -i my-test
```

## Adding a new tool version

When Terraform or AWS CLI releases a new version:

1. Add the version to `supported_versions.json`
2. Download the verification files to `security/` — see [`docs/binaries-verifications.md`](docs/binaries-verifications.md)
3. Open a PR with the changes

## Code review

All PRs require at least one approval. The CI must pass (lint, build, tests) before merging.
31 changes: 18 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ ARG DEBIAN_FRONTEND=noninteractive
FROM debian:${DEBIAN_VERSION} as terraform
ARG TARGETARCH
ARG TERRAFORM_VERSION
RUN apt-get update
# RUN apt-get install --no-install-recommends -y libcurl4=7.74.0-1.3+deb11u7
RUN apt-get install --no-install-recommends -y ca-certificates=20230311
RUN apt-get install --no-install-recommends -y curl=7.88.1-10+deb12u4
RUN apt-get install --no-install-recommends -y gnupg=2.2.40-1.1
RUN apt-get install --no-install-recommends -y unzip=6.0-28
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
ca-certificates=20230311 \
curl=7.88.1-10+deb12u4 \
gnupg=2.2.40-1.1 \
unzip=6.0-28 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /workspace
RUN curl --silent --show-error --fail --remote-name https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_${TARGETARCH}.zip
COPY security/hashicorp.asc ./
Expand All @@ -26,13 +28,16 @@ RUN unzip -j terraform_${TERRAFORM_VERSION}_linux_${TARGETARCH}.zip
# Install AWS CLI version 2
FROM debian:${DEBIAN_VERSION} as aws-cli
ARG AWS_CLI_VERSION
RUN apt-get update
RUN apt-get install -y --no-install-recommends ca-certificates=20230311
RUN apt-get install -y --no-install-recommends curl=7.88.1-10+deb12u4
RUN apt-get install -y --no-install-recommends gnupg=2.2.40-1.1
RUN apt-get install -y --no-install-recommends unzip=6.0-28
RUN apt-get install -y --no-install-recommends git=1:2.39.2-1.1
RUN apt-get install -y --no-install-recommends jq=1.6-2.1
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates=20230311 \
curl=7.88.1-10+deb12u4 \
gnupg=2.2.40-1.1 \
unzip=6.0-28 \
git=1:2.39.2-1.1 \
jq=1.6-2.1 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /workspace
RUN curl --show-error --fail --output "awscliv2.zip" --remote-name "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-${AWS_CLI_VERSION}.zip"
COPY security/awscliv2.asc ./
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

# Terraform and AWS CLI Docker image

[![CI](https://github.com/bgauduch/terraform-aws-cli/actions/workflows/build-test.yml/badge.svg)](https://github.com/bgauduch/terraform-aws-cli/actions/workflows/build-test.yml)
[![Latest Release](https://img.shields.io/github/v/release/bgauduch/terraform-aws-cli)](https://github.com/bgauduch/terraform-aws-cli/releases/latest)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/bgauduch/terraform-aws-cli/badge)](https://securityscorecards.dev/viewer/?uri=github.com/bgauduch/terraform-aws-cli)

## 📦 Supported tags and respective Dockerfile links

Available image tags can be found on the Docker Hub registry: [zenika/terraform-aws-cli](https://hub.docker.com/r/zenika/terraform-aws-cli/tags)
Expand Down Expand Up @@ -90,6 +94,14 @@ TERRAFORM_VERSION=1.5.2
## 🙏 Contributions
Do not hesitate to contribute by [filling an issue](https://github.com/Zenika/terraform-aws-cli/issues) or [a PR](https://github.com/Zenika/terraform-aws-cli/pulls) !

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on how to contribute to this project.

## Security

See [SECURITY.md](SECURITY.md) for the security policy and how to report vulnerabilities.

## 📚 Documentations

* [Dependencies upgrades checklist](https://github.com/zenika-open-source/terraform-aws-cli/tree/master/docs/dependencies-upgrades.md)
Expand Down
51 changes: 41 additions & 10 deletions dev.sh
Original file line number Diff line number Diff line change
@@ -1,27 +1,58 @@
#!/usr/bin/env bash

set -eo pipefail
set -euo pipefail

# FIXME: use getopts function to parse aguments
# FIXME: if provided, both TF and AWS CLI semvers should be regex-validated
trap 'echo "Error: script failed at line ${LINENO}" >&2' ERR

usage() {
echo "Usage: $0 [-a AWS_CLI_VERSION] [-t TF_VERSION] [-i IMAGE_TAG]"
echo " -a AWS CLI version (default: latest from supported_versions.json)"
echo " -t Terraform version (default: latest from supported_versions.json)"
echo " -i Image tag (default: dev)"
exit 1
}

while getopts "a:t:i:h" opt; do
case ${opt} in
a) AWS_VERSION="${OPTARG}" ;;
t) TF_VERSION="${OPTARG}" ;;
i) IMAGE_TAG="${OPTARG}" ;;
h) usage ;;
*) usage ;;
esac
done

# Set AWS and TF CLI to latest supported versions if not specified
[[ -n $1 ]] && AWS_VERSION=$1 || AWS_VERSION=$(jq -r '.awscli_versions | sort | .[-1]' supported_versions.json)
[[ -n $2 ]] && TF_VERSION=$2 || TF_VERSION=$(jq -r '.tf_versions | sort | .[-1]' supported_versions.json)
AWS_VERSION="${AWS_VERSION:-$(jq -r '.awscli_versions | sort | .[-1]' supported_versions.json)}"
TF_VERSION="${TF_VERSION:-$(jq -r '.tf_versions | sort | .[-1]' supported_versions.json)}"

# Set image name and tag (dev if not specified)
IMAGE_NAME="zenika/terraform-aws-cli"
[[ -n $3 ]] && IMAGE_TAG=$3 || IMAGE_TAG="dev"
IMAGE_TAG="${IMAGE_TAG:-dev}"

SEMVER_REGEX="^[0-9]+\.[0-9]+\.[0-9]+$"

validate_semver() {
local version="$1"
local name="$2"
if [[ ! "${version}" =~ ${SEMVER_REGEX} ]]; then
echo "Error: ${name} '${version}' is not a valid semver (expected X.Y.Z)"
exit 1
fi
}

validate_semver "${AWS_VERSION}" "AWS_CLI_VERSION"
validate_semver "${TF_VERSION}" "TERRAFORM_VERSION"

# Set platform for Hadolint image (only linux/arm64 or linux/arm64 supported)
PLATEFORM="linux/$(uname -m)"
# Set platform for Hadolint image (only linux/amd64 or linux/arm64 supported)
PLATFORM="linux/$(uname -m)"

# Lint Dockerfile
echo "Linting Dockerfile..."
docker container run --rm --interactive \
--volume "${PWD}":/data \
--workdir /data \
--platform "${PLATEFORM}" \
--platform "${PLATFORM}" \
hadolint/hadolint:2.12.0-alpine /bin/hadolint \
--config hadolint.yaml Dockerfile
echo "Lint Successful!"
Expand All @@ -30,7 +61,7 @@ echo "Lint Successful!"
echo "Building images with AWS_CLI_VERSION=${AWS_VERSION} and TERRAFORM_VERSION=${TF_VERSION}..."
docker buildx build \
--progress plain \
--platform "${PLATEFORM}" \
--platform "${PLATFORM}" \
--build-arg AWS_CLI_VERSION="${AWS_VERSION}" \
--build-arg TERRAFORM_VERSION="${TF_VERSION}" \
--tag ${IMAGE_NAME}:${IMAGE_TAG} .
Expand Down
Loading
Loading