├── .circleci └── config.yml ├── .github └── FUNDING.yml ├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── assets ├── terraform-docs-as-pdf.png └── terraform-docs-as-pdf.psd └── bin ├── Makefile.patch └── generate.sh /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | references: 4 | update_submodules: &update_submodules 5 | run: 6 | name: Update git submodules 7 | command: | 8 | git submodule update --init --remote 9 | 10 | install_dependencies: &install_dependencies 11 | run: 12 | name: Install dependencies 13 | command: | 14 | sudo apt-get update 15 | 16 | sudo apt-get install patch ghostscript nano 17 | 18 | # Install wkhtmltopdf 19 | mkdir wkhtmltopdf_download 20 | cd wkhtmltopdf_download 21 | wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.trusty_amd64.deb 22 | sudo dpkg -i ./wkhtmltox_0.12.5-1.trusty_amd64.deb || sudo apt-get --fix-broken install 23 | cd .. 24 | rm -rf wkhtmltopdf_download/ 25 | 26 | # Install git-lfs - https://github.com/git-lfs/git-lfs/wiki/Installation#ubuntu 27 | # sudo add-apt-repository ppa:git-core/ppa -y 28 | # curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash 29 | # sudo apt-get install git-lfs 30 | # git lfs install 31 | 32 | # verify versions 33 | grep --version 34 | sed --version 35 | wkhtmltopdf --version 36 | gs --version 37 | 38 | run_website_locally_and_generate_all: &run_website_locally_and_generate_all 39 | run: 40 | name: Run website locally (in background) and generate all pdfs 41 | environment: 42 | GIT_USER_EMAIL: anton+betajobot@antonbabenko.com 43 | GIT_USER_NAME: betajobot 44 | no_output_timeout: 3h 45 | command: | 46 | echo "Patch terraform-website/Makefile to remove --tty" 47 | patch terraform-website/Makefile bin/Makefile.patch 48 | 49 | cd terraform-website 50 | 51 | make website & 52 | 53 | echo "Wait for site to start (30 minimum, sometimes internet may be slow, so 300 is better)" 54 | sleep 300 55 | 56 | # Code from https://stackoverflow.com/a/42873372/550451 57 | curl --fail \ 58 | --connect-timeout 5 \ 59 | --max-time 10 \ 60 | --retry 10 \ 61 | --retry-delay 2 \ 62 | --retry-max-time 40 \ 63 | 'http://localhost:3000/' > /dev/null 64 | 65 | cd .. 66 | 67 | # Generate all while web-site is running 68 | ./bin/generate.sh 69 | 70 | jobs: 71 | build_all: 72 | machine: true 73 | working_directory: ~/project 74 | steps: 75 | - checkout 76 | - *update_submodules 77 | - *install_dependencies 78 | - *run_website_locally_and_generate_all 79 | 80 | workflows: 81 | version: 2 82 | nightly: 83 | triggers: 84 | - schedule: 85 | cron: "0 0 * * *" 86 | filters: 87 | branches: 88 | only: 89 | - master 90 | jobs: 91 | - build_all 92 | 93 | 94 | build_all: 95 | jobs: 96 | - build_all: 97 | filters: 98 | branches: 99 | only: master 100 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [antonbabenko] 2 | custom: https://www.paypal.me/antonbabenko 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.txt 2 | *.pdf 3 | cmds/ 4 | pdfs/ 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "terraform-website"] 2 | path = terraform-website 3 | url = https://github.com/hashicorp/terraform-website.git 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Anton Babenko 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Complete Terraform documentation as PDF files. Updating nightly. 2 | 3 | [![CircleCI](https://circleci.com/gh/antonbabenko/terraform-docs-as-pdf.svg?style=svg&circle-token=9e5321eb98d9d47cda7ef4209e287f56c25a702a)](https://circleci.com/gh/antonbabenko/terraform-docs-as-pdf) 4 | ![](https://img.shields.io/github/repo-size/antonbabenko/terraform-docs-as-pdf.svg) 5 | ![](https://img.shields.io/github/last-commit/antonbabenko/terraform-docs-as-pdf.svg) 6 | 7 | > Once upon a time, I've been missing Terraform documentation on my flight across Atlantic. 8 | 9 | ## Features 10 | 11 | 1. Official content from [terraform.io](https://terraform.io/) web-site is used. Source: [terraform-website](https://github.com/hashicorp/terraform-website). 12 | 1. Include documentation for 95+ officially supported Terraform providers. Source: [terraform-providers](https://github.com/terraform-providers). 13 | 1. Updating nightly. 14 | 1. Documentation is generated from the web-site running locally. 15 | 1. Get updates in your Dropbox folder - https://www.dropbox.com/sh/pfj9e1m5d7nqhp3/AAAqW1OI3oYPa4UXfYb4fLGaa 16 | 17 | ## How to use this? 18 | 19 | 1. Don't have Dropbox account? Open one using [my referral link](https://db.tt/5Bhs91K9Wb) and I will get 500M extra. :) 20 | 21 | 1. To get PDFs to your Dropbox folder - click [this shared link](https://www.dropbox.com/sh/pfj9e1m5d7nqhp3/AAAqW1OI3oYPa4UXfYb4fLGaa), then choose "Download" and "Save to my Dropbox". 22 | 23 | 1. Alternatively, browse PDFs online - [https://www.dropbox.com/sh/pfj9e1m5d7nqhp3/AAAqW1OI3oYPa4UXfYb4fLGaa](https://www.dropbox.com/sh/pfj9e1m5d7nqhp3/AAAqW1OI3oYPa4UXfYb4fLGaa) 24 | 25 | ## Existing PDF files 26 | 27 | 1. All in one: Terraform docs with all official providers 28 | 1. Terraform docs (without providers) 29 | 1. Terraform docs for each provider 30 | 31 | ## Authors 32 | 33 | This project is maintained by [Anton Babenko](https://github.com/antonbabenko) with help from [these awesome contributors](https://github.com/antonbabenko/terraform-docs-as-pdf/graphs/contributors). 34 | 35 | ## License 36 | 37 | MIT Licensed. See LICENSE for full details. 38 | 39 | Terraform documentation itself is licensed under MPL 2.0. See [LICENSE.md](https://github.com/hashicorp/terraform-website/blob/master/LICENSE.md) for more details. 40 | 41 | ### Latest update: 2022-05-19 42 | -------------------------------------------------------------------------------- /assets/terraform-docs-as-pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ann-felix/terraform-docs-as-pdf/8c978a8f8e748bf9fbf0b85e347482d73b6a0467/assets/terraform-docs-as-pdf.png -------------------------------------------------------------------------------- /assets/terraform-docs-as-pdf.psd: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f1d0a63a13ca0a789dd2abbdfa691956abf15146588d5a2834dd57764fb2aac5 3 | size 331967 4 | -------------------------------------------------------------------------------- /bin/Makefile.patch: -------------------------------------------------------------------------------- 1 | --- Makefile 2021-12-16 21:08:32.000000000 +0100 2 | +++ Makefile_new 2021-12-16 21:29:46.000000000 +0100 3 | @@ -6,7 +6,6 @@ 4 | @docker run \ 5 | --interactive \ 6 | --rm \ 7 | - --tty \ 8 | --workdir "/website" \ 9 | --volume "$(shell pwd):/website" \ 10 | --volume "/website/node_modules" \ 11 | -------------------------------------------------------------------------------- /bin/generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TARGET_SITE="http://localhost:3000" 4 | 5 | # Get all urls 6 | # wget --spider --force-html -r -l5 "$TARGET_SITE" 2>&1 | grep '^--' | awk '{ print $3 }' | grep -v '\.\(css\|js\|png\|gif\|jpg|svg|woff|ttf|zip|json\)$' > url-list-5.txt 7 | 8 | # Using sitemap (better) 9 | # curl -O http://localhost:3000/sitemap.xml 10 | 11 | # gnu grep 12 | #ggrep -Po 'http(s?)://[^ \"()\<>]*' sitemap.xml 13 | 14 | # Remove index.html from URL 15 | #sed -i -r "s#/index.html\$##g" url-list-5.txt 16 | 17 | # Make list unique and nice 18 | #sort url-list-5.txt | uniq | sort -n > unique-5.txt 19 | 20 | URLS="unique-urls.txt" 21 | 22 | CMDS_DIR="cmds" 23 | 24 | function assert_is_installed { 25 | local readonly name="$1" 26 | 27 | if [[ ! $(command -v ${name}) ]]; then 28 | echo "ERROR: The binary '$name' is required by this script but is not installed or in the system's PATH." 29 | exit 1 30 | fi 31 | } 32 | 33 | function string_starts_with { 34 | local readonly str="$1" 35 | local readonly prefix="$2" 36 | 37 | [[ "$str" == "$prefix"* ]] 38 | } 39 | 40 | function verify_dependencies { 41 | 42 | assert_is_installed git 43 | assert_is_installed curl 44 | assert_is_installed grep # gnu 45 | # assert_is_installed ggrep 46 | assert_is_installed sed 47 | 48 | # https://wkhtmltopdf.org/downloads.html 49 | assert_is_installed wkhtmltopdf 50 | 51 | # https://www.ghostscript.com/download.html 52 | assert_is_installed gs 53 | } 54 | 55 | function prepare_urls { 56 | # Get all URLs from sitemap.xml 57 | # ggrep on Mac = GNU grep 58 | curl $TARGET_SITE/sitemap.xml | grep -Po 'http(s?)://[^ \"()\<>]*' | sed -r "s#/index.html\$##g" > all-urls.txt 59 | 60 | # Drop duplicates 61 | sort all-urls.txt | uniq | sort -n > $URLS 62 | 63 | # Replace URL to local one 64 | sed -i -r "s#https://www.terraform.io#${TARGET_SITE}#g" $URLS 65 | } 66 | 67 | function recreate_work_dir { 68 | rm -rf $CMDS_DIR 69 | mkdir -p $CMDS_DIR 70 | 71 | rm -rf pdfs 72 | mkdir -p pdfs 73 | } 74 | 75 | 76 | function make_cmd_files { 77 | 78 | i=0 79 | index=0 80 | prev_group_name="" 81 | 82 | while read url; do 83 | url_path=$(echo "$url" | sed -r 's#https?://[a-z0-9\:]+/(.*)#\1#g') 84 | 85 | if $(string_starts_with "$url_path" "docs/providers/"); then 86 | provider_name=$(echo "$url_path" | sed -r 's#([a-z]+/){2}([a-z]+)(.*)#\2#g') 87 | 88 | if [[ $prev_group_name != $provider_name ]]; then 89 | i=0 90 | index=0 91 | fi 92 | 93 | echo -n "$url " >> "${CMDS_DIR}/${provider_name}.${index}" 94 | prev_group_name=$provider_name 95 | else 96 | echo -n "$url " >> "${CMDS_DIR}/terraform-website.${index}" 97 | prev_group_name="terraform-website" 98 | fi 99 | 100 | if (( $i != 0 && $i % 20 == 0 )); then 101 | ((index=index+1)) 102 | fi 103 | 104 | ((i=i+1)) 105 | 106 | done < "$URLS" 107 | } 108 | 109 | function make_final_cmd_file { 110 | 111 | for file in $(\ls ${CMDS_DIR}); do 112 | echo "pdfs/$file.pdf" >> "${CMDS_DIR}/${file}" 113 | cat "${CMDS_DIR}/${file}" >> "${CMDS_DIR}/final" 114 | done 115 | 116 | } 117 | 118 | function make_pdf_files { 119 | 120 | wkhtmltopdf \ 121 | --print-media-type \ 122 | --disable-javascript \ 123 | --disable-internal-links \ 124 | --javascript-delay 10000 \ 125 | --load-error-handling skip \ 126 | --stop-slow-scripts \ 127 | --read-args-from-stdin \ 128 | < "${CMDS_DIR}/final" 129 | 130 | } 131 | 132 | function combine_pdf_files { 133 | 134 | pushd pdfs 135 | all_pdfs=($(\ls -1 *.pdf)) 136 | 137 | prev_name="" 138 | for file in "${all_pdfs[@]}"; do 139 | name=$(cut -d "." -f 1 <<< "$file") 140 | 141 | if [[ $prev_name != $name ]]; then 142 | echo "Combining PDF files by name - $name" 143 | 144 | gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile=../${name}.pdf $(\ls -1 ${name}.*.pdf | sort -V) 145 | fi 146 | 147 | prev_name=$name 148 | done 149 | 150 | # Make one huge (include terraform-website in the beginning) 151 | # @todo: include cover, toc 152 | echo "Combining all PDF files into one - complete-terraform-website.pdf" 153 | gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile=../complete-terraform-website.pdf ../terraform-website.pdf $(\ls -1 ../*.pdf | grep -v terraform-website.pdf | sort -V) 154 | 155 | popd 156 | 157 | } 158 | 159 | function upload_pdf_files { 160 | 161 | all_pdfs=($(\ls -1 *.pdf)) 162 | 163 | for file in "${all_pdfs[@]}"; do 164 | 165 | echo "Uploading ${file}" 166 | 167 | curl -X POST https://content.dropboxapi.com/2/files/upload \ 168 | --header "Authorization: Bearer $DROPBOX_TOKEN" \ 169 | --header "Dropbox-API-Arg: {\"path\": \"/terraform-docs-as-pdf/${file}\",\"mode\": \"overwrite\",\"autorename\": false,\"mute\": false,\"strict_conflict\": false}" \ 170 | --header "Content-Type: application/octet-stream" \ 171 | --data-binary @$file 172 | 173 | rm -f $file 174 | 175 | done 176 | 177 | 178 | # List all filenames 179 | #curl -X POST https://api.dropboxapi.com/2/files/list_folder \ 180 | # --header "Authorization: Bearer $DROPBOX_TOKEN" \ 181 | # --header "Content-Type: application/json" \ 182 | # --data "{\"path\": \"/terraform-docs-as-pdf\",\"recursive\": false,\"include_media_info\": false,\"include_deleted\": false,\"include_has_explicit_shared_members\": false,\"include_mounted_folders\": false, \"limit\": 100}" | jq -r '.entries[] | select (.".tag"|test("file")) | .name' | sort 183 | 184 | } 185 | 186 | function git_config_commit_and_push { 187 | 188 | echo "Configuring git to use user.email '$GIT_USER_EMAIL', user.name '$GIT_USER_NAME', and 'push.default matching'" 189 | git config credential.helper 'cache --timeout=120' 190 | git config user.email "$GIT_USER_EMAIL" 191 | git config user.name "$GIT_USER_NAME" 192 | git config --global push.default matching 193 | 194 | git add . 195 | git status 196 | git commit -m "[skip ci] Updated documentation" 197 | git push -q https://${GITHUB_PERSONAL_TOKEN}@github.com/antonbabenko/terraform-docs-as-pdf.git master 198 | 199 | } 200 | 201 | function update_readme { 202 | now=$(date --rfc-3339=date) 203 | 204 | sed -i -r "s|### Latest update: .*|### Latest update: $now|g" README.md 205 | } 206 | 207 | echo "Verified installed dependencies..." 208 | verify_dependencies 209 | 210 | echo "Preparing list of URLs..." 211 | prepare_urls 212 | 213 | echo "Prepare working directories..." 214 | recreate_work_dir 215 | 216 | echo "Making list of cmd files..." 217 | make_cmd_files 218 | 219 | echo "Combining small cmd files into one..." 220 | make_final_cmd_file 221 | 222 | echo "Making pdf files... This may take some time..." 223 | make_pdf_files 224 | 225 | echo "Combining PDF files..." 226 | combine_pdf_files 227 | 228 | echo "Uploading PDF files..." 229 | upload_pdf_files 230 | 231 | echo "Updating README..." 232 | update_readme 233 | 234 | echo "Upload PDF files to github..." 235 | git_config_commit_and_push --------------------------------------------------------------------------------