Skip to content

Commit

Permalink
Merge pull request #3 from mazgi/simplify-startup-process
Browse files Browse the repository at this point in the history
Simplify startup process
  • Loading branch information
mazgi committed Sep 27, 2022
2 parents dfef006 + c6c4ee0 commit d31a269
Show file tree
Hide file tree
Showing 18 changed files with 506 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: default
name: use-multiple-platforms

on:
push:
Expand All @@ -7,16 +7,20 @@ on:
jobs:
provisioning:
timeout-minutes: 10
runs-on: ubuntu-latest
runs-on: ${{ matrix.runs-on }}
strategy:
matrix:
backend:
- azurerm
- gcs
- s3
runs-on:
- ubuntu-latest
# - macos-latest
# - windows-latest
steps:
- uses: actions/checkout@v3
- name: Set up environment variables
- name: Export UIDs as environment variables
run: |
cat<<EOE > .env
# Todo https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-githubs-ip-addresses
Expand All @@ -28,9 +32,15 @@ jobs:
- name: Set the backend type to ${{ matrix.backend }}
run: |
echo "_TERRAFORM_BACKEND_TYPE=${{ matrix.backend }}" >> .env
- name: Generate and export Project ID as the environment variable
run: |
export _B=${{ matrix.backend }}
export _R=${{ matrix.runs-on }}
echo "PROJECT_UNIQUE_ID=${PROJECT_UNIQUE_ID}-m${_B:0:1}${_R:0:1}" >> .env
env:
PROJECT_UNIQUE_ID: ${{ secrets.PROJECT_UNIQUE_ID }}
- name: Export credentials
run: |
echo "PROJECT_UNIQUE_ID=${PROJECT_UNIQUE_ID}" >> .env
echo "AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}" >> .env
echo "AWS_ACCOUNT_ID=${AWS_ACCOUNT_ID}" >> .env
echo "AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}" >> .env
Expand All @@ -40,7 +50,6 @@ jobs:
echo "ARM_TENANT_ID=${ARM_TENANT_ID}" >> .env
echo "CLOUDSDK_CORE_PROJECT=${CLOUDSDK_CORE_PROJECT}" >> .env
env:
PROJECT_UNIQUE_ID: ${{ secrets.PROJECT_UNIQUE_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
Expand Down Expand Up @@ -79,7 +88,7 @@ jobs:
docker compose logs
- name: Exec Terraform - check the format for each tf file
run: |
docker compose exec provisioning terraform fmt -check
docker compose exec provisioning terraform fmt -check -recursive
- name: Exec Terraform - validate
run: |
docker compose exec provisioning terraform validate
Expand All @@ -95,6 +104,6 @@ jobs:
- name: Stop the service
timeout-minutes: 1
run: |
rm -rf tmp/run/container-*/
rm -rf tmp/run/container-*/ || true
sleep 2
docker compose down --remove-orphans
116 changes: 116 additions & 0 deletions .github/workflows/use-one-platform.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
name: use-one-platform

on:
push:
workflow_dispatch:

jobs:
provisioning:
timeout-minutes: 10
runs-on: ${{ matrix.runs-on }}
strategy:
matrix:
platform:
- aws
- azure
- google-cloud
runs-on:
- ubuntu-latest
# - macos-latest
# - windows-latest
steps:
- uses: actions/checkout@v3
- name: Export UIDs as environment variables
run: |
cat<<EOE > .env
# Todo https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-githubs-ip-addresses
TF_VAR_allowed_ipaddr_list=["0.0.0.0/0"]
EOE
echo "UID=$(id -u)" >> .env
echo "GID=$(id -g)" >> .env
echo "DOCKER_GID=$(getent group docker | cut -d : -f 3)" >> .env
- name: Generate and export Project ID as the environment variable
run: |
export _P=${{ matrix.platform }}
export _R=${{ matrix.runs-on }}
echo "PROJECT_UNIQUE_ID=${PROJECT_UNIQUE_ID}-1${_P:0:2}${_R:0:1}" >> .env
env:
PROJECT_UNIQUE_ID: ${{ secrets.PROJECT_UNIQUE_ID }}
- name: Export credentials for AWS
if: matrix.platform == 'aws'
run: |
echo "AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}" >> .env
echo "AWS_ACCOUNT_ID=${AWS_ACCOUNT_ID}" >> .env
echo "AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}" >> .env
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Export credentials for Azure
if: matrix.platform == 'azure'
run: |
echo "ARM_CLIENT_ID=${ARM_CLIENT_ID}" >> .env
echo "ARM_CLIENT_SECRET=${ARM_CLIENT_SECRET}" >> .env
echo "ARM_SUBSCRIPTION_ID=${ARM_SUBSCRIPTION_ID}" >> .env
echo "ARM_TENANT_ID=${ARM_TENANT_ID}" >> .env
env:
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
- name: Export credentials for Google Cloud
if: matrix.platform == 'google-cloud'
run: |
echo "CLOUDSDK_CORE_PROJECT=${CLOUDSDK_CORE_PROJECT}" >> .env
env:
CLOUDSDK_CORE_PROJECT: ${{ secrets.CLOUDSDK_CORE_PROJECT }}
- name: Export GOOGLE_SA_KEY
if: matrix.platform == 'google-cloud'
run: |
echo ${GOOGLE_SA_KEY} > config/credentials/google-cloud-keyfile.provisioning-owner.json
jq -e '. | select(.type=="service_account")' config/credentials/google-cloud-keyfile.provisioning-owner.json > /dev/null
env:
GOOGLE_SA_KEY: ${{ secrets.GOOGLE_SA_KEY }}
- name: (debug)Check services
run: |
docker compose --profile=use-only-${{ matrix.platform }} config provisioning-use-only-${{ matrix.platform }}
- name: Build containers
timeout-minutes: 4
run: |
docker compose --profile=use-only-${{ matrix.platform }} build provisioning-use-only-${{ matrix.platform }}
- name: Start the service
timeout-minutes: 4
run: |
docker compose --profile=use-only-${{ matrix.platform }} up provisioning-use-only-${{ matrix.platform }} --detach
while :
do
docker compose --profile=use-only-${{ matrix.platform }} ps --format=json provisioning-use-only-${{ matrix.platform }}\
| jq -e '.[] | select(.Health=="healthy")' 2> /dev/null\
&& break
sleep 1
done
- name: Show service logs
timeout-minutes: 1
run: |
docker compose --profile=use-only-${{ matrix.platform }} logs provisioning-use-only-${{ matrix.platform }}
- name: Exec Terraform - check the format for each tf file
run: |
docker compose --profile=use-only-${{ matrix.platform }} exec provisioning-use-only-${{ matrix.platform }} terraform fmt -check -recursive
- name: Exec Terraform - validate
run: |
docker compose --profile=use-only-${{ matrix.platform }} exec provisioning-use-only-${{ matrix.platform }} terraform validate
- name: Exec Terraform - dry-run
timeout-minutes: 1
run: |
docker compose --profile=use-only-${{ matrix.platform }} exec provisioning-use-only-${{ matrix.platform }} terraform plan
- name: Exec Terraform - apply
timeout-minutes: 1
if: github.ref == 'refs/heads/main'
run: |
docker compose --profile=use-only-${{ matrix.platform }} exec provisioning-use-only-${{ matrix.platform }} terraform apply -auto-approve
- name: Stop the service
timeout-minutes: 1
run: |
rm -rf tmp/run/container-*/ || true
sleep 2
docker compose --profile=use-only-${{ matrix.platform }} down --remove-orphans
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.env
.terraform-version
.terraform.lock.hcl
node_modules/
16 changes: 16 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"[terraform]": {
"editor.defaultFormatter": "hashicorp.terraform",
"editor.formatOnSave": true,
"editor.formatOnSaveMode": "file"
},
"[terraform-vars]": {
"editor.defaultFormatter": "hashicorp.terraform",
"editor.formatOnSave": true,
"editor.formatOnSaveMode": "file"
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"terraform.experimentalFeatures.validateOnSave": true,
"terraform.languageServer.enable": true
}
31 changes: 26 additions & 5 deletions Dockerfile.d/provisioning/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
# See https://github.com/mazgi/dockerfiles/blob/main/Dockerfile.d/provisioning/with-user.Dockerfile
# See https://github.com/mazgi/dockerfiles/blob/main/Dockerfile.d/provisioning/customize-example.Dockerfile
FROM ghcr.io/mazgi/provisioning

# Set in non-interactive mode.
ENV DEBIAN_FRONTEND=noninteractive

# https://www.terraform.io/downloads.html
ARG TERRAFORM_VERSIONS=1.2.8
ENV TERRAFORM_VERSIONS=${TERRAFORM_VERSIONS}

ARG DOCKER_GID
ARG GID=0
ARG UID=0
ENV DOCKER_GID=${DOCKER_GID}
ENV GID=${GID:-0}
ENV UID=${UID:-0}

COPY rootfs /
RUN :\
&& cd /usr/local/bin\
&& ln -fs echo-with-color.zsh echoDebug\
&& ln -fs echo-with-color.zsh echoInfo\
&& ln -fs echo-with-color.zsh echoWarn\
&& ln -fs echo-with-color.zsh echoErr\
&& :

HEALTHCHECK --interval=2s --timeout=1s --retries=2 --start-period=5s\
CMD jq -e ". | select(.succeeded)" $(docker-util.keep-running.zsh --print-status-file-path)

RUN : Terraform\
# Install Terraform via tfenv
&& echo $TERRAFORM_VERSIONS | tr ',' '\n' | xargs -IV tfenv install V\
# use the beginning version on the list
&& tfenv use ${TERRAFORM_VERSIONS%%,*}\
&& :

RUN :\
# Create a user for development who has the same UID and GID as you.
&& useradd --comment '' --create-home --gid users --uid ${UID} developer\
Expand All @@ -21,12 +44,10 @@ RUN :\
&& usermod --append --groups docker developer 2> /dev/null || true\
# It will be duplicate UID or GID with "node" user when your UID==1000 or GID==100.
&& echo '%users ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/grant-all-without-password-to-users\
&& echo '%developer ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/grant-all-without-password-to-developer
&& echo '%developer ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/grant-all-without-password-to-developer\
&& :

# Reset DEBIAN_FRONTEND to default(`dialog`).
# If you no need `dialog`, you can set `DEBIAN_FRONTEND=readline`.
# see also: man 7 debconf
ENV DEBIAN_FRONTEND=

COPY rootfs /
ENTRYPOINT [ "/usr/local/bin/docker-entrypoint.start-services.zsh" ]
5 changes: 5 additions & 0 deletions Dockerfile.d/provisioning/rootfs/etc/ansible/ansible.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[defaults]
host_key_checking = False

[ssh_connection]
ssh_args = -o UserKnownHostsFile=/dev/null
Empty file.
17 changes: 17 additions & 0 deletions Dockerfile.d/provisioning/rootfs/etc/zsh/zlogin
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
autoload -U bashcompinit; bashcompinit
autoload -Uz compinit; compinit
# https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-completion.html#cli-command-completion-linux
if (( $+commands[aws_completer] )); then
complete -C aws_completer aws
fi
if [[ -f /etc/bash_completion.d/azure-cli ]]; then
source /etc/bash_completion.d/azure-cli
fi
if [[ -f /usr/share/google-cloud-sdk/completion.zsh.inc ]]; then
source /usr/share/google-cloud-sdk/completion.zsh.inc
fi
# https://www.terraform.io/cli/commands#shell-tab-completion
if (( $+commands[terraform] )); then
complete -C terraform terraform
fi
eval "$(starship init zsh)"

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env -S zsh -eu

readonly local SCRIPT_NAME=$(basename $0)
readonly local STATUS_FILE=/var/run/container-stat-myself/status.json
getStatusFilePath () {
echo ${STATUS_FILE:?}
}
resetStatus () {
echoDebug "Reset the status."
readonly local _dir=$(dirname ${STATUS_FILE:?})
sudo mkdir -p ${_dir:?}/
sudo chmod 777 ${_dir:?}/
echo '{}' > ${STATUS_FILE:?}
}
updateStatusToSucceeded () {
echoDebug "Update the status to succeeded."
readonly local _tmpfile=${STATUS_FILE:?}.tmp
cp ${STATUS_FILE:?} ${_tmpfile:?}
jq '. + {succeeded:true}' ${_tmpfile:?} | tee ${STATUS_FILE:?}
rm -rf ${_tmpfile:?}
}
updateStatusToFailed () {
echoDebug "Update the status to succeeded."
readonly local _tmpfile=${STATUS_FILE:?}.tmp
cp ${STATUS_FILE:?} ${_tmpfile:?}
jq '. + {succeeded:false}' ${_tmpfile:?} | tee ${STATUS_FILE:?}
rm -rf ${_tmpfile:?}
}

showHelp() {
echo "Usage: ${SCRIPT_NAME} [OPTIONS]"
echo "Options:"
echo "\t-h, --help\t\tShow this help message."
echo "\t-p, --print-status-file-path\t\t(TBD)."
echo "\t-f, --record-failure\t\t(TBD)."
echo "\t-r, --reset-status\t\t(TBD)."
echo "\t-s, --record-success\t\t(TBD)."
echo "\t-w, --wait-signals\t\t(TBD)."
}

args=$(getopt -o hpfrsw -l help,print-status-file-path,record-failure,reset-status,record-success,wait-signals -- "$@") || exit 1
eval "set -- $args"
while [ $# -gt 0 ]; do
case $1 in
-h | --help)
showHelp
shift; exit 1;;
-p | --print-status-file-path)
getStatusFilePath
shift; exit 0;;
-f | --record-failure)
updateStatusToFailed
shift; exit 0;;
-r | --reset-status)
resetStatus
shift; exit 0;;
-s | --record-success)
updateStatusToSucceeded
shift; exit 0;;
-w | --wait-signals)
# Nothing todo.
shift; break;;
--)
shift; break;;
esac
done

trapSigTerm () {
echoDebug "Exit by SIGTERM."
trap SIGTERM
exit 0
}
trap 'trapSigTerm' SIGTERM

echoInfo '✅ You are all set!'
# http:https://patorjk.com/software/taag/#p=display&f=Calvin%20S&t=you're%20all%20set
echoDebug '┬ ┬┌─┐┬ ┬┬─┐┌─┐ ┌─┐┬ ┬ ┌─┐┌─┐┌┬┐'
echoDebug '└┬┘│ ││ │├┬┘├┤ ├─┤│ │ └─┐├┤ │ '
echoDebug ' ┴ └─┘└─┘┴└─└─┘ ┴ ┴┴─┘┴─┘ └─┘└─┘ ┴ '
echoDebug "Turn in infinity sleep..."
sleep infinity &; readonly local SLEEP_PID=$!
wait ${SLEEP_PID}
exit $?
Loading

0 comments on commit d31a269

Please sign in to comment.