├── .github ├── dependabot.yml ├── pull_request_template.md └── workflows │ ├── auto-labeler.yml │ ├── deploy-docker-image-main.yml │ ├── deploy-docker-image-release.yml │ ├── docker-image-ci.yml │ ├── dockerfile-lint.yml │ ├── greeting.yml │ ├── toolkit-updater.yaml │ └── vulnerability-scanner.yaml ├── .gitignore ├── CODEOWNERS ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── assets └── images │ └── devops-toolkit.jpg ├── demo ├── README.md └── provistion-azure-vm │ ├── .terraform.lock.hcl │ ├── README.md │ ├── main.tf │ ├── output.tf │ ├── providers.tf │ ├── ssh.tf │ └── variables.tf ├── docs ├── build │ └── build_toolkit_image.md ├── others │ └── README.md ├── troubleshooting │ └── TROUBLESHOOTING.md └── usage │ ├── README.md │ ├── ansible_usage.md │ ├── awscli_usage.md │ ├── azurecli_usage.md │ ├── helm_usage.md │ ├── kubectl_usage.md │ ├── python_usage.md │ ├── run_mode.md │ └── terraform_usage.md ├── entrypoint.sh ├── pr-changelog.txt ├── samples ├── README.md ├── ansible │ └── check_os.yml ├── python │ └── rectangle_area_calculator.py ├── run_sample.sh └── terraform │ └── basic │ └── main.tf ├── script_requirements.txt ├── scripts ├── check_latest_version.py ├── check_version_in_toolkit.sh ├── docker_build.sh ├── parse_diff.py └── update_latest_version.py └── toolkit_info.json /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" 8 | - package-ecosystem: "docker" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Closes: #XXX 2 | 3 | ## Changes 4 | 5 | - DescribeYourChangeHere 6 | -------------------------------------------------------------------------------- /.github/workflows/auto-labeler.yml: -------------------------------------------------------------------------------- 1 | name: Auto Labeler 2 | on: 3 | issues: 4 | types: 5 | - reopened 6 | - opened 7 | - edited 8 | 9 | pull_request: 10 | types: 11 | - reopened 12 | - opened 13 | - edited 14 | 15 | jobs: 16 | auto_labeler: 17 | # Add permission to update PR and issue labels 18 | permissions: 19 | issues: write 20 | pull-requests: write 21 | 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: Extract labels from title 25 | id: extract_labels 26 | run: | 27 | # Supported labels definition 28 | supported_labels=("ci" "doc" "core" "bug" "enhancement" "sample" "usage") 29 | 30 | # Get title 31 | if [[ "${{ github.event_name }}" == "pull_request" ]]; then 32 | title="${{ github.event.pull_request.title }}" 33 | number="${{ github.event.pull_request.number }}" 34 | type="pr" 35 | elif [[ "${{ github.event_name }}" == "issues" ]]; then 36 | title="${{ github.event.issue.title }}" 37 | number="${{ github.event.issue.number }}" 38 | type="issue" 39 | else 40 | echo "Invalid event type: ${{ github.event_name }}" 41 | exit 1 42 | fi 43 | 44 | # Function to parse title and return supported labels 45 | echo "Analyzing pull request title: '${title}'" 46 | 47 | # Parse title and return supported labels 48 | parsed_labels="" 49 | for label in "${supported_labels[@]}"; do 50 | if [[ $title == *"${label}"* ]]; then 51 | if [[ $parsed_labels == "" ]]; then 52 | # Cover init case 53 | parsed_labels="${label}" 54 | else 55 | parsed_labels="${parsed_labels},${label}" 56 | fi 57 | echo "Added label ${label}" 58 | fi 59 | done 60 | 61 | # Remove trailing semicolon if present 62 | parsed_labels="${parsed_labels%;}" 63 | echo "$parsed_labels" 64 | 65 | # Main script 66 | if [ -z "$title" ]; then 67 | echo "Please provide a title." 68 | exit 1 69 | fi 70 | 71 | echo "labels=${parsed_labels}" >> $GITHUB_OUTPUT 72 | echo "number=${number}" >> $GITHUB_OUTPUT 73 | echo "type=${type}" >> $GITHUB_OUTPUT 74 | echo $GITHUB_OUTPUT 75 | 76 | - name: Add labels to the PR/issue 77 | if: steps.extract_labels.outputs.labels != '' 78 | run: gh "$TYPE" edit "$NUMBER" --add-label "$LABELS" 79 | env: 80 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 81 | GH_REPO: ${{ github.repository }} 82 | NUMBER: ${{ steps.extract_labels.outputs.number }} 83 | TYPE: ${{ steps.extract_labels.outputs.type }} 84 | LABELS: ${{ steps.extract_labels.outputs.labels }} 85 | -------------------------------------------------------------------------------- /.github/workflows/deploy-docker-image-main.yml: -------------------------------------------------------------------------------- 1 | name: Deploy - Docker Image Latest (main) 2 | 3 | on: 4 | workflow_dispatch: 5 | ## TODO: Implement the auto push later, manual release latest image for now 6 | # push: 7 | # branches: main 8 | # paths: 9 | # - 'Dockerfile' 10 | # - 'scripts/*' 11 | # - '.github/workflows/*' 12 | 13 | jobs: 14 | buildandpush: 15 | runs-on: ubuntu-latest 16 | # Docs: https://docs.github.com/en/actions/deployment/about-deployments/deploying-with-github-actions 17 | environment: dockerhub 18 | steps: 19 | - name: Check out the repo 20 | uses: actions/checkout@v4 21 | 22 | - name: Login to Docker Hub 23 | uses: docker/login-action@v3 24 | with: 25 | username: ${{ secrets.DOCKERHUB_USERNAME }} 26 | password: ${{ secrets.DOCKERHUB_TOKEN }} 27 | 28 | - name: Build the Docker image 29 | run: | 30 | docker build . --file Dockerfile --tag "devops-toolkit-merge:$GITHUB_SHA" 31 | 32 | - name: Verify tool versions 33 | run: | 34 | cd scripts 35 | chmod +x check_version_in_toolkit.sh 36 | ./check_version_in_toolkit.sh "devops-toolkit-merge:$GITHUB_SHA" "../toolkit_info.json" 37 | 38 | - name: Running Sample Tool Code 39 | run: | 40 | echo "Run sample tool code inside toolkit" 41 | docker run --rm devops-toolkit-merge:$GITHUB_SHA samples/run_sample.sh 42 | 43 | - name: Push Docker Image 44 | run: | 45 | SHA7=${GITHUB_SHA::7} 46 | docker tag "devops-toolkit-merge:$GITHUB_SHA" "tungbq/devops-toolkit:main-$SHA7" 47 | docker tag "devops-toolkit-merge:$GITHUB_SHA" "tungbq/devops-toolkit:latest" 48 | docker images 49 | echo "Push image with SHA" 50 | docker push "tungbq/devops-toolkit:main-$SHA7" 51 | echo "Push latest image" 52 | docker push "tungbq/devops-toolkit:latest" 53 | 54 | - name: Docker Hub Description 55 | uses: peter-evans/dockerhub-description@v4 56 | with: 57 | username: ${{ secrets.DOCKERHUB_USERNAME }} 58 | password: ${{ secrets.DOCKERHUB_TOKEN }} 59 | repository: tungbq/devops-toolkit 60 | enable-url-completion: true 61 | -------------------------------------------------------------------------------- /.github/workflows/deploy-docker-image-release.yml: -------------------------------------------------------------------------------- 1 | name: Deploy - Docker Image Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | buildandpush: 10 | runs-on: ubuntu-latest 11 | # Docs: https://docs.github.com/en/actions/deployment/about-deployments/deploying-with-github-actions 12 | environment: dockerhub 13 | steps: 14 | - name: Check out the repo 15 | uses: actions/checkout@v4 16 | 17 | - name: Extract tag name 18 | id: extract_tag 19 | run: echo "TAG_NAME=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV 20 | 21 | - name: Login to Docker Hub 22 | uses: docker/login-action@v3 23 | with: 24 | username: ${{ secrets.DOCKERHUB_USERNAME }} 25 | password: ${{ secrets.DOCKERHUB_TOKEN }} 26 | 27 | - name: Build the Docker image 28 | run: | 29 | docker build . --file Dockerfile --tag "devops-toolkit-release:${{ env.TAG_NAME }}" 30 | 31 | - name: Verify tool versions 32 | run: | 33 | cd scripts 34 | chmod +x check_version_in_toolkit.sh 35 | ./check_version_in_toolkit.sh "devops-toolkit-release:${{ env.TAG_NAME }}" "../toolkit_info.json" 36 | 37 | - name: Running Sample Tool Code 38 | run: | 39 | echo "Run sample tool code inside toolkit" 40 | docker run --rm devops-toolkit-release:${{ env.TAG_NAME }} samples/run_sample.sh 41 | 42 | - name: Push Docker Image 43 | run: | 44 | docker tag "devops-toolkit-release:${{ env.TAG_NAME }}" "tungbq/devops-toolkit:${{ env.TAG_NAME }}" 45 | docker tag "devops-toolkit-release:${{ env.TAG_NAME }}" "tungbq/devops-toolkit:latest" 46 | docker images 47 | echo "Push image with TAG_NAME" 48 | docker push "tungbq/devops-toolkit:${{ env.TAG_NAME }}" 49 | echo "Push latest image" 50 | docker push "tungbq/devops-toolkit:latest" 51 | 52 | - name: Docker Hub Description 53 | uses: peter-evans/dockerhub-description@v4 54 | with: 55 | username: ${{ secrets.DOCKERHUB_USERNAME }} 56 | password: ${{ secrets.DOCKERHUB_TOKEN }} 57 | repository: tungbq/devops-toolkit 58 | enable-url-completion: true 59 | -------------------------------------------------------------------------------- /.github/workflows/docker-image-ci.yml: -------------------------------------------------------------------------------- 1 | name: Docker Image CI 2 | 3 | on: 4 | pull_request: 5 | branches: ['main'] 6 | paths: 7 | - 'Dockerfile' 8 | - 'scripts/*' 9 | - '.github/workflows/docker-image-ci.yml' 10 | - 'samples/' 11 | 12 | # Abort the previous running CI workflow in the same pull request 13 | concurrency: 14 | group: ${{ github.workflow }}-${{ github.ref }} 15 | cancel-in-progress: true 16 | 17 | jobs: 18 | build: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Check out the repo 22 | uses: actions/checkout@v4 23 | 24 | - name: Build the Docker image 25 | run: | 26 | SHA7=${GITHUB_SHA::7} 27 | echo $SHA7 28 | docker build . --file Dockerfile --tag "devops-toolkit-review:$GITHUB_SHA" 29 | 30 | - name: Verify tool versions 31 | run: | 32 | cd scripts 33 | chmod +x check_version_in_toolkit.sh 34 | ./check_version_in_toolkit.sh "devops-toolkit-review:$GITHUB_SHA" "../toolkit_info.json" 35 | 36 | - name: Running Sample Tool Code 37 | run: | 38 | echo "Run sample tool code inside toolkit" 39 | docker run --rm devops-toolkit-review:$GITHUB_SHA samples/run_sample.sh 40 | -------------------------------------------------------------------------------- /.github/workflows/dockerfile-lint.yml: -------------------------------------------------------------------------------- 1 | name: Dockerfile Lint 2 | 3 | on: 4 | pull_request: 5 | branches: [ "main" ] 6 | paths: ["Dockerfile"] 7 | 8 | # Abort the previous running CI workflow in the same pull request 9 | concurrency: 10 | group: ${{ github.workflow }}-${{ github.ref }} 11 | cancel-in-progress: true 12 | 13 | jobs: 14 | dockerfile-lint: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: Run Dockerfile lint 19 | # https://github.com/hadolint/hadolint 20 | # TODO: find better alternatives? 21 | # Do no fail the workflow on linter error at initial phase, will update this workflow later 22 | run: docker run --rm -i hadolint/hadolint < Dockerfile || true 23 | -------------------------------------------------------------------------------- /.github/workflows/greeting.yml: -------------------------------------------------------------------------------- 1 | name: Greetings 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | issues: 8 | types: 9 | - opened 10 | 11 | jobs: 12 | greeting: 13 | runs-on: ubuntu-latest 14 | if: ${{ github.actor != 'all-contributors[bot]' && github.event.pull_request.user.login != 'tungbq' }} 15 | permissions: 16 | issues: write 17 | pull-requests: write 18 | steps: 19 | - uses: actions/first-interaction@v1 20 | with: 21 | repo-token: ${{ secrets.GITHUB_TOKEN }} 22 | issue-message: "Hi, thanks for your contribution!🎉 Great first issue! \n If you find this repository helpful, kindly consider showing your appreciation by giving it a star ⭐ Thanks! 💖" 23 | pr-message: "Hi, thanks for your contribution!🎉 Great first PR! \n If you find this repository helpful, kindly consider showing your appreciation by giving it a star ⭐ Thanks! 💖" 24 | -------------------------------------------------------------------------------- /.github/workflows/toolkit-updater.yaml: -------------------------------------------------------------------------------- 1 | name: Update Toolkit 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 */14 * 6' # Run every 14 days on Saturday at midnight 6 | workflow_dispatch: 7 | 8 | jobs: 9 | update-versions: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout Repository 14 | uses: actions/checkout@v4 15 | 16 | - name: Set up Python 17 | uses: actions/setup-python@v5 18 | with: 19 | python-version: 3.11 20 | 21 | - name: Install Dependencies 22 | run: | 23 | python -m pip install --upgrade pip 24 | # Dependencies for python script under 'scripts' 25 | python -m pip install -r script_requirements.txt 26 | 27 | - name: Get Latest Version 28 | run: python scripts/check_latest_version.py "./toolkit_info.json" 29 | 30 | - name: Update Version 31 | run: python scripts/update_latest_version.py "./toolkit_info.json" "./Dockerfile" "./README.md" 32 | 33 | - name: Prepare PR changelog 34 | run: | 35 | # Init PR description 36 | echo "core: update tool versions" > pr-changelog.txt 37 | echo "" >> pr-changelog.txt 38 | 39 | # Add details version changed PR description 40 | python scripts/parse_diff.py "./toolkit_info.json" >> pr-changelog.txt 41 | 42 | # Additional PR description info 43 | echo "" >> pr-changelog.txt 44 | echo "Auto-generated by [create-pull-request](https://github.com/peter-evans/create-pull-request)" >> pr-changelog.txt 45 | 46 | cat pr-changelog.txt 47 | 48 | - name: Create Pull Request 49 | id: cpr 50 | uses: peter-evans/create-pull-request@v7 51 | with: 52 | token: ${{ secrets.PAT }} 53 | commit-message: 'core: update tool versions' 54 | committer: 'github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>' 55 | author: '${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>' 56 | signoff: false 57 | branch: update-toolkit 58 | branch-suffix: timestamp 59 | delete-branch: true 60 | base: 'main' 61 | title: 'core: update tool versions' 62 | body-path: pr-changelog.txt 63 | labels: 'upgrade, automated-pr, core' 64 | -------------------------------------------------------------------------------- /.github/workflows/vulnerability-scanner.yaml: -------------------------------------------------------------------------------- 1 | name: Scans container images 2 | on: 3 | schedule: 4 | - cron: '0 0 */14 * 6' # Run every 14 days on Saturday at midnight 5 | workflow_dispatch: 6 | jobs: 7 | build: 8 | name: Scan 9 | runs-on: ubuntu-24.04 10 | steps: 11 | - name: Run Trivy vulnerability scanner 12 | uses: aquasecurity/trivy-action@0.31.0 13 | with: 14 | image-ref: 'tungbq/devops-toolkit:latest' 15 | format: 'table' 16 | exit-code: '1' 17 | ignore-unfixed: true 18 | vuln-type: 'os,library' 19 | severity: 'CRITICAL,HIGH' 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | 8 | # Crash log files 9 | crash.log 10 | crash.*.log 11 | 12 | # Exclude all .tfvars files, which are likely to contain sensitive data, such as 13 | # password, private keys, and other secrets. These should not be part of version 14 | # control as they are data points which are potentially sensitive and subject 15 | # to change depending on the environment. 16 | *.tfvars 17 | *.tfvars.json 18 | 19 | # Ignore override files as they are usually used to override resources locally and so 20 | # are not checked in 21 | override.tf 22 | override.tf.json 23 | *_override.tf 24 | *_override.tf.json 25 | 26 | # Ignore transient lock info files created by terraform apply 27 | .terraform.tfstate.lock.info 28 | 29 | # Include override files you do wish to add to version control using negated pattern 30 | # !example_override.tf 31 | 32 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 33 | # example: *tfplan* 34 | 35 | # Ignore CLI configuration files 36 | .terraformrc 37 | terraform.rc 38 | 39 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @tungbq 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | The following information provides a set of guidelines for contributing to the tungbq/devops-toolkit chain main repo. Use your best judgment, and, if you see room for improvement, please propose changes to this document. 4 | 5 | ## First steps 6 | 7 | The first step is to find an issue you want to fix. To identify issues we think are good for first-time contributors, we add the **good first issue** label. 8 | Once you find an existing issue that you want to work on or if you have a new issue to create, continue below. 9 | 10 | ## Proposing changes 11 | 12 | To contribute a change proposal, use the following workflow: 13 | 14 | 1. [Fork the repository](https://github.com/tungbq/devops-toolkit). 15 | 2. If you find this repository helpful, kindly consider showing your appreciation by giving it a star ⭐ Thanks! 💖 16 | 3. [Add an upstream](https://docs.github.com/en/github/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) so that you can update your fork. 17 | 4. Clone your fork to your computer. 18 | 5. Create a branch and name it appropriately. 19 | 6. Work on only one major change in one pull request. 20 | 7. Make sure all tests are passing locally. 21 | 8. Next, rinse and repeat the following: 22 | 23 | 1. Commit your changes. Write a simple, straightforward commit message. To learn more, see [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/). 24 | 2. Push your changes to your remote fork. To add your remote, you can copy/paste the following: 25 | 26 | ```sh 27 | 28 | #Remove origin 29 | 30 | git remote remove origin 31 | 32 | #set a new remote 33 | 34 | git remote add my_awesome_new_remote_repo [insert-link-found-in-source-subtab-of-your-repo] 35 | 36 | #Verify new remote 37 | 38 | git remote -v 39 | 40 | > my_awesome_new_remote_repo [link-found-in-source-subtab-of-your-repo] (fetch) 41 | > my_awesome_new_remote_repo [link-found-in-source-subtab-of-your-repo] (push) 42 | 43 | #Push changes to your remote repo 44 | 45 | git push 46 | 47 | #e.g. git push my_awesome_new_remote_repo 48 | ``` 49 | 50 | 3. Create a PR on the devops-toolkit repository. There should be a PR template to help you do so. 51 | 4. Wait for your changes to be reviewed. If you are a maintainer, you can assign your PR to one or more reviewers. If you aren't a maintainer, one of the maintainers will assign a reviewer. 52 | 5. After you receive feedback from a reviewer, make the requested changes, commit them to your branch, and push them to your remote fork again. 53 | 6. Once approval is given, feel free to squash & merge! -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Use the official Ubuntu 22.04 base image 2 | ARG UBUNTU_VERSION=22.04 3 | FROM ubuntu:${UBUNTU_VERSION} 4 | 5 | # Set environment variables to avoid interactive installation prompts 6 | ARG DEBIAN_FRONTEND=noninteractive 7 | ARG TZ=UTC 8 | 9 | # Update 10 | RUN apt-get update 11 | 12 | # Install required packages 13 | RUN apt-get install -y --no-install-recommends \ 14 | ca-certificates \ 15 | curl \ 16 | gnupg \ 17 | lsb-release \ 18 | git \ 19 | jq \ 20 | wget \ 21 | unzip \ 22 | openssh-client \ 23 | locales \ 24 | gss-ntlmssp \ 25 | libicu70 \ 26 | libssl3 \ 27 | libc6 \ 28 | libgcc1 \ 29 | libgssapi-krb5-2 \ 30 | liblttng-ust1 \ 31 | libstdc++6 \ 32 | zlib1g 33 | 34 | # Install Python 35 | ARG PYTHON_VERSION=3.11 36 | RUN apt install -y python${PYTHON_VERSION} && \ 37 | ln -sf /usr/bin/python${PYTHON_VERSION} /usr/bin/python3 38 | 39 | # Install pip for Python 3.11 40 | RUN curl -k https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ 41 | python3 get-pip.py && \ 42 | rm get-pip.py 43 | 44 | # Install Ansible 45 | ARG ANSIBLE_VERSION=2.18.3 46 | RUN python3 -m pip install ansible-core==${ANSIBLE_VERSION} 47 | 48 | # Install Terraform 49 | ARG TERRAFORM_VERSION=1.11.2 50 | RUN mkdir /tmp/terraform_env/ && \ 51 | cd /tmp/terraform_env/ && \ 52 | wget https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip && \ 53 | unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip && \ 54 | cp terraform /usr/local/bin/ && \ 55 | rm -rf /tmp/terraform_env/ 56 | 57 | # Install Kubectl 58 | ARG KUBECTL_VERSION=1.32.3 59 | RUN mkdir /tmp/kubectl_env/ && \ 60 | cd /tmp/kubectl_env/ && \ 61 | curl -LO "https://dl.k8s.io/release/v$KUBECTL_VERSION/bin/linux/amd64/kubectl" && \ 62 | chmod +x kubectl && \ 63 | mv ./kubectl /usr/local/bin/kubectl && \ 64 | rm -rf /tmp/kubectl_env/ 65 | 66 | # Install Helm 67 | ARG HELM_VERSION=3.17.2 68 | RUN mkdir /tmp/helm_env/ && \ 69 | cd /tmp/helm_env/ && \ 70 | wget https://get.helm.sh/helm-v${HELM_VERSION}-linux-amd64.tar.gz && \ 71 | tar -xvzf helm-v${HELM_VERSION}-linux-amd64.tar.gz && \ 72 | mv linux-amd64/helm /usr/local/bin/helm && \ 73 | rm -rf /tmp/helm_env/ 74 | 75 | # Install AwsCLI 76 | ARG AWSCLI_VERSION=2.24.24 77 | RUN mkdir /tmp/awscli_env/ && \ 78 | cd /tmp/awscli_env/ && \ 79 | wget "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-${AWSCLI_VERSION}.zip" && \ 80 | unzip awscli-exe-linux-x86_64-${AWSCLI_VERSION}.zip && \ 81 | ./aws/install && \ 82 | rm -rf /tmp/awscli_env/ 83 | 84 | # Install AzureCLI 85 | ARG AZURECLI_VERSION=2.70.0 86 | RUN mkdir -p /etc/apt/keyrings && \ 87 | curl -sLS https://packages.microsoft.com/keys/microsoft.asc | \ 88 | gpg --dearmor | \ 89 | tee /etc/apt/keyrings/microsoft.gpg > /dev/null && \ 90 | chmod go+r /etc/apt/keyrings/microsoft.gpg && \ 91 | AZ_DIST=$(lsb_release -cs) && \ 92 | echo "deb [arch=`dpkg --print-architecture` signed-by=/etc/apt/keyrings/microsoft.gpg] https://packages.microsoft.com/repos/azure-cli/ $AZ_DIST main" | \ 93 | tee /etc/apt/sources.list.d/azure-cli.list && \ 94 | apt-get update && \ 95 | apt-get install --no-install-recommends -y azure-cli=$AZURECLI_VERSION-1~$AZ_DIST 96 | 97 | # PowerShell Installation 98 | ARG PS_VERSION=7.5.0 99 | ARG PS_PACKAGE=powershell_${PS_VERSION}-1.deb_amd64.deb 100 | ARG PS_PACKAGE_URL=https://github.com/PowerShell/PowerShell/releases/download/v${PS_VERSION}/${PS_PACKAGE} 101 | ARG PS_INSTALL_VERSION=7 102 | 103 | RUN curl -sSL ${PS_PACKAGE_URL} -o /tmp/powershell.deb && \ 104 | apt-get install --no-install-recommends -y /tmp/powershell.deb && \ 105 | rm /tmp/powershell.deb 106 | 107 | ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false \ 108 | LC_ALL=en_US.UTF-8 \ 109 | LANG=en_US.UTF-8 \ 110 | PS_INSTALL_FOLDER=/opt/microsoft/powershell/$PS_INSTALL_VERSION \ 111 | PSModuleAnalysisCachePath=/var/cache/microsoft/powershell/PSModuleAnalysisCache/ModuleAnalysisCache \ 112 | POWERSHELL_DISTRIBUTION_CHANNEL=PSDocker-Ubuntu-22.04 113 | 114 | RUN locale-gen $LANG && update-locale && \ 115 | export POWERSHELL_TELEMETRY_OPTOUT=1 && \ 116 | chmod a+x,o-w ${PS_INSTALL_FOLDER}/pwsh && \ 117 | ln -sf ${PS_INSTALL_FOLDER}/pwsh /usr/bin/pwsh && \ 118 | pwsh -NoLogo -NoProfile -Command " \ 119 | \$ErrorActionPreference = 'Stop' ; \ 120 | \$ProgressPreference = 'SilentlyContinue' ; \ 121 | \$maxTries = 0 ; \ 122 | while(!(Test-Path -Path \$env:PSModuleAnalysisCachePath)) { \ 123 | Write-Host 'Waiting for $env:PSModuleAnalysisCachePath' ; \ 124 | Start-Sleep -Seconds 6 ; \ 125 | \$maxTries++ ; \ 126 | if(\$maxTries -gt 20) { \ 127 | Write-Error 'Failed to create $env:PSModuleAnalysisCachePath' ; \ 128 | exit 1 ; \ 129 | } ; \ 130 | }" 131 | 132 | # Cleanup 133 | RUN apt-get clean && \ 134 | rm -rf /var/lib/apt/lists/* 135 | 136 | # Set the working directory 137 | WORKDIR /root 138 | 139 | # Adding tooling samples 140 | COPY samples/ /root/samples/ 141 | RUN chmod +x /root/samples/run_sample.sh 142 | 143 | # Reset environment variables 144 | ENV DEBIAN_FRONTEND teletype 145 | ENV TZ="" 146 | 147 | # Copy the entrypoint script into the container 148 | COPY entrypoint.sh /usr/local/bin/entrypoint.sh 149 | 150 | # Make the entrypoint script executable 151 | RUN chmod +x /usr/local/bin/entrypoint.sh 152 | 153 | # Set the entrypoint to the entrypoint script 154 | ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] 155 | 156 | # Define the default command to run when the container starts 157 | CMD ["/bin/bash"] 158 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | devops-toolkit 3 |

4 | 5 |

DevOps Toolkit

6 | 7 |

🐳 Container image for an all-in-one DevOps environment with popular tools like Ansible, Terraform, kubectl, AWS CLI, Azure CLI, Git, Python and more...

8 | 9 |

10 | last commit 11 | devops-toolkit release 12 | 13 | Docker main 14 | tungbq/devops-toolkit 15 | GitHub Repo stars 16 |

17 | 18 | ## Key Features 19 | 20 | - **Comprehensive Toolset**: Pre-installed with tools like Git, Python, Ansible, Terraform, kubectl, Helm, AWS CLI, Azure CLI, and more. 21 | - **Easy Integration**: Use it directly or customize it with your preferred versions. 22 | - **Efficient Updates**: Weekly updates ensure the latest versions and security patches. 23 | - **Configuration Reusability**: Mounts host config folders for seamless reuse across sessions. 24 | 25 | ## Getting Started 26 | 27 | ### 1. Quick Start 28 | 29 | ```bash 30 | mkdir -p $HOME/.dtc # Skip this step if you already created the configuration folder before 31 | docker pull tungbq/devops-toolkit:latest 32 | docker run -it --rm --name devops-toolkit-demo1 \ 33 | -v $HOME/.dtc:/dtc \ 34 | --network host \ 35 | tungbq/devops-toolkit:latest 36 | ``` 37 | 38 | ### 2. Run with custom tool config from host (.dtc) 39 | Mount current directory and start the toolkit 40 | ```bash 41 | docker run -it --name devops-toolkit-demo2 \ 42 | --volume "$PWD:$PWD" \ 43 | --volume "$HOME/.dtc:/dtc" \ 44 | --volume "$HOME/.ssh:/root/.ssh" \ 45 | --workdir "$PWD" \ 46 | --network host \ 47 | tungbq/devops-toolkit:latest 48 | 49 | # Adjust the docker run command base on your use cases 50 | ``` 51 | 52 | ### 3. Run with tool config from host 53 | 54 | ```bash 55 | docker run -it --name devops-toolkit-demo3 \ 56 | --volume "$HOME/.aws:/root/.aws" \ 57 | --volume "$HOME/.azure:/root/.azure" \ 58 | --volume "$HOME/.kube:/root/.kube" \ 59 | --volume "$HOME/.terraform.d:/root/.terraform.d" \ 60 | --volume "$HOME/.config/helm:/root/.config/helm" \ 61 | --volume "$HOME/.ansible:/root/.ansible" \ 62 | --volume "$HOME/.gitconfig:/root/.gitconfig" \ 63 | --volume "$HOME/.ssh:/root/.ssh" \ 64 | --volume "$PWD:$PWD" \ 65 | --workdir "$PWD" \ 66 | --network host \ 67 | tungbq/devops-toolkit:latest 68 | 69 | # Adjust the docker run command base on your use cases 70 | ``` 71 | 72 | ### 4. Note 73 | 74 | - `.dtc` stands for **D**evOps **T**oolkit **C**onfiguration 75 | - You can replace `$HOME/.dtc` with any desired folder path on your VM. 76 | - Remove the `-v $HOME/.dtc:/dtc` option if you do not wish to store configurations on the host (not recommended for configuration reuse). 77 | 78 | ## Versioning 79 | 80 | We use the following versioning scheme: 81 | 82 | - **Repository Tags**: `vX.Y.Z` (e.g., `v1.2.3`) 83 | - **Docker Tags**: `X.Y.Z` or `latest` for the most recent version. 84 | 85 | You can pull specific versions from Docker Hub using: 86 | 87 | ```bash 88 | docker pull tungbq/devops-toolkit:1.2.3 89 | docker pull tungbq/devops-toolkit:latest 90 | ``` 91 | 92 | For more details on versioning, check the [**release notes**](https://github.com/tungbq/devops-toolkit/releases). 93 | 94 | ## User Guide 📖 95 | 96 | Explore the comprehensive guide below to gain insight into the detailed utilization of every tool within the toolkit. 97 | 98 | - For detailed instructions on using specific tools, refer to: [**DevOps toolkit specific tool user guide**](./docs/usage/README.md) 99 | - For instructions on common run modes, visit [**DevOps toolkit common run mode**](./docs/usage/run_mode.md) 100 | 101 | ## Demo 📺 102 | 103 | - Checkout the Demo code and instruction [here](./demo/). 104 | 105 | ## The DevOps Toolkit Core 🧰 106 | 107 | Built on `ubuntu:22.04` base image 108 | 109 | | Name | Version | Release | Usage | 110 | | :--------- | :---------------------- | :--------------------------------------------------------------------------- | :------------------------------------------------- | 111 | | Python | PYTHON_VERSION=3.11 | [Check](https://www.python.org/downloads/source/) | [python_usage](./docs/usage/python_usage.md) | 112 | | Ansible | ANSIBLE_VERSION=2.18.3 | [Check](https://api.github.com/repos/ansible/ansible/releases/latest) | [ansible_usage](./docs/usage/ansible_usage.md) | 113 | | Terraform | TERRAFORM_VERSION=1.11.2 | [Check](https://releases.hashicorp.com/terraform/) | [terraform_usage](./docs/usage/terraform_usage.md) | 114 | | Kubectl | KUBECTL_VERSION=1.32.3 | [Check](https://dl.k8s.io/release/stable.txt) | [kubectl_usage](./docs/usage/kubectl_usage.md) | 115 | | Helm | HELM_VERSION=3.17.2 | [Check](https://github.com/helm/helm/releases) | [helm_usage](./docs/usage/helm_usage.md) | 116 | | AwsCLI | AWSCLI_VERSION=2.24.24 | [Check](https://raw.githubusercontent.com/aws/aws-cli/v2/CHANGELOG.rst) | [awscli_usage](./docs/usage/awscli_usage.md) | 117 | | AzureCLI | AZURECLI_VERSION=2.70.0 | [Check](https://learn.microsoft.com/en-us/cli/azure/release-notes-azure-cli) | [azurecli_usage](./docs/usage/azurecli_usage.md) | 118 | | PowerShell | PS_VERSION=7.5.0 | [Check](https://github.com/PowerShell/PowerShell/releases) | TODO | 119 | 120 | And more tools to be implemented... 121 | 122 | ## Contributing 123 | 124 | - See: [CONTRIBUTING.md](./CONTRIBUTING.md) 125 | - Looking for the issue to work on? Check the list of our open issues [**good first issue**](https://github.com/tungbq/devops-toolkit/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) 126 | - Feel free to open a new issue if you encounter the toolkit bug or want to request more content about DevOps toolkit 127 | - Submit a [new issue](https://github.com/tungbq/devops-toolkit/issues/new) (🐛) if you encounter the bug/error when using this toolkit 128 | 129 | ## Hit the Star! ⭐ 130 | 131 | - If you find this repository helpful, kindly consider showing your appreciation by giving it a star ⭐ Thanks! 💖 132 | -------------------------------------------------------------------------------- /assets/images/devops-toolkit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tungbq/devops-toolkit/bc941d11085966782186fdcd8871cad0570d2845/assets/images/devops-toolkit.jpg -------------------------------------------------------------------------------- /demo/README.md: -------------------------------------------------------------------------------- 1 | # DevOps Toolkit demo 📺 2 | 3 | ## Quick demo 4 | 5 | ```bash 6 | docker run --network host --rm -v ~/.dtc:/dtc tungbq/devops-toolkit:latest samples/run_sample.sh 7 | ``` 8 | 9 | ## Demo Table 10 | 11 | Keeps track of all demo resources 12 | 13 | | Tool | Demo link | Status | 14 | | :-------: | --------------------------------------------- | :------ | 15 | | Terraform | [provistion-azure-vm](./provistion-azure-vm/) | ✔️ Done | 16 | -------------------------------------------------------------------------------- /demo/provistion-azure-vm/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/azure/azapi" { 5 | version = "1.15.0" 6 | constraints = "~> 1.5" 7 | hashes = [ 8 | "h1:Y7ruMuPh8UJRTRl4rm+cdpGtmURx2taqiuqfYaH3o48=", 9 | "zh:0627a8bc77254debc25dc0c7b62e055138217c97b03221e593c3c56dc7550671", 10 | "zh:2fe045f07070ef75d0bec4b0595a74c14394daa838ddb964e2fd23cc98c40c34", 11 | "zh:343009f39c957883b2c06145a5954e524c70f93585f943f1ea3d28ef6995d0d0", 12 | "zh:53fe9ab54485aaebc9b91e27a10bce2729a1c95b1399079e631dc6bb9e3f27dc", 13 | "zh:63c407e7dc04d178d4798c17ad489d9cc92f7d1941d7f4a3f560b95908b6107b", 14 | "zh:7d6fc2b432b264f036bb80ab2b2ba67f80a5d98da8a8c322aa097833dad598c9", 15 | "zh:7ec49c0a8799d469eb6e2a1f856693f9862f1b73f5ed70adc1b346e5a4c6458d", 16 | "zh:889704f10319d301d677539d788fc82a7c73608ab78cb93e1280ac2be39e6e00", 17 | "zh:90b4b07405b7cde9ebae3b034cb5bb5dd18484d1b95bd250f905451f1e86ac3f", 18 | "zh:92aa9c241a8cb2a6d81ad47bc007c119f8b818464a960ebaf39008766c361e6b", 19 | "zh:f28fbd0a2c59e239b53067bc1adc691be444876bcb2d4f78d310f549724da6e0", 20 | "zh:ffb15e0ddfa505d0e9b75341570199076ae574887124f398162b1ead9376b25f", 21 | ] 22 | } 23 | 24 | provider "registry.terraform.io/hashicorp/azurerm" { 25 | version = "2.99.0" 26 | constraints = "~> 2.0" 27 | hashes = [ 28 | "h1:FXBB5TkvZpZA+ZRtofPvp5IHZpz4Atw7w9J8GDgMhvk=", 29 | "zh:08d81e72e97351538ab4d15548942217bf0c4d3b79ad3f4c95d8f07f902d2fa6", 30 | "zh:11fdfa4f42d6b6f01371f336fea56f28a1db9e7b490c5ca0b352f6bbca5a27f1", 31 | "zh:12376e2c4b56b76098d5d713d1a4e07e748a926c4d165f0bd6f52157b1f7a7e9", 32 | "zh:31f1cb5b88ed1307625050e3ee7dd9948773f522a3f3bf179195d607de843ea3", 33 | "zh:767971161405d38412662a73ea40a422125cdc214c72fbc569bcfbea6e66c366", 34 | "zh:973c402c3728b68c980ea537319b703c009b902a981b0067fbc64e04a90e434c", 35 | "zh:9ec62a4f82ec1e92bceeff80dd8783f61de0a94665c133f7c7a7a68bda9cdbd6", 36 | "zh:bbb3b7e1229c531c4634338e4fc81b28bce58312eb843a931a4420abe42d5b7e", 37 | "zh:cbbe02cd410d21476b3a081b5fa74b4f1b3d9d79b00214009028d60e859c19a3", 38 | "zh:cc00ecc7617a55543b60a0da1196ea92df48c399bcadbedf04c783e3d47c6e08", 39 | "zh:eecb9fd0e7509c7fd4763e546ef0933f125770cbab2b46152416e23d5ec9dd53", 40 | ] 41 | } 42 | 43 | provider "registry.terraform.io/hashicorp/random" { 44 | version = "3.6.2" 45 | constraints = "~> 3.0" 46 | hashes = [ 47 | "h1:wmG0QFjQ2OfyPy6BB7mQ57WtoZZGGV07uAPQeDmIrAE=", 48 | "zh:0ef01a4f81147b32c1bea3429974d4d104bbc4be2ba3cfa667031a8183ef88ec", 49 | "zh:1bcd2d8161e89e39886119965ef0f37fcce2da9c1aca34263dd3002ba05fcb53", 50 | "zh:37c75d15e9514556a5f4ed02e1548aaa95c0ecd6ff9af1119ac905144c70c114", 51 | "zh:4210550a767226976bc7e57d988b9ce48f4411fa8a60cd74a6b246baf7589dad", 52 | "zh:562007382520cd4baa7320f35e1370ffe84e46ed4e2071fdc7e4b1a9b1f8ae9b", 53 | "zh:5efb9da90f665e43f22c2e13e0ce48e86cae2d960aaf1abf721b497f32025916", 54 | "zh:6f71257a6b1218d02a573fc9bff0657410404fb2ef23bc66ae8cd968f98d5ff6", 55 | "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", 56 | "zh:9647e18f221380a85f2f0ab387c68fdafd58af6193a932417299cdcae4710150", 57 | "zh:bb6297ce412c3c2fa9fec726114e5e0508dd2638cad6a0cb433194930c97a544", 58 | "zh:f83e925ed73ff8a5ef6e3608ad9225baa5376446349572c2449c0c0b3cf184b7", 59 | "zh:fbef0781cb64de76b1df1ca11078aecba7800d82fd4a956302734999cfd9a4af", 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /demo/provistion-azure-vm/README.md: -------------------------------------------------------------------------------- 1 | # DEMO: Provision Azure VM with DevOps toolkit 2 | 3 | ## Navigate to Terraform demo code 4 | 5 | ```bash 6 | cd devops-toolkit/demo/provistion-azure-vm 7 | 8 | mkdir -p $HOME/.dtc # Skip this step if you already created the configuration folder before 9 | docker pull tungbq/devops-toolkit:latest 10 | docker run -it --rm --name demo_azure_tf \ 11 | -v $HOME/.dtc:/dtc \ 12 | --network host \ 13 | tungbq/devops-toolkit:latest 14 | ``` 15 | 16 | At this point, your container already started with `demo/provistion-azure-vm` code available inside. Let's move to the next step 17 | 18 | ## Login to Azure 19 | 20 | ```bash 21 | # In devops-toolkit contaienr env 22 | az account show 23 | az login --use-device-code 24 | # Follow the cmd output to login 25 | ``` 26 | 27 | ## Initialize Terraform 28 | 29 | ```bash 30 | # In devops-toolkit contaienr env 31 | terraform init 32 | ``` 33 | 34 | ## Plan Terraform 35 | 36 | ```bash 37 | # In devops-toolkit contaienr env 38 | terraform plan 39 | ``` 40 | 41 | ## Apply Terraform 42 | 43 | ```bash 44 | # In devops-toolkit contaienr env 45 | terraform apply 46 | ``` 47 | 48 | Enter 'yes' to confirm 49 | 50 | ## Verify 51 | 52 | - Now you can go to Azure Portal to verify your VM: https://portal.azure.com/#home 53 | - Or ping the Public IP shown in the console 54 | 55 | ## Cleanup 56 | 57 | Destroy the resources with terraform if they are not used anymore: 58 | 59 | ```bash 60 | # In devops-toolkit contaienr env 61 | terraform destroy 62 | ``` 63 | 64 | ## Conclusion 65 | 66 | You can see that in just a few steps, you can use Terraform to provision the Azure VM without install terraform on the host machine! 67 | -------------------------------------------------------------------------------- /demo/provistion-azure-vm/main.tf: -------------------------------------------------------------------------------- 1 | resource "random_pet" "rg_name" { 2 | prefix = var.resource_group_name_prefix 3 | } 4 | 5 | resource "azurerm_resource_group" "rg" { 6 | location = var.resource_group_location 7 | name = random_pet.rg_name.id 8 | } 9 | 10 | # Create virtual network 11 | resource "azurerm_virtual_network" "my_terraform_network" { 12 | name = "myVnet" 13 | address_space = ["10.0.0.0/16"] 14 | location = azurerm_resource_group.rg.location 15 | resource_group_name = azurerm_resource_group.rg.name 16 | } 17 | 18 | # Create subnet 19 | resource "azurerm_subnet" "my_terraform_subnet" { 20 | name = "mySubnet" 21 | resource_group_name = azurerm_resource_group.rg.name 22 | virtual_network_name = azurerm_virtual_network.my_terraform_network.name 23 | address_prefixes = ["10.0.1.0/24"] 24 | } 25 | 26 | # Create public IPs 27 | resource "azurerm_public_ip" "my_terraform_public_ip" { 28 | name = "myPublicIP" 29 | location = azurerm_resource_group.rg.location 30 | resource_group_name = azurerm_resource_group.rg.name 31 | allocation_method = "Dynamic" 32 | } 33 | 34 | # Create Network Security Group and rule 35 | resource "azurerm_network_security_group" "my_terraform_nsg" { 36 | name = "myNetworkSecurityGroup" 37 | location = azurerm_resource_group.rg.location 38 | resource_group_name = azurerm_resource_group.rg.name 39 | 40 | security_rule { 41 | name = "SSH" 42 | priority = 1001 43 | direction = "Inbound" 44 | access = "Allow" 45 | protocol = "Tcp" 46 | source_port_range = "*" 47 | destination_port_range = "22" 48 | source_address_prefix = "*" 49 | destination_address_prefix = "*" 50 | } 51 | } 52 | 53 | # Create network interface 54 | resource "azurerm_network_interface" "my_terraform_nic" { 55 | name = "myNIC" 56 | location = azurerm_resource_group.rg.location 57 | resource_group_name = azurerm_resource_group.rg.name 58 | 59 | ip_configuration { 60 | name = "my_nic_configuration" 61 | subnet_id = azurerm_subnet.my_terraform_subnet.id 62 | private_ip_address_allocation = "Dynamic" 63 | public_ip_address_id = azurerm_public_ip.my_terraform_public_ip.id 64 | } 65 | } 66 | 67 | # Connect the security group to the network interface 68 | resource "azurerm_network_interface_security_group_association" "example" { 69 | network_interface_id = azurerm_network_interface.my_terraform_nic.id 70 | network_security_group_id = azurerm_network_security_group.my_terraform_nsg.id 71 | } 72 | 73 | # Generate random text for a unique storage account name 74 | resource "random_id" "random_id" { 75 | keepers = { 76 | # Generate a new ID only when a new resource group is defined 77 | resource_group = azurerm_resource_group.rg.name 78 | } 79 | 80 | byte_length = 8 81 | } 82 | 83 | # Create storage account for boot diagnostics 84 | resource "azurerm_storage_account" "my_storage_account" { 85 | name = "diag${random_id.random_id.hex}" 86 | location = azurerm_resource_group.rg.location 87 | resource_group_name = azurerm_resource_group.rg.name 88 | account_tier = "Standard" 89 | account_replication_type = "LRS" 90 | } 91 | 92 | # Create virtual machine 93 | resource "azurerm_linux_virtual_machine" "my_terraform_vm" { 94 | name = "myVM" 95 | location = azurerm_resource_group.rg.location 96 | resource_group_name = azurerm_resource_group.rg.name 97 | network_interface_ids = [azurerm_network_interface.my_terraform_nic.id] 98 | size = "Standard_DS1_v2" 99 | 100 | os_disk { 101 | name = "myOsDisk" 102 | caching = "ReadWrite" 103 | storage_account_type = "Premium_LRS" 104 | } 105 | 106 | source_image_reference { 107 | publisher = "Canonical" 108 | offer = "0001-com-ubuntu-server-jammy" 109 | sku = "22_04-lts-gen2" 110 | version = "latest" 111 | } 112 | 113 | computer_name = "hostname" 114 | admin_username = var.username 115 | 116 | admin_ssh_key { 117 | username = var.username 118 | public_key = azapi_resource_action.ssh_public_key_gen.output.publicKey 119 | } 120 | 121 | boot_diagnostics { 122 | storage_account_uri = azurerm_storage_account.my_storage_account.primary_blob_endpoint 123 | } 124 | } -------------------------------------------------------------------------------- /demo/provistion-azure-vm/output.tf: -------------------------------------------------------------------------------- 1 | output "resource_group_name" { 2 | value = azurerm_resource_group.rg.name 3 | } 4 | 5 | output "public_ip_address" { 6 | value = azurerm_linux_virtual_machine.my_terraform_vm.public_ip_address 7 | } 8 | -------------------------------------------------------------------------------- /demo/provistion-azure-vm/providers.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">=0.12" 3 | 4 | required_providers { 5 | azapi = { 6 | source = "azure/azapi" 7 | version = "~>1.5" 8 | } 9 | azurerm = { 10 | source = "hashicorp/azurerm" 11 | version = "~>2.0" 12 | } 13 | random = { 14 | source = "hashicorp/random" 15 | version = "~>3.0" 16 | } 17 | } 18 | } 19 | 20 | provider "azurerm" { 21 | features {} 22 | } -------------------------------------------------------------------------------- /demo/provistion-azure-vm/ssh.tf: -------------------------------------------------------------------------------- 1 | resource "random_pet" "ssh_key_name" { 2 | prefix = "ssh" 3 | separator = "" 4 | } 5 | 6 | resource "azapi_resource_action" "ssh_public_key_gen" { 7 | type = "Microsoft.Compute/sshPublicKeys@2022-11-01" 8 | resource_id = azapi_resource.ssh_public_key.id 9 | action = "generateKeyPair" 10 | method = "POST" 11 | 12 | response_export_values = ["publicKey", "privateKey"] 13 | } 14 | 15 | resource "azapi_resource" "ssh_public_key" { 16 | type = "Microsoft.Compute/sshPublicKeys@2022-11-01" 17 | name = random_pet.ssh_key_name.id 18 | location = azurerm_resource_group.rg.location 19 | parent_id = azurerm_resource_group.rg.id 20 | } 21 | 22 | output "key_data" { 23 | value = azapi_resource_action.ssh_public_key_gen.output.publicKey 24 | } 25 | -------------------------------------------------------------------------------- /demo/provistion-azure-vm/variables.tf: -------------------------------------------------------------------------------- 1 | variable "resource_group_location" { 2 | type = string 3 | default = "eastus" 4 | description = "Location of the resource group." 5 | } 6 | 7 | variable "resource_group_name_prefix" { 8 | type = string 9 | default = "rg" 10 | description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription." 11 | } 12 | 13 | variable "username" { 14 | type = string 15 | description = "The username for the local account that will be created on the new VM." 16 | default = "azureadmin" 17 | } 18 | -------------------------------------------------------------------------------- /docs/build/build_toolkit_image.md: -------------------------------------------------------------------------------- 1 | # Build your own devops-toolkit image 2 | 3 | **NOTE:** If you'd refer using the official prebuilt docker image from DockerHub, you can skip this section! 4 | Jump to [Use Docker Hub image](https://github.com/tungbq/devops-toolkit?tab=readme-ov-file#use-the-official-image-from-docker-hub) for instead. 5 | 6 | **1. Clone the Repository:** 7 | 8 | ```bash 9 | git clone https://github.com/tungbq/devops-toolkit.git 10 | ``` 11 | 12 | **2. Navigate to the Repository:** 13 | 14 | ```bash 15 | cd devops-toolkit 16 | ``` 17 | 18 | **3. Build the DevOps toolkit image:** 19 | 20 | - Build with the default versions 21 | 22 | ```bash 23 | docker build -t devops-toolkit:latest . 24 | ``` 25 | 26 | - Build with single custom version 27 | 28 | ```bash 29 | docker build \ 30 | --build-arg TERRAFORM_VERSION=1.7.0 \ 31 | -t devops-toolkit:custom . 32 | ``` 33 | 34 | - Build with multiple custom versions 35 | 36 | ```bash 37 | docker build \ 38 | --build-arg UBUNTU_VERSION=22.04 \ 39 | --build-arg PYTHON_VERSION=3.10 \ 40 | --build-arg ANSIBLE_VERSION=2.16.3 \ 41 | --build-arg TERRAFORM_VERSION=1.7.0 \ 42 | --build-arg KUBECTL_VERSION=1.29.2 \ 43 | --build-arg HELM_VERSION=3.14.2 \ 44 | --build-arg AWSCLI_VERSION=2.15.24 \ 45 | -t devops-toolkit:custom . 46 | ``` 47 | 48 | **4. Test the toolkit image:** 49 | 50 | - Run below command to verify newly created image 51 | 52 | ```bash 53 | cd scripts 54 | chmod +x check_version_in_toolkit.sh 55 | ./check_version_in_toolkit.sh devops-toolkit:latest ./toolkit_info.json 56 | ``` 57 | -------------------------------------------------------------------------------- /docs/others/README.md: -------------------------------------------------------------------------------- 1 | # Others 2 | 3 | - Install source: https://ppa-stats.sheth.io/#/?ppaName=ppa&ppaOwner=deadsnakes&packageName=python3.9 4 | -------------------------------------------------------------------------------- /docs/troubleshooting/TROUBLESHOOTING.md: -------------------------------------------------------------------------------- 1 | # Most common error 2 | 3 | #### docker-on-wsl2-very-slow 4 | 5 | - 6 | 7 | #### exec /usr/local/bin/kubectl: exec format error 8 | 9 | - See: 10 | Check architecure: dpkg --print-architecture 11 | 12 | #### docker: Error response from daemon: Conflict. The container name "/my_devops_toolkit" is already in use by container 13 | 14 | - Fix by using anotehr name or delete the current container 15 | -------------------------------------------------------------------------------- /docs/usage/README.md: -------------------------------------------------------------------------------- 1 | # The devops-toolkit usage 2 | 3 | This guide us how to use the `devops-toolkit` with serveral usecases 4 | 5 | ## Python 6 | 7 | - Check [**python_usage**](./python_usage.md) 8 | 9 | ## Ansible 10 | 11 | - Check [**ansible_usage**](./ansible_usage.md) 12 | 13 | ## Terraform 14 | 15 | - Check [**terraform_usage**](./terraform_usage.md) 16 | 17 | ## Kubectl 18 | 19 | - Check [**kubectl_usage**](./kubectl_usage.md) 20 | 21 | ## Helm 22 | 23 | - Check [**helm_usage**](./helm_usage.md) 24 | 25 | ## AwsCLI 26 | 27 | - Check [**awscli_usage**](./awscli_usage.md) 28 | 29 | ## AzureCLI 30 | 31 | - Check [**azurecli_usage**](./azurecli_usage.md) 32 | 33 | ## Troubleshooting 34 | 35 | - For any issues, check [this document](../troubleshooting/TROUBLESHOOTING.md) 36 | -------------------------------------------------------------------------------- /docs/usage/ansible_usage.md: -------------------------------------------------------------------------------- 1 | # Use ansible in the devops-toolkit 2 | 3 | ## Ansible document 4 | 5 | Some document to help you start with ansible 6 | 7 | - 8 | - 9 | 10 | ## Run with Docker command 11 | 12 | ### Note 13 | 14 | To use the existing container instead of creating one, use `docker exec` command instead of `docker run` 15 | 16 | ```bash 17 | docker exec -it my_devops_toolkit /bin/bash 18 | ``` 19 | 20 | ### Common Run Modes 21 | 22 | For instructions on common run modes, visit [**DevOps Toolkit Common Run Mode**](../usage/run_mode.md). 23 | 24 | ### Use case 1: Run Ansible sample code provided in the container 25 | 26 | ```bash 27 | docker run --rm --network host -v ~/.dtc:/dtc -it tungbq/devops-toolkit:latest 28 | 29 | # You now in the container terminal 30 | ansible-playbook samples/ansible/check_os.yml 31 | ``` 32 | 33 | ### Use case 2: Clone external code inside container 34 | 35 | ```bash 36 | docker run --rm --network host -v ~/.dtc:/dtc -it tungbq/devops-toolkit:latest 37 | # You now in the container terminal 38 | 39 | # Now run your cloned script 40 | # Clone code 41 | mkdir ansible_workspace; cd ansible_workspace 42 | git clone https://github.com/ansible/ansible-examples.git 43 | 44 | cd ansible-examples 45 | ansible-playbook 46 | ``` 47 | 48 | ### Use case 3: Mount external code to container 49 | 50 | Clone the code to the host then mount to container 51 | 52 | ```bash 53 | # Given that we have code somewhere in you machine 54 | docker run --rm -v "$(pwd)":/root/ansible_workspace --network host -v ~/.dtc:/dtc -it tungbq/devops-toolkit:latest 55 | # Run the ansible code as usual 56 | ``` 57 | 58 | ### Use case 4: Mount external code to container and use .ssh keys from the host 59 | 60 | Clone the code to the host then mount code and `.ssh` folder to container 61 | 62 | ```bash 63 | # Given that we have code somewhere in you machine 64 | docker run --rm -v ~/.ssh:/root/.ssh -v "$(pwd)":/root/ansible_workspace --network host -v ~/.dtc:/dtc -it tungbq/devops-toolkit:latest 65 | # Run the ansible code as usual 66 | ``` 67 | 68 | ### Troubleshooting 69 | 70 | - For any issues, check [this reference](../troubleshooting/TROUBLESHOOTING.md) 71 | -------------------------------------------------------------------------------- /docs/usage/awscli_usage.md: -------------------------------------------------------------------------------- 1 | # Use awscli in the devops-toolkit 2 | 3 | ## Prerequisite 4 | 5 | An AWS account 6 | 7 | ## awscli document 8 | 9 | Some document to help you start with awscli 10 | 11 | - 12 | - 13 | 14 | ## Run with Docker command 15 | 16 | ### Note 17 | 18 | To use the existing container instead of creating one, use `docker exec` command instead of `docker run` 19 | 20 | ```bash 21 | docker exec -it my_devops_toolkit /bin/bash 22 | ``` 23 | 24 | ### Common Run Modes 25 | 26 | For instructions on common run modes, visit [**DevOps Toolkit Common Run Mode**](../usage/run_mode.md). 27 | 28 | ### Use case 1: Configure credentials and list S3 bucket with awscli 29 | 30 | ```bash 31 | docker run --rm --network host -it -v ~/.dtc:/dtc tungbq/devops-toolkit:latest 32 | ############################################### 33 | # Now we are in the docker container terminal # 34 | ############################################### 35 | # Configure credentials 36 | aws configure 37 | # List S3 buckets 38 | aws s3 ls 39 | ``` 40 | 41 | Sample Result 42 | 43 | ```bash 44 | root@docker-desktop:~# aws configure 45 | AWS Access Key ID [None]: xxxxxxxx 46 | AWS Secret Access Key [None]: xxxxxxxx 47 | Default region name [None]: xxxxxxxx 48 | Default output format [None]: xxxxxxxx 49 | ``` 50 | 51 | ### Troubleshooting 52 | 53 | - For any issues, check [this reference](../troubleshooting/TROUBLESHOOTING.md) 54 | -------------------------------------------------------------------------------- /docs/usage/azurecli_usage.md: -------------------------------------------------------------------------------- 1 | # Use azurecli in the devops-toolkit 2 | 3 | ## Prerequisite 4 | 5 | An Azure account 6 | 7 | ## azurecli document 8 | 9 | Some document to help you start with azurecli 10 | 11 | - 12 | 13 | ## Run with Docker command 14 | 15 | ### Note 16 | 17 | To use the existing container instead of creating one, use `docker exec` command instead of `docker run` 18 | 19 | ```bash 20 | docker exec -it my_devops_toolkit /bin/bash 21 | ``` 22 | 23 | ### Common Run Modes 24 | 25 | For instructions on common run modes, visit [**DevOps Toolkit Common Run Mode**](../usage/run_mode.md). 26 | 27 | ### Use case 1: Az login and run command 28 | 29 | ```bash 30 | docker run --rm -it -v ~/.dtc:/dtc tungbq/devops-toolkit:latest 31 | 32 | # Login with AZ CLI 33 | az login --use-device-code 34 | ### To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code to authenticate 35 | 36 | # List all resource groups 37 | az group list 38 | ``` 39 | 40 | Sample Result 41 | 42 | ```bash 43 | root@f097467db632:~# az group list 44 | [ 45 | { 46 | "id": "/subscriptions/xxxxxxxx-yyyy-zzzz-ttttttttt/resourceGroups/your_resource_group", 47 | "location": "centralindia", 48 | "managedBy": null, 49 | "name": "your_resource_group", 50 | "properties": { 51 | "provisioningState": "Succeeded" 52 | }, 53 | "tags": null, 54 | "type": "Microsoft.Resources/resourceGroups" 55 | }, 56 | ... 57 | ] 58 | ``` 59 | 60 | ### Troubleshooting 61 | 62 | - For any issues, check [this reference](../troubleshooting/TROUBLESHOOTING.md) 63 | -------------------------------------------------------------------------------- /docs/usage/helm_usage.md: -------------------------------------------------------------------------------- 1 | # Use helm in the devops-toolkit 2 | 3 | ## Prerequisite 4 | 5 | Familiar with the [kubectl_usage](./kubectl_usage.md) first so we can have the correct k8s integration 6 | 7 | ## Helm document 8 | 9 | Some document to help you start with helm 10 | 11 | - 12 | - 13 | 14 | ## Run with Docker command 15 | 16 | ### Note 17 | 18 | To use the existing container instead of creating one, use `docker exec` command instead of `docker run` 19 | 20 | ```bash 21 | docker exec -it my_devops_toolkit /bin/bash 22 | ``` 23 | 24 | ### Common Run Modes 25 | 26 | For instructions on common run modes, visit [**DevOps Toolkit Common Run Mode**](../usage/run_mode.md). 27 | 28 | ### Use case 1: Deploy an application with Helm 29 | 30 | ```bash 31 | docker run --rm --network host -it -v ~/.dtc:/dtc tungbq/devops-toolkit:latest 32 | ############################################### 33 | # Now we are in the docker container terminal # 34 | ############################################### 35 | # Command to check k8s node 36 | kubectl get nodes 37 | # Deploy with Helm 38 | helm repo add bitnami https://charts.bitnami.com/bitnami 39 | # Make sure we get the latest list of charts 40 | helm repo update 41 | helm install bitnami/mysql --generate-name 42 | ``` 43 | 44 | Sample Result 45 | 46 | ```bash 47 | Update Complete. ⎈Happy Helming!⎈ 48 | root@docker-desktop:~# helm install bitnami/mysql --generate-name 49 | WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config 50 | WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config 51 | NAME: mysql-1710654490 52 | LAST DEPLOYED: Sun Mar 17 05:48:12 2024 53 | NAMESPACE: default 54 | STATUS: deployed 55 | REVISION: 1 56 | TEST SUITE: None 57 | NOTES: 58 | CHART NAME: mysql 59 | CHART VERSION: 9.23.0 60 | APP VERSION: 8.0.36 61 | ``` 62 | 63 | ### Troubleshooting 64 | 65 | - For any issues, check [this reference](../troubleshooting/TROUBLESHOOTING.md) 66 | -------------------------------------------------------------------------------- /docs/usage/kubectl_usage.md: -------------------------------------------------------------------------------- 1 | # Use kubectl in the devops-toolkit 2 | 3 | ## Kubernetes document 4 | 5 | Some document to help you start with kubernetes (k8s) 6 | 7 | - 8 | - 9 | 10 | ## Run with Docker command 11 | 12 | ### Note 13 | 14 | To use the existing container instead of creating one, use `docker exec` command instead of `docker run` 15 | 16 | ```bash 17 | docker exec -it my_devops_toolkit /bin/bash 18 | ``` 19 | 20 | ### Common Run Modes 21 | 22 | For instructions on common run modes, visit [**DevOps Toolkit Common Run Mode**](../usage/run_mode.md). 23 | 24 | ### Use case 1: Use kube config from the host 25 | 26 | Mount the `.kube/config` file from the host to container 27 | 28 | ```bash 29 | docker run --rm --network host -it -v ~/.dtc:/dtc tungbq/devops-toolkit:latest 30 | ############################################### 31 | # Now we are in the docker container terminal # 32 | ############################################### 33 | # Command to check k8s node 34 | kubectl get nodes 35 | # Deploy application 36 | kubectl apply -f https://k8s.io/examples/application/deployment.yaml 37 | # View the pod 38 | kubectl get pods -w 39 | # View the deployment 40 | kubectl get deployment 41 | # More command as per your need... 42 | ``` 43 | 44 | Sample Result 45 | 46 | ```bash 47 | root@docker-desktop:~# kubectl get nodes 48 | NAME STATUS ROLES AGE VERSION 49 | kind-control-plane Ready control-plane 21m v1.29.2 50 | root@docker-desktop:~# kubectl apply -f https://k8s.io/examples/application/deployment.yaml 51 | deployment.apps/nginx-deployment unchanged 52 | root@docker-desktop:~# kubectl get pods -w 53 | NAME READY STATUS RESTARTS AGE 54 | nginx-deployment-86dcfdf4c6-c2cfp 1/1 Running 0 99s 55 | nginx-deployment-86dcfdf4c6-w4vp7 1/1 Running 0 99s 56 | root@docker-desktop:~# kubectl get deployment 57 | NAME READY UP-TO-DATE AVAILABLE AGE 58 | nginx-deployment 2/2 2 2 115s 59 | ``` 60 | 61 | ### Troubleshooting 62 | 63 | - For any issues, check [this reference](../troubleshooting/TROUBLESHOOTING.md) 64 | -------------------------------------------------------------------------------- /docs/usage/python_usage.md: -------------------------------------------------------------------------------- 1 | # Use python in the devops-toolkit 2 | 3 | ## Python document 4 | 5 | Some document to help you start with python 6 | 7 | - 8 | - 9 | 10 | ## Run with Docker command 11 | 12 | ### Note 13 | 14 | To use the existing container instead of creating one, use `docker exec` command instead of `docker run` 15 | 16 | ```bash 17 | # Given that we have 'my_devops_toolkit' start before 18 | docker exec -it my_devops_toolkit /bin/bash 19 | ``` 20 | 21 | ### Common Run Modes 22 | 23 | For instructions on common run modes, visit [**DevOps Toolkit Common Run Mode**](../usage/run_mode.md). 24 | 25 | ### Use case 1: Run python sample code provided in the container 26 | 27 | ```bash 28 | docker run --rm --network host -it -v ~/.dtc:/dtc tungbq/devops-toolkit:latest 29 | # You now in the container terminal 30 | python3 samples/python/rectangle_area_calculator.py 31 | ``` 32 | 33 | ### Use case 2: Clone external code inside container 34 | 35 | ```bash 36 | docker run --rm --network host -it -v ~/.dtc:/dtc tungbq/devops-toolkit:latest 37 | # You now in the container terminal 38 | # Clone code 39 | mkdir python_workspace 40 | cd python_workspace 41 | 42 | # Clone code 43 | mkdir python_workspace; cd python_workspace 44 | git clone https://github.com/geekcomputers/Python.git 45 | 46 | # Now run your cloned script 47 | cd Python 48 | python3 Day_of_week.py 49 | ``` 50 | 51 | ### Use case 3: Mount external code to container 52 | 53 | Clone the code to the host then mount to container 54 | 55 | ```bash 56 | # Given that we have code somewhere in you machine 57 | docker run --rm -v "$(pwd)":/root/python_workspace --network host -it -v ~/.dtc:/dtc tungbq/devops-toolkit:latest 58 | # Run the python code as usual 59 | ``` 60 | 61 | ### Troubleshooting 62 | 63 | - For any issues, check [this reference](../troubleshooting/TROUBLESHOOTING.md) 64 | -------------------------------------------------------------------------------- /docs/usage/run_mode.md: -------------------------------------------------------------------------------- 1 | # DevOps toolkit run mode 2 | 3 | The DevOps Toolkit image can be run in various modes. See [docker/container/run](https://docs.docker.com/reference/cli/docker/container/run/) for more information. Check the document below for further details. 4 | 5 | ## Run option 6 | 7 | Command: `docker run tungbq/devops-toolkit:`, some of the common options can be used in any combination: 8 | 9 | - `-it`: Interactive mode. 10 | - `--rm`: Remove the container after it completes (Ctrl + C or container exit event). 11 | - `--network host`: Use the host (VM) network. 12 | - `--name `: Assign a name to the container (e.g: `--name demo001`). 13 | - `-v :/config`: Mount a config folder on the host to the container. This allows reusing configurations in the container, like AWS and Azure login sessions (e.g: `-v ~/.dtc:/dtc`, `-v /tmp/devops-toolkit-config-01:/config`). 14 | 15 | ## Example 16 | 17 | - Run the image in interactive mode: 18 | 19 | ```bash 20 | docker run -it --rm tungbq/devops-toolkit:latest 21 | ``` 22 | 23 | - Run a specific tag of the toolkit: 24 | 25 | ```bash 26 | docker run -it --rm tungbq/devops-toolkit:0.1.0 27 | ``` 28 | 29 | - Run the image with host network and remove the container after it completes: 30 | 31 | ```bash 32 | docker run --network host -it --rm tungbq/devops-toolkit:latest 33 | ``` 34 | 35 | - Run the image with default configuration and keep the container: 36 | 37 | ```bash 38 | docker run --network host -it tungbq/devops-toolkit:latest 39 | ``` 40 | 41 | - Run the image with default configuration, specify the container name, and keep the container: 42 | 43 | ```bash 44 | docker run --network host -it --name demo001 tungbq/devops-toolkit:latest 45 | ``` 46 | 47 | - Run the image and mount the configuration from the host, and remove the container after it completes: 48 | 49 | ```bash 50 | mkdir -p ~/.dtc # or other location you want to store the configuration 51 | docker run --network host -it --rm -v ~/.dtc:/dtc tungbq/devops-toolkit:latest 52 | ``` 53 | -------------------------------------------------------------------------------- /docs/usage/terraform_usage.md: -------------------------------------------------------------------------------- 1 | # Use terraform in the devops-toolkit 2 | 3 | ## Terraform document 4 | 5 | Some document to help you start with terraform 6 | 7 | - 8 | - 9 | 10 | ## Run with Docker command 11 | 12 | ### Note 13 | 14 | To use the existing container instead of creating one, use `docker exec` command instead of `docker run` 15 | 16 | ```bash 17 | docker exec -it my_devops_toolkit /bin/bash 18 | ``` 19 | 20 | ### Common Run Modes 21 | 22 | For instructions on common run modes, visit [**DevOps Toolkit Common Run Mode**](../usage/run_mode.md). 23 | 24 | ### Use case 1: Run terraform sample code provided in the container 25 | 26 | ```bash 27 | docker run --rm --network host -it -v ~/.dtc:/dtc tungbq/devops-toolkit:latest 28 | # You now in the container terminal 29 | # Navigate to Terraform sample 30 | pushd samples/terraform/basic 31 | # Init the terraform 32 | terraform init 33 | # Apply change, select 'yes' to confirm 34 | terraform apply 35 | # Once done, destroy the infra, select 'yes' to confirm 36 | terraform destroy 37 | popd 38 | ``` 39 | 40 | ### Use case 2: Clone external code inside container 41 | 42 | ```bash 43 | docker run --rm --network host -it -v ~/.dtc:/dtc tungbq/devops-toolkit:latest 44 | # You now in the container terminal 45 | 46 | # Now run your cloned script 47 | # Clone code 48 | mkdir terraform_workspace; cd terraform_workspace 49 | git clone terraform-examples 50 | 51 | cd terraform-examples 52 | # Run terraform here: init-plan-apply,... 53 | ``` 54 | 55 | ### Use case 3: Mount external code to container 56 | 57 | Clone the code to the host then mount to container 58 | 59 | ```bash 60 | # Given that we have code somewhere in you machine 61 | docker run --rm -v "$(pwd)":/root/terraform_workspace -v ~/.dtc:/dtc --network host -it tungbq/devops-toolkit:latest 62 | # Run the terraform code as usual 63 | ``` 64 | 65 | ### Troubleshooting 66 | 67 | - For any issues, check [this reference](../troubleshooting/TROUBLESHOOTING.md) 68 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # NOTE: 'dtc' stands for devops toolkit configuration 4 | CONFIG_DIR=/dtc 5 | 6 | # Function to create symlink if source exists 7 | create_symlink() { 8 | local src=$1 9 | local dest=$2 10 | if [ -e "$src" ]; then 11 | ln -sf "$src" "$dest" 12 | echo "Symlink created: $src -> $dest" 13 | fi 14 | } 15 | 16 | # Check if the /dtc directory exists and is not empty 17 | if [ -d "$CONFIG_DIR" ]; then 18 | echo "Custom configuration directory detected. Setting up symlinks..." 19 | 20 | # TODO: Check and only create if folder does not exist 21 | ## config mount point 22 | mkdir -p /dtc/.aws \ 23 | /dtc/.azure \ 24 | /dtc/.kube \ 25 | /dtc/.terraform.d \ 26 | /dtc/.config/helm \ 27 | /dtc/.ansible 28 | 29 | ## root container path 30 | mkdir -p /root/.config/ 31 | 32 | create_symlink "$CONFIG_DIR/.aws" "/root/.aws" 33 | create_symlink "$CONFIG_DIR/.azure" "/root/.azure" 34 | create_symlink "$CONFIG_DIR/.kube" "/root/.kube" 35 | create_symlink "$CONFIG_DIR/.terraform.d" "/root/.terraform.d" 36 | create_symlink "$CONFIG_DIR/.config/helm" "/root/.config/helm" 37 | create_symlink "$CONFIG_DIR/.ansible" "/root/.ansible" 38 | create_symlink "$CONFIG_DIR/.gitconfig" "/root/.gitconfig" 39 | else 40 | echo "No custom configuration directory detected. Using default configurations..." 41 | fi 42 | 43 | # Execute the provided command 44 | exec "$@" 45 | -------------------------------------------------------------------------------- /pr-changelog.txt: -------------------------------------------------------------------------------- 1 | core: update tool versions 2 | 3 | - **terraform**: from `1.11.0` to `1.11.2` 4 | - **kubectl**: from `1.32.2` to `1.32.3` 5 | - **helm**: from `3.17.1` to `3.17.2` 6 | - **awscli**: from `2.24.15` to `2.24.24` 7 | - **azurecli**: from `2.69.0` to `2.70.0` 8 | 9 | Auto-generated by [create-pull-request](https://github.com/peter-evans/create-pull-request) 10 | -------------------------------------------------------------------------------- /samples/README.md: -------------------------------------------------------------------------------- 1 | # Sample code for tools inside toolkit 2 | 3 | ## First step 4 | 5 | Start and dive into the container 6 | 7 | ```bash 8 | docker run -it --rm tungbq/devops-toolkit:latest 9 | ``` 10 | 11 | Congrats! You now in the container and able to run the tooling sample inside toolkit, the console will look like: 12 | 13 | ```bash 14 | root@05cf97a07b19:~# 15 | ``` 16 | 17 | ## Python 18 | 19 | ```bash 20 | python3 samples/python/rectangle_area_calculator.py 21 | ```` 22 | 23 | ## Ansible 24 | 25 | ```bash 26 | ansible-playbook samples/ansible/check_os.yml 27 | ``` 28 | 29 | ## Terraform 30 | 31 | ```bash 32 | # Navigate to Terraform sample 33 | pushd samples/terraform/basic 34 | # Init the terraform 35 | terraform init 36 | # Apply change, select 'yes' to confirm 37 | terraform apply 38 | # Once done, destroy the infra, select 'yes' to confirm 39 | terraform destroy 40 | popd 41 | ``` 42 | 43 | 44 | ## Kubectl 45 | 46 | ```bash 47 | # Check Kubectl version 48 | kubectl version 49 | ``` 50 | 51 | ## Helm 52 | ```bash 53 | # Add Helm Chart repository 54 | helm repo add bitnami https://charts.bitnami.com/bitnami 55 | # Search Helm Chart Repository for Jenkins 56 | helm search repo bitnami | grep jenkins 57 | ``` 58 | 59 | ## AwsCLI 60 | 61 | - TODO 62 | 63 | ## AzureCLI 64 | 65 | - TODO 66 | -------------------------------------------------------------------------------- /samples/ansible/check_os.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check OS Version on Localhost 3 | hosts: localhost 4 | tasks: 5 | - name: Gather facts 6 | ansible.builtin.setup: 7 | 8 | - name: Print OS version 9 | ansible.builtin.debug: 10 | msg: "The OS version is {{ ansible_distribution }} {{ ansible_distribution_version }}" 11 | -------------------------------------------------------------------------------- /samples/python/rectangle_area_calculator.py: -------------------------------------------------------------------------------- 1 | def calculate_rectangle_area(length, width): 2 | """ 3 | Calculate the area of a rectangle. 4 | 5 | Args: 6 | - length (float): Length of the rectangle. 7 | - width (float): Width of the rectangle. 8 | 9 | Returns: 10 | - float: The calculated area of the rectangle. 11 | """ 12 | print("Length:", length) 13 | print("Width:", width) 14 | 15 | area = length * width 16 | return area 17 | 18 | def main(): 19 | # Define length and width of the rectangle 20 | length = 5.0 21 | width = 3.0 22 | 23 | # Calculate the area of the rectangle 24 | area = calculate_rectangle_area(length, width) 25 | 26 | # Display the result 27 | print("The area of the rectangle is:", area) 28 | 29 | if __name__ == "__main__": 30 | main() 31 | -------------------------------------------------------------------------------- /samples/run_sample.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Define color variables 4 | GREEN='\033[0;32m' # Green color 5 | NC='\033[0m' # No color (reset) 6 | 7 | # Function to log messages with INFO prefix in green color 8 | console_log() { 9 | message=$1 10 | echo -e "${GREEN}[INFO] $message ${NC}" 11 | } 12 | 13 | ########### 14 | # Python 15 | ########### 16 | console_log "Running Python sample: rectangle_area_calculator.py" 17 | python3 samples/python/rectangle_area_calculator.py 18 | 19 | ########### 20 | # Ansible 21 | ########### 22 | console_log "Running Ansible sample: check_os.yml" 23 | ansible-playbook samples/ansible/check_os.yml 24 | 25 | ########### 26 | # Terraform 27 | ########### 28 | console_log "Running Terraform sample: basic" 29 | pushd samples/terraform/basic || exit 30 | terraform init 31 | terraform apply -auto-approve 32 | terraform destroy -auto-approve 33 | popd || exit 34 | 35 | ########### 36 | # Kubectl 37 | ########### 38 | console_log "Running Kubectl sample: check version" 39 | kubectl version 40 | 41 | ########### 42 | # Helm 43 | ########### 44 | console_log "Running Helm sample: add and search" 45 | helm repo add bitnami https://charts.bitnami.com/bitnami 46 | helm search repo bitnami | grep jenkins 47 | 48 | -------------------------------------------------------------------------------- /samples/terraform/basic/main.tf: -------------------------------------------------------------------------------- 1 | resource "null_resource" "local_command" { 2 | provisioner "local-exec" { 3 | command = "echo Hello, Terraform!" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /script_requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | -------------------------------------------------------------------------------- /scripts/check_latest_version.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import re 3 | import json 4 | import argparse 5 | 6 | class VersionParser: 7 | def __init__(self): 8 | self.url = None 9 | self.version = None 10 | 11 | def fetch_html(self, url): 12 | try: 13 | response = requests.get(url) 14 | response.raise_for_status() 15 | return response.text 16 | except requests.exceptions.RequestException as e: 17 | raise Exception(f"Error fetching HTML from {url}: {e}") 18 | 19 | def do_http_request(self, url): 20 | try: 21 | response = requests.get(url) 22 | response.raise_for_status() 23 | return response.json() 24 | except requests.exceptions.RequestException as e: 25 | raise Exception(f"Error fetching data from {url}: {e}") 26 | 27 | def check_version(self, name, url, pattern): 28 | latest_version = None 29 | text = self.fetch_html(url) 30 | match = re.search(pattern, text) 31 | 32 | if match: 33 | latest_version = match.group(1) 34 | print(f"Latest version of {name}: {latest_version}") 35 | else: 36 | raise Exception(f"Version number not found for {name}.") 37 | 38 | return latest_version 39 | 40 | def check_python_version(self): 41 | # Specifying the Python version for installation via apt (saves time and reduces image size). Refer to issue #104. 42 | # While manual updates for the Python version are needed, 3.11 has been reliable so far (on Ubuntu:22.04 base image). 43 | python_version = "3.11" 44 | return python_version 45 | 46 | def check_kubectl_version(self): 47 | pattern = r'v(\d+\.\d+\.\d+)' 48 | return self.check_version("kubectl", "https://cdn.dl.k8s.io/release/stable.txt", pattern) 49 | 50 | def check_awscli_version(self): 51 | version_pattern = re.compile(r'\b(\d+\.\d+\.\d+)\b') 52 | return self.check_version("awscli", "https://raw.githubusercontent.com/aws/aws-cli/v2/CHANGELOG.rst", version_pattern) 53 | 54 | def check_github_release_version(self, name, repo, tag_prefix="v"): 55 | print(f"Checking {name} version from repo {repo} using tag prefix: {tag_prefix}") 56 | latest_version = None 57 | req = self.do_http_request(f"https://api.github.com/repos/{repo}/releases/latest") 58 | latest_tag_name = req["tag_name"] 59 | 60 | latest_version = latest_tag_name.split(tag_prefix)[1] 61 | print(f"Latest version of {name}: {latest_version}") 62 | return latest_version 63 | 64 | def main(output_file): 65 | versions = {} 66 | version_parser = VersionParser() 67 | 68 | try: 69 | # Python 70 | python_version = version_parser.check_python_version() 71 | versions["python3"] = python_version 72 | 73 | # Ansible 74 | ansible_version = version_parser.check_github_release_version("Ansible", "ansible/ansible") 75 | versions["ansible"] = ansible_version 76 | 77 | # Terraform 78 | terraform_version = version_parser.check_github_release_version("Terraform", "hashicorp/terraform") 79 | versions["terraform"] = terraform_version 80 | 81 | # Kubectl 82 | kubectl_version = version_parser.check_kubectl_version() 83 | versions["kubectl"] = kubectl_version 84 | 85 | # Helm 86 | helm_version = version_parser.check_github_release_version("Helm", "helm/helm") 87 | versions["helm"] = helm_version 88 | 89 | # Awscli 90 | awscli_version = version_parser.check_awscli_version() 91 | versions["awscli"] = awscli_version 92 | 93 | # AZ CLi 94 | azcli_version = version_parser.check_github_release_version("Azure CLI", "Azure/azure-cli", "azure-cli-") 95 | versions["azurecli"] = azcli_version 96 | 97 | # PowerShell Core 98 | pwsh_version = version_parser.check_github_release_version("PowerShell", "PowerShell/PowerShell", "v") 99 | versions["pwsh"] = pwsh_version 100 | 101 | # Summary 102 | print("Summary:") 103 | print(versions) 104 | 105 | ## TODO: implement auto workflow 106 | # Write version data to the specified output file 107 | with open(output_file, 'w') as json_file: 108 | json.dump(versions, json_file, indent=2) 109 | print(f"Version data written to '{output_file}'") 110 | except Exception as e: 111 | print(f"An error occurred: {e}") 112 | 113 | if __name__ == "__main__": 114 | parser = argparse.ArgumentParser(description="Parse toolkit versions and write to a JSON file.") 115 | parser.add_argument("output_file", help="Path to the output JSON file") 116 | 117 | args = parser.parse_args() 118 | main(args.output_file) -------------------------------------------------------------------------------- /scripts/check_version_in_toolkit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | image_name=$1 4 | toolkit_info_path=$2 5 | 6 | # Use jq to extract values 7 | python_version=$(cat "$toolkit_info_path" | jq -r '.python3') 8 | ansible_version=$(cat "$toolkit_info_path" | jq -r '.ansible') 9 | terraform_version=$(cat "$toolkit_info_path" | jq -r '.terraform') 10 | kubectl_version=$(cat "$toolkit_info_path" | jq -r '.kubectl') 11 | helm_version=$(cat "$toolkit_info_path" | jq -r '.helm') 12 | awscli_version=$(cat "$toolkit_info_path" | jq -r '.awscli') 13 | azurecli_version=$(cat "$toolkit_info_path" | jq -r '.azurecli') 14 | pwsh_version=$(cat "$toolkit_info_path" | jq -r '.pwsh') 15 | 16 | # Print the versions 17 | echo "Desired version:" 18 | echo "python_version=$python_version" 19 | echo "ansible_version=$ansible_version" 20 | echo "terraform_version=$terraform_version" 21 | echo "kubectl_version=$kubectl_version" 22 | echo "helm_version=$helm_version" 23 | echo "awscli_version=$awscli_version" 24 | echo "azurecli_version=$azurecli_version" 25 | echo "pwsh_version=$pwsh_version" 26 | 27 | # Define the tools and their expected versions 28 | declare -A tools=( 29 | [python3]="$python_version" 30 | [ansible]="$ansible_version" 31 | [terraform]="$terraform_version" 32 | [kubectl]="$kubectl_ve"rsion 33 | [helm]="$helm_version" 34 | [aws]="$awscli_version" 35 | [az]="$azurecli_version" 36 | [pwsh]="$pwsh_version" 37 | # Add more tools as needed 38 | ) 39 | 40 | # Function to check tool versions 41 | check_tool_version() { 42 | local tool_name=$1 43 | local expected_version=$2 44 | echo "[$tool_name] Checking version..." 45 | 46 | # Possible version option flags for different tools 47 | local version_flags=( 48 | "--version" 49 | "version" 50 | ) 51 | 52 | installed_version="" 53 | 54 | # Iterate through possible version flags 55 | for flag in "${version_flags[@]}"; do 56 | installed_version=$(docker run --rm "$image_name" "$tool_name" "$flag" 2>&1) 57 | # Check if the version information is in the output 58 | if echo "$installed_version" | grep -q "$expected_version"; then 59 | break 60 | fi 61 | done 62 | 63 | # Compare the installed version with the expected version 64 | if echo "$installed_version" | grep -q "$expected_version"; then 65 | echo "[OK] $tool_name version is correct: $installed_version" 66 | else 67 | echo "[Error] Incorrect $tool_name version. Expected $expected_version but found $installed_version" 68 | exit 1 69 | fi 70 | } 71 | 72 | # Loop through the tools and check their versions 73 | for tool in "${!tools[@]}"; do 74 | check_tool_version "$tool" "${tools[$tool]}" 75 | echo "" 76 | done 77 | 78 | # If all checks pass, print success message 79 | echo "All tools in $image_name are correctly installed and have the expected versions." 80 | -------------------------------------------------------------------------------- /scripts/docker_build.sh: -------------------------------------------------------------------------------- 1 | echo "To-do" 2 | -------------------------------------------------------------------------------- /scripts/parse_diff.py: -------------------------------------------------------------------------------- 1 | import re 2 | import subprocess 3 | import sys 4 | 5 | def parse_git_diff(file_path): 6 | # Run git diff command and capture its output 7 | git_diff_output = subprocess.check_output(['git', 'diff', file_path], universal_newlines=True) 8 | 9 | # Define regex patterns to capture the key and versions 10 | remove_pattern = re.compile(r'-\s+"(\w+)":\s"([\d\.]+)",') 11 | add_pattern = re.compile(r'\+\s+"(\w+)":\s"([\d\.]+)",') 12 | 13 | # Find all matches 14 | removed = remove_pattern.findall(git_diff_output) 15 | added = add_pattern.findall(git_diff_output) 16 | 17 | # Create dictionaries from matches for easy lookup 18 | removed_dict = dict(removed) 19 | added_dict = dict(added) 20 | 21 | # Generate the formatted output 22 | output = [] 23 | for key in added_dict: 24 | if key in removed_dict: 25 | output.append(f"- **{key}**: from `{removed_dict[key]}` to `{added_dict[key]}`") 26 | 27 | formatted_output = "\n".join(output) 28 | return formatted_output 29 | 30 | if __name__ == "__main__": 31 | if len(sys.argv) != 2: 32 | print("Usage: python script.py ") 33 | sys.exit(1) 34 | 35 | file_path = sys.argv[1] 36 | formatted_output = parse_git_diff(file_path) 37 | print(formatted_output) 38 | -------------------------------------------------------------------------------- /scripts/update_latest_version.py: -------------------------------------------------------------------------------- 1 | import json 2 | import argparse 3 | import os 4 | 5 | def parse_toolkit_info(toolkit_info_file): 6 | with open(toolkit_info_file, 'r') as json_file: 7 | toolkit_info = json.load(json_file) 8 | return toolkit_info 9 | 10 | def update_file(file_path, version_arg, new_version, file_type): 11 | with open(file_path, 'r') as file: 12 | file_content = file.read() 13 | 14 | old_version = None 15 | arg_pattern = f'{version_arg}=' if file_type == 'Dockerfile' else f'| {version_arg}=' 16 | if arg_pattern in file_content: 17 | old_version = file_content.split(arg_pattern)[1].split()[0] 18 | 19 | print(f"Working on: {file_path}") 20 | print(f"Old version: {old_version}") 21 | 22 | if not old_version: 23 | raise Exception(f"Cannot detect old version in {file_type}!") 24 | 25 | if old_version != new_version: 26 | new_file_content = file_content.replace(f'{arg_pattern}{old_version}', f'{arg_pattern}{new_version}') 27 | 28 | with open(file_path, 'w') as file: 29 | file.write(new_file_content) 30 | 31 | print(f"{file_type} updated. {tool_name} version changed from {old_version} to {new_version}") 32 | else: 33 | print(f"No update needed for {tool_name}. Versions match.") 34 | 35 | def update_dockerfile(dockerfile_path, version_arg, new_version): 36 | update_file(dockerfile_path, version_arg, new_version, 'Dockerfile') 37 | 38 | def update_readme(readme_path, version_arg, new_version): 39 | update_file(readme_path, version_arg, new_version, 'readme') 40 | 41 | if __name__ == "__main__": 42 | parser = argparse.ArgumentParser(description="Update Dockerfile with latest toolkit versions.") 43 | parser.add_argument("toolkit_info", help="Path to the toolkit_info.json file") 44 | parser.add_argument("dockerfile", help="Path to the Dockerfile") 45 | parser.add_argument("readme", help="Path to the readme") 46 | 47 | args = parser.parse_args() 48 | 49 | toolkit_info_file = args.toolkit_info 50 | dockerfile_path = args.dockerfile 51 | readme_path = args.readme 52 | 53 | toolkit_info = parse_toolkit_info(toolkit_info_file) 54 | 55 | tools = [ 56 | {"name": "python3", "version_arg": "PYTHON_VERSION"}, 57 | {"name": "ansible", "version_arg": "ANSIBLE_VERSION"}, 58 | {"name": "terraform", "version_arg": "TERRAFORM_VERSION"}, 59 | {"name": "kubectl", "version_arg": "KUBECTL_VERSION"}, 60 | {"name": "helm", "version_arg": "HELM_VERSION"}, 61 | {"name": "awscli", "version_arg": "AWSCLI_VERSION"}, 62 | {"name": "azurecli", "version_arg": "AZURECLI_VERSION"}, 63 | {"name": "pwsh", "version_arg": "PS_VERSION"} 64 | ] 65 | 66 | for tool in tools: 67 | tool_name = tool["name"] 68 | print(f"[{tool_name}] Check and update") 69 | version_arg = tool["version_arg"] 70 | 71 | if tool_name in toolkit_info: 72 | new_version = toolkit_info[tool_name] 73 | update_dockerfile(dockerfile_path, version_arg, new_version) 74 | update_readme(readme_path, version_arg, new_version) 75 | else: 76 | print(f"Error: {tool_name} version not found in {toolkit_info_file}.") 77 | -------------------------------------------------------------------------------- /toolkit_info.json: -------------------------------------------------------------------------------- 1 | { 2 | "python3": "3.11", 3 | "ansible": "2.18.3", 4 | "terraform": "1.11.2", 5 | "kubectl": "1.32.3", 6 | "helm": "3.17.2", 7 | "awscli": "2.24.24", 8 | "azurecli": "2.70.0", 9 | "pwsh": "7.5.0" 10 | } --------------------------------------------------------------------------------