├── .copywrite.hcl ├── .github ├── actions │ └── spelling │ │ ├── README.md │ │ ├── advice.md │ │ ├── allow.txt │ │ ├── excludes.txt │ │ ├── expect.txt │ │ ├── line_forbidden.patterns │ │ ├── only.txt │ │ ├── patterns.txt │ │ └── reject.txt ├── dependabot.yml ├── env ├── pr-body.md ├── social │ └── preview.jpg └── workflows │ ├── cla.yaml │ ├── cnspec-update.yml │ ├── ensure-generated.yaml │ ├── gh-release.yaml │ ├── notify-integration-release-via-manual.yaml │ ├── notify-integration-release-via-tag.yaml │ ├── pr-test-lint.yaml │ ├── release.yaml │ ├── spell-check.yaml │ └── test-plugin.yaml ├── .gitignore ├── .golangci.yml ├── .goreleaser.yml ├── .vscode └── settings.json ├── .web-docs ├── README.md ├── components │ └── provisioner │ │ ├── cnspec │ │ └── README.md │ │ └── mondoo │ │ └── README.md ├── metadata.hcl └── scripts │ └── compile-to-webdocs.sh ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── VERSION ├── assets ├── enable_policies.gif ├── github.splash.png ├── service_account.gif └── title.png ├── docs-partials └── provisioner │ ├── Config-not-required.mdx │ └── SudoConfig-not-required.mdx ├── docs ├── README.md └── provisioners │ ├── cnspec.mdx │ └── mondoo.mdx ├── download.sh ├── examples ├── aws │ ├── amazon-linux-2.json │ ├── amazon-linux-2.pkr.hcl │ ├── amazon-linux-2023.pkr.hcl │ ├── ubuntu-18.04.json │ ├── ubuntu-20.04.json │ ├── ubuntu-2004.pkr.hcl │ ├── ubuntu-2204.pkr.hcl │ └── windows-2019.pkr.hcl ├── azure │ ├── README.md │ ├── ubuntu │ │ ├── .gitignore │ │ ├── ubuntu-18.04.json │ │ └── vars.json │ └── windows │ │ ├── variables.pkrvars.hcl │ │ └── windows.pkr.hcl ├── custom-policybundle │ ├── README.md │ ├── custom-policy.mql.yaml │ └── docker-ubuntu.pkr.hcl ├── digitalocean │ ├── centos-7.json │ └── ubuntu-18-04.json ├── docker │ ├── README.md │ └── docker-ubuntu.pkr.hcl ├── gcp │ └── ubuntu2004.pkr.hcl ├── github-actions │ └── packer-build-scan.yaml ├── scripts │ └── bootstrap_win.txt └── vsphere │ ├── centos7 │ ├── README.md │ ├── centos-7-x86_64.vsphere.json │ ├── centos-7-x86_64.vsphere.pkr.hcl │ ├── http │ │ └── kickstart.cfg │ └── scripts │ │ └── prepare.sh │ ├── photon4 │ ├── README.md │ ├── data │ │ └── ks.pkrtpl.hcl │ ├── photon.auto.pkrvars.hcl │ ├── photon.pkr.hcl │ ├── variables.pkr.hcl │ └── variables.pkrvars.hcl │ └── rocky8 │ ├── README.md │ ├── data │ └── ks.pkrtpl.hcl │ ├── rocky-8.auto.pkrvars.hcl │ ├── rocky-8.pkr.hcl │ ├── variables.pkr.hcl │ └── variables.pkrvars.hcl ├── go.mod ├── go.sum ├── main.go ├── provisioner ├── buildinfo.go ├── buildinfo_test.go ├── provisioner.go ├── provisioner.hcl2spec.go ├── sshkey.go └── version │ └── version.go ├── test ├── alpine3.11 │ ├── README.md │ ├── Vagrantfile │ ├── alpine-3.11-x86_64.json │ ├── http │ │ └── answers │ └── scripts │ │ └── prepare.sh ├── hcl-docker │ └── docker-ubuntu.pkr.hcl ├── hcl-virtualbox │ ├── Vagrantfile │ ├── alpine.pkr.hcl │ ├── http │ │ └── answers │ ├── scripts │ │ └── prepare.sh │ └── variables.pkr.hcl ├── hcl-vmware-arm │ ├── alpine.pkr.hcl │ ├── http │ │ └── answers │ ├── scripts │ │ └── prepare.sh │ └── variables.pkr.hcl └── policybundle │ ├── centos-7.json │ └── centos7-policy.yaml └── tools.go /.copywrite.hcl: -------------------------------------------------------------------------------- 1 | schema_version = 1 2 | 3 | project { 4 | license = "BUSL-1.1" 5 | copyright_holder = "Mondoo, Inc." 6 | copyright_year = 2024 7 | 8 | # (OPTIONAL) A list of globs that should not have copyright/license headers. 9 | # Supports doublestar glob patterns for more flexibility in defining which 10 | # files or folders should be ignored 11 | header_ignore = [ 12 | "**/*.tf", 13 | "**/testdata/**", 14 | "**/*.pb.go", 15 | "**/*_string.go", 16 | "**/*pkrtpl.hcl", 17 | "**/.web-docs/**", 18 | ] 19 | } -------------------------------------------------------------------------------- /.github/actions/spelling/README.md: -------------------------------------------------------------------------------- 1 | # check-spelling/check-spelling configuration 2 | 3 | | File | Purpose | Format | Info | 4 | | -------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | 5 | | [allow.txt](allow.txt) | Add words to the dictionary | one word per line (only letters and `'`s allowed) | [allow](https://github.com/check-spelling/check-spelling/wiki/Configuration#allow) | 6 | | [reject.txt](reject.txt) | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | [reject](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-reject) | 7 | | [excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes) | 8 | | [only.txt](only.txt) | Only check matching files (applied after excludes) | perl regular expression | [only](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-only) | 9 | | [patterns.txt](patterns.txt) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns) | 10 | | [line_forbidden.patterns](line_forbidden.patterns) | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns) | 11 | | [expect.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect) | 12 | | [advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice) | 13 | 14 | Note: you can replace any of these files with a directory by the same name (minus the suffix) 15 | and then include multiple files inside that directory (with that suffix) to merge multiple files together. 16 | -------------------------------------------------------------------------------- /.github/actions/spelling/advice.md: -------------------------------------------------------------------------------- 1 | 2 |
If the flagged items are false positives 3 | 4 | If items relate to a ... 5 | 6 | - binary file (or some other file you wouldn't want to check at all). 7 | 8 | Please add a file path to the `excludes.txt` file matching the containing file. 9 | 10 | File paths are Perl 5 Regular Expressions - you can [test](https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files. 11 | 12 | `^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude README.md (on whichever branch you're using). 13 | 14 | - well-formed pattern. 15 | 16 | If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it, 17 | try adding it to the `patterns.txt` file. 18 | 19 | Patterns are Perl 5 Regular Expressions - you can [test](https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines. 20 | 21 | Note that patterns can't match multiline strings. 22 | 23 |
24 | -------------------------------------------------------------------------------- /.github/actions/spelling/allow.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mondoohq/packer-plugin-cnspec/9e780ed9261efaf0b3e31ab20211c27378451b2f/.github/actions/spelling/allow.txt -------------------------------------------------------------------------------- /.github/actions/spelling/excludes.txt: -------------------------------------------------------------------------------- 1 | # See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes 2 | (?:^|/)(?i)COPYRIGHT 3 | (?:^|/)(?i)LICEN[CS]E 4 | (?:^|/)3rdparty/ 5 | (?:^|/)go\.sum$ 6 | (?:^|/)package(?:-lock|)\.json$ 7 | (?:^|/)Pipfile$ 8 | (?:^|/)pyproject.toml 9 | (?:^|/)requirements(?:-dev|-doc|-test|)\.txt$ 10 | (?:^|/)vendor/ 11 | ignore$ 12 | \.a$ 13 | \.ai$ 14 | \.all-contributorsrc$ 15 | \.avi$ 16 | \.bmp$ 17 | \.bz2$ 18 | \.cer$ 19 | \.class$ 20 | \.coveragerc$ 21 | \.crl$ 22 | \.crt$ 23 | \.csr$ 24 | \.dll$ 25 | \.docx?$ 26 | \.drawio$ 27 | \.DS_Store$ 28 | \.eot$ 29 | \.eps$ 30 | \.exe$ 31 | \.gif$ 32 | \.git-blame-ignore-revs$ 33 | \.gitattributes$ 34 | \.gitkeep$ 35 | \.graffle$ 36 | \.gz$ 37 | \.icns$ 38 | \.ico$ 39 | \.ipynb$ 40 | \.jar$ 41 | \.jks$ 42 | \.jpe?g$ 43 | \.key$ 44 | \.lib$ 45 | \.lock$ 46 | \.map$ 47 | \.min\.. 48 | \.mo$ 49 | \.mod$ 50 | \.mp[34]$ 51 | \.o$ 52 | \.ocf$ 53 | \.otf$ 54 | \.p12$ 55 | \.parquet$ 56 | \.pdf$ 57 | \.pem$ 58 | \.pfx$ 59 | \.png$ 60 | \.psd$ 61 | \.pyc$ 62 | \.pylintrc$ 63 | \.qm$ 64 | \.s$ 65 | \.sig$ 66 | \.so$ 67 | \.svgz?$ 68 | \.sys$ 69 | \.tar$ 70 | \.tgz$ 71 | \.tiff?$ 72 | \.ttf$ 73 | \.wav$ 74 | \.webm$ 75 | \.webp$ 76 | \.woff2?$ 77 | \.xcf$ 78 | \.xlsx?$ 79 | \.xpm$ 80 | \.xz$ 81 | \.zip$ 82 | ^\.github/actions/spelling/ 83 | ^\Q.github/workflows/spelling.yml\E$ 84 | -------------------------------------------------------------------------------- /.github/actions/spelling/expect.txt: -------------------------------------------------------------------------------- 1 | tions 2 | pkrvars 3 | pkr 4 | linux 5 | mkpasswd 6 | quickview 7 | testcase 8 | testsuite 9 | classname 10 | acf 11 | bqjbhq 12 | cec 13 | fbf 14 | -------------------------------------------------------------------------------- /.github/actions/spelling/only.txt: -------------------------------------------------------------------------------- 1 | \.md$ 2 | \.mdx$ 3 | -------------------------------------------------------------------------------- /.github/actions/spelling/patterns.txt: -------------------------------------------------------------------------------- 1 | # See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns 2 | 3 | # acceptable duplicates 4 | # ls directory listings 5 | [-bcdlpsw](?:[-r][-w][-sx]){3}\s+\d+\s+(\S+)\s+\g{-1}\s+\d+\s+ 6 | 7 | # Commit message -- Signed-off-by and friends 8 | ^\s*(?:(?:Based-on-patch|Co-authored|Helped|Mentored|Reported|Reviewed|Signed-off)-by|Thanks-to): (?:[^<]*<[^>]*>|[^<]*)\s*$ 9 | 10 | # Autogenerated revert commit message 11 | ^This reverts commit [0-9a-f]{40}\.$ 12 | 13 | # ignore long runs of a single character: 14 | \b([A-Za-z])\g{-1}{3,}\b 15 | 16 | # ignore funky space IDs that blow up spell checking 17 | api\.mondoo\.app\/.*\b 18 | console\.mondoo\.com\/.*\b 19 | 20 | # azure subscription ID 21 | [0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12} 22 | 23 | # azure subscriptions URL 24 | \/subscriptions\/\S* 25 | 26 | # docker container 27 | \b[a-z,0-9]{12}\b 28 | 29 | # URLs in markdown links / images 30 | ]\(.*\) 31 | 32 | # Azure Key Vault Vault. It feels wrong, but it's technically right 33 | Key Vault Vault 34 | 35 | # luna containers in scan output 36 | \bluna/.*\b 37 | 38 | # this comes up in permissions and is valid 39 | \broot root\b 40 | 41 | # AWS resources 42 | (ami|subnet|vpc|sg|fs)-[0-9a-fA-F]{17} 43 | 44 | # http and https URLs 45 | https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*) 46 | 47 | # registry key paths 48 | HKEY_[\w\\]* 49 | 50 | # Container digests 51 | \bsha256:\w* 52 | 53 | # mime types 54 | \bapplication\/\S* 55 | 56 | # mql certificate IDs 57 | certificate:\w* 58 | 59 | # ARN values 60 | \barn:\S* 61 | 62 | # mac user dir path 63 | \/Users\/\S* 64 | 65 | # AWS Token, ID access key, etc 66 | aws_session_token\s+\=(\s+)?.+ 67 | aws_access_key_id\s+\=(\s+)?.+ 68 | aws_secret_access_key\s+\=(\s+)?.+ 69 | 70 | # PGP 71 | \b(?:[0-9A-F]{4} ){9}[0-9A-F]{4}\b 72 | # GPG keys 73 | \b(?:[0-9A-F]{4} ){5}(?: [0-9A-F]{4}){5}\b 74 | 75 | # uuid 76 | \b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b 77 | 78 | # curl arguments 79 | \b(?:\\n|)curl(?:\s+-[a-zA-Z]{1,2}\b)*(?:\s+-[a-zA-Z]{3,})(?:\s+-[a-zA-Z]+)* 80 | 81 | # set arguments 82 | \bset(?:\s+-[abefimouxE]{1,2})*\s+-[abefimouxE]{3,}(?:\s+-[abefimouxE]+)* 83 | 84 | # tar arguments 85 | \b(?:\\n|)g?tar(?:\.exe|)(?:(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+ 86 | 87 | # file permissions 88 | ['"`\s][-bcdLlpsw](?:[-r][-w][-Ssx]){2}[-r][-w][-SsTtx]\+?['"`\s] 89 | 90 | # score score is valid in MQL docs 91 | score score 92 | 93 | # macOS temp folders 94 | /var/folders/\w\w/[+\w]+/(?:T|-Caches-)/ 95 | 96 | # ssh 97 | (?:ssh-\S+|-nistp256) [-a-zA-Z=;:\/0-9+]{12,} 98 | 99 | # kubernetes object suffix 100 | -[0-9a-f]{10}-\w{5}\s 101 | 102 | # sed regular expressions 103 | sed 's/(?:[^/]*?[a-zA-Z]{3,}[^/]*?/){2} 104 | 105 | # UNIX device paths 106 | \/dev\/\w* 107 | 108 | # AWS RDS instance types 109 | db.\w{2}.\w* 110 | 111 | # uuid 112 | [<({"'>][0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}[<'"})>] 113 | 114 | # rsa private keys 115 | MII[BCEJ]\w* 116 | 117 | # UID in MQL policy 118 | - uid: \S* 119 | -------------------------------------------------------------------------------- /.github/actions/spelling/reject.txt: -------------------------------------------------------------------------------- 1 | ad-hoc 2 | ^attache$ 3 | ^bellow$ 4 | benefitting 5 | occurences? 6 | ^dependan.* 7 | ^oer$ 8 | Sorce 9 | ^[Ss]pae.* 10 | ^untill$ 11 | ^untilling$ 12 | ^wether.* 13 | \w*(?> $GITHUB_ENV 36 | - name: Set Version (Repository Dispatch) 37 | if: github.event_name == 'repository_dispatch' 38 | run: | 39 | echo VERSION=${{ github.event.client_payload.version }} >> $GITHUB_ENV 40 | - name: Unified Version 41 | id: version 42 | run: | 43 | echo "Version: $VERSION" 44 | echo "version=${VERSION}" >> $GITHUB_OUTPUT 45 | 46 | - name: Import environment variables from file 47 | run: cat ".github/env" >> $GITHUB_ENV 48 | - name: Install Go 49 | uses: actions/setup-go@v5.5.0 50 | with: 51 | go-version: ">=${{ env.golang-version }}" 52 | cache: false 53 | - name: Bump cnspec 54 | run: | 55 | MAJOR=$(echo "${{ steps.version.outputs.version }}" | cut -d. -f1) 56 | go get go.mondoo.com/cnspec/${MAJOR}@${{ steps.version.outputs.version }} 57 | go mod tidy 58 | echo "${{ steps.version.outputs.version }}" > VERSION 59 | 60 | - name: Prepare title and branch name 61 | id: branch 62 | run: | 63 | BRANCH_NAME="version/cnspec_update_${{ steps.version.outputs.version }}" 64 | COMMIT_MSG="🧹 Bump cnspec to ${{ steps.version.outputs.version }}" 65 | echo "COMMIT_TITLE=${COMMIT_MSG}" >> $GITHUB_OUTPUT 66 | echo "BRANCH_NAME=${BRANCH_NAME}" >> $GITHUB_OUTPUT 67 | 68 | - name: Create PR 69 | id: cpr 70 | uses: peter-evans/create-pull-request@v7 71 | with: 72 | base: main 73 | labels: dependencies,go 74 | committer: "Mondoo Tools " 75 | commit-message: ${{ steps.branch.outputs.COMMIT_TITLE }} 76 | author: "Mondoo Tools " 77 | title: ${{ steps.branch.outputs.COMMIT_TITLE }} 78 | branch: ${{ steps.branch.outputs.BRANCH_NAME }} 79 | body-path: .github/pr-body.md 80 | 81 | - name: PR infos 82 | if: ${{ steps.cpr.outputs.pull-request-number }} 83 | run: | 84 | echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" 85 | echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" 86 | 87 | 88 | -------------------------------------------------------------------------------- /.github/workflows/ensure-generated.yaml: -------------------------------------------------------------------------------- 1 | name: Ensure Code is generated and Docs are compiled 2 | on: 3 | push: 4 | jobs: 5 | ensure-generate: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Checkout 9 | uses: actions/checkout@v4.1.1 10 | with: 11 | ref: ${{ github.ref }} 12 | - name: Import environment variables from file 13 | run: cat ".github/env" >> $GITHUB_ENV 14 | - name: Set up Go 15 | uses: actions/setup-go@v5.5.0 16 | with: 17 | go-version: ">=${{ env.golang-version }}" 18 | cache: false 19 | - run: | 20 | make generate 21 | if [[ -z "$(git status -s)" ]]; then 22 | echo "OK" 23 | else 24 | echo "Docs have been updated, but the compiled docs have not been committed." 25 | echo "Run 'make build-docs', and commit the result to resolve this error." 26 | exit 1 27 | fi 28 | -------------------------------------------------------------------------------- /.github/workflows/gh-release.yaml: -------------------------------------------------------------------------------- 1 | name: Create packer-plugin-cnspec GitHub Release 2 | 3 | ## Only trigger release when the VERSION file changed on main branch 4 | on: 5 | push: 6 | paths: 7 | - "VERSION" 8 | branches: 9 | - main 10 | workflow_dispatch: 11 | 12 | env: 13 | # C07QZDJFF89 == #release-coordination 14 | SLACK_BOT_CHANNEL_ID: "C07QZDJFF89" 15 | 16 | jobs: 17 | create-gh-release: 18 | name: GH Release 19 | permissions: 20 | contents: write 21 | runs-on: ubuntu-latest 22 | steps: 23 | - id: slack 24 | uses: slackapi/slack-github-action@v2.1.0 25 | with: 26 | method: chat.postMessage 27 | token: ${{ secrets.SLACK_BOT_TOKEN }} 28 | payload: | 29 | channel: "${{ env.SLACK_BOT_CHANNEL_ID }}" 30 | text: "GitHub Actions Run" 31 | attachments: 32 | - color: "#FFFF00" 33 | blocks: 34 | - type: "section" 35 | fields: 36 | - type: "mrkdwn" 37 | text: "<${{ github.event.repository.html_url }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }}|${{ github.workflow }}>" 38 | - type: "mrkdwn" 39 | text: "*Status:*\n`In Progress`" 40 | - name: Checkout 41 | uses: actions/checkout@v4 42 | - name: Set release version 43 | run: echo "RELEASE_VERSION=$(cat VERSION)" >> $GITHUB_ENV 44 | # fetch a token for the mondoo-mergebot app 45 | - name: Generate token 46 | id: generate-token 47 | uses: actions/create-github-app-token@v2 48 | with: 49 | app-id: ${{ secrets.MONDOO_MERGEBOT_APP_ID }} 50 | private-key: ${{ secrets.MONDOO_MERGEBOT_APP_PRIVATE_KEY }} 51 | - name: Release 52 | uses: softprops/action-gh-release@v2 53 | with: 54 | tag_name: ${{ env.RELEASE_VERSION }} 55 | generate_release_notes: true 56 | make_latest: true 57 | token: ${{ steps.generate-token.outputs.token }} 58 | - name: Release file present? 59 | id: check_release_file 60 | uses: nick-fields/retry@v3 61 | with: 62 | retry_wait_seconds: 30 63 | timeout_seconds: 5 64 | max_attempts: 120 65 | retry_on: error 66 | warning_on_retry: false 67 | # error on HTTP code different to 302 68 | command: curl -o /dev/null -s -w "%{http_code}\n" "https://github.com/mondoohq/packer-plugin-cnspec/releases/download/${{ env.RELEASE_VERSION }}/packer-plugin-cnspec_${{ env.RELEASE_VERSION }}_SHA256SUMS" | grep 302 69 | - uses: slackapi/slack-github-action@v2.1.0 70 | if : ${{ always() }} 71 | with: 72 | method: chat.update 73 | token: ${{ secrets.SLACK_BOT_TOKEN }} 74 | payload: | 75 | channel: "${{ env.SLACK_BOT_CHANNEL_ID }}" 76 | ts: "${{ steps.slack.outputs.ts }}" 77 | text: "GitHub Actions Run" 78 | attachments: 79 | - color: "${{ (steps.check_release_file.outcome == 'success') && '#00FF00' || (steps.check_release_file.outcome == 'failure') && '#FF0000' || '#FFA500' }}" 80 | blocks: 81 | - type: "section" 82 | fields: 83 | - type: "mrkdwn" 84 | text: "<${{ github.event.repository.html_url }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }}|${{ github.workflow }}>" 85 | - type: "mrkdwn" 86 | text: " " 87 | - type: "mrkdwn" 88 | text: "*Status:*\n`${{ steps.check_release_file.outcome }}`" -------------------------------------------------------------------------------- /.github/workflows/notify-integration-release-via-manual.yaml: -------------------------------------------------------------------------------- 1 | # Manual release workflow is used for deploying documentation updates 2 | # on the specified branch without making an official plugin release. 3 | name: Notify Integration Release (Manual) 4 | on: 5 | workflow_dispatch: 6 | inputs: 7 | version: 8 | description: "The release version (semver)" 9 | default: 1.0.0 10 | required: false 11 | branch: 12 | description: "A branch or SHA" 13 | default: "main" 14 | required: false 15 | jobs: 16 | notify-release: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout this repo 20 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 21 | with: 22 | ref: ${{ github.event.inputs.branch }} 23 | # Ensure that Docs are Compiled 24 | - name: Import environment variables from file 25 | run: cat ".github/env" >> $GITHUB_ENV 26 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.2.0 27 | with: 28 | go-version: ">=${{ env.golang-version }}" 29 | cache: false 30 | - shell: bash 31 | run: make generate 32 | - shell: bash 33 | run: | 34 | if [[ -z "$(git status -s)" ]]; then 35 | echo "OK" 36 | else 37 | echo "Docs have been updated, but the compiled docs have not been committed." 38 | echo "Run 'make generate', and commit the result to resolve this error." 39 | exit 1 40 | fi 41 | # Perform the Release 42 | - name: Checkout integration-release-action 43 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 44 | with: 45 | repository: hashicorp/integration-release-action 46 | path: ./integration-release-action 47 | - name: Notify Release 48 | uses: ./integration-release-action 49 | with: 50 | # The integration identifier will be used by the Packer team to register the integration 51 | # the expected format is packer// 52 | integration_identifier: "packer/mondoohq/cnspec" 53 | release_version: ${{ github.event.inputs.version }} 54 | release_sha: ${{ github.event.inputs.branch }} 55 | github_token: ${{ secrets.GITHUB_TOKEN }} 56 | -------------------------------------------------------------------------------- /.github/workflows/notify-integration-release-via-tag.yaml: -------------------------------------------------------------------------------- 1 | name: Notify Integration Release (Tag) 2 | on: 3 | push: 4 | tags: 5 | - "*.*.*" # Proper releases 6 | jobs: 7 | strip-version: 8 | runs-on: ubuntu-latest 9 | outputs: 10 | packer-version: ${{ steps.strip.outputs.packer-version }} 11 | steps: 12 | - name: Strip leading v from version tag 13 | id: strip 14 | env: 15 | REF: ${{ github.ref_name }} 16 | run: | 17 | echo "packer-version=$(echo "$REF" | sed -E 's/v?([0-9]+\.[0-9]+\.[0-9]+)/\1/')" >> "$GITHUB_OUTPUT" 18 | notify-release: 19 | needs: 20 | - strip-version 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Checkout this repo 24 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 25 | with: 26 | ref: ${{ github.ref }} 27 | # Ensure that Docs are Compiled 28 | - name: Import environment variables from file 29 | run: cat ".github/env" >> $GITHUB_ENV 30 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.2.0 31 | with: 32 | go-version: ">=${{ env.golang-version }}" 33 | cache: false 34 | - shell: bash 35 | run: make generate 36 | - shell: bash 37 | run: | 38 | if [[ -z "$(git status -s)" ]]; then 39 | echo "OK" 40 | else 41 | echo "Docs have been updated, but the compiled docs have not been committed." 42 | echo "Run 'make generate', and commit the result to resolve this error." 43 | exit 1 44 | fi 45 | # Perform the Release 46 | - name: Checkout integration-release-action 47 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 48 | with: 49 | repository: hashicorp/integration-release-action 50 | path: ./integration-release-action 51 | - name: Notify Release 52 | uses: ./integration-release-action 53 | with: 54 | # The integration identifier will be used by the Packer team to register the integration 55 | # the expected format is packer// 56 | integration_identifier: "packer/mondoohq/cnspec" 57 | release_version: ${{ needs.strip-version.outputs.packer-version }} 58 | release_sha: ${{ github.ref }} 59 | github_token: ${{ secrets.GITHUB_TOKEN }} 60 | -------------------------------------------------------------------------------- /.github/workflows/pr-test-lint.yaml: -------------------------------------------------------------------------------- 1 | name: Build Packer Plugin 2 | 3 | ## Only trigger tests if source is changing 4 | on: 5 | push: 6 | paths: 7 | - "**.go" 8 | - "**.mod" 9 | - "go.sum" 10 | 11 | jobs: 12 | license-check: 13 | name: License Check 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@v4.1.1 18 | 19 | - name: Setup Copywrite 20 | uses: hashicorp/setup-copywrite@v1.1.3 21 | 22 | - name: Check Header Compliance 23 | run: copywrite headers --plan 24 | 25 | goreleaser: 26 | name: GoReleaser 27 | runs-on: self-hosted 28 | env: 29 | RUNNER_TYPE: "self-hosted" 30 | timeout-minutes: 120 31 | steps: 32 | - name: Checkout 33 | uses: actions/checkout@v4.1.1 34 | - name: Unshallow 35 | run: git fetch --prune --unshallow 36 | - name: Import environment variables from file 37 | run: cat ".github/env" >> $GITHUB_ENV 38 | - name: Set up Go 39 | uses: actions/setup-go@v5.5.0 40 | with: 41 | go-version: ">=${{ env.golang-version }}" 42 | cache: false 43 | - name: Check go mod 44 | run: | 45 | go mod tidy 46 | git diff --exit-code go.mod 47 | 48 | - name: Run golangci-lint 49 | uses: golangci/golangci-lint-action@v8.0.0 50 | with: 51 | version: latest 52 | skip-cache: true 53 | 54 | - name: "Install required tooling" 55 | if: ${{ env.RUNNER_TYPE != 'self-hosted' }} 56 | run: | 57 | # Only use sudo on self-hosted runners 58 | sudo apt install -y zip 59 | - name: Set cnspec version 60 | run: echo "CNSPEC_VERSION=$(go list -json -m go.mondoo.com/cnspec/v11 | jq -r '.Version')" >> $GITHUB_ENV 61 | - name: Run GoReleaser 62 | uses: goreleaser/goreleaser-action@v6 63 | with: 64 | version: latest 65 | args: release --snapshot --skip=publish --clean 66 | env: 67 | API_VERSION: x5.0 68 | CNSPEC_VERSION: ${{ env.CNSPEC_VERSION }} 69 | 70 | go-auto-approve: 71 | runs-on: ubuntu-latest 72 | needs: [goreleaser, license-check] 73 | # For now, we only auto approve and merge cnspec bump PRs created by mondoo-tools. 74 | # We have to check the commit author, because the PR is created by "github-actions[bot]" 75 | # https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/evaluate-expressions-in-workflows-and-actions#startswith 76 | if: ${{ startsWith(github.ref, 'refs/heads/version/cnspec_update_v') && github.event.commits[0].author.username == 'mondoo-tools' }} 77 | permissions: 78 | contents: write 79 | pull-requests: write 80 | steps: 81 | - name: Checkout 82 | uses: actions/checkout@v4 83 | # figure out the PR for this commit 84 | - uses: cloudposse-github-actions/get-pr@v2.0.0 85 | id: pr 86 | with: 87 | github-token: "${{ secrets.GITHUB_TOKEN }}" 88 | filterOutClosed: true 89 | filterOutDraft: true 90 | # fetch a token for the mondoo-mergebot app 91 | - name: Generate token 92 | id: generate-token 93 | uses: actions/create-github-app-token@v2 94 | with: 95 | app-id: ${{ secrets.MONDOO_MERGEBOT_APP_ID }} 96 | private-key: ${{ secrets.MONDOO_MERGEBOT_APP_PRIVATE_KEY }} 97 | # automerge using bot token 98 | - name: Approve and merge a PR 99 | run: | 100 | gh pr review ${{ steps.pr.outputs.number }} --approve 101 | gh pr merge ${{ steps.pr.outputs.number }} --squash 102 | env: 103 | GH_TOKEN: ${{ steps.generate-token.outputs.token }} 104 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Release Packer Plugin 2 | 3 | on: 4 | push: 5 | tags: 6 | - "*" 7 | workflow_dispatch: 8 | 9 | jobs: 10 | goreleaser: 11 | runs-on: self-hosted 12 | env: 13 | RUNNER_TYPE: "self-hosted" 14 | timeout-minutes: 120 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4.1.1 18 | - name: Unshallow 19 | run: git fetch --prune --unshallow 20 | - name: Import environment variables from file 21 | run: cat ".github/env" >> $GITHUB_ENV 22 | - name: Set up Go 23 | uses: actions/setup-go@v5.5.0 24 | with: 25 | go-version: ">=${{ env.golang-version }}" 26 | cache: false 27 | - name: Set cnspec version 28 | run: echo "CNSPEC_VERSION=$(go list -json -m go.mondoo.com/cnspec/v11 | jq -r '.Version')" >> $GITHUB_ENV 29 | - name: Run GoReleaser 30 | uses: goreleaser/goreleaser-action@v6 31 | with: 32 | version: latest 33 | args: release --clean --timeout 120m 34 | env: 35 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 36 | API_VERSION: x5.0 37 | CNSPEC_VERSION: ${{ env.CNSPEC_VERSION }} 38 | - name: Install Github CLI (gh) 39 | if: ${{ env.RUNNER_TYPE != 'self-hosted' }} 40 | run: | 41 | # For shared runners we install gh, for private runners its already installed 42 | wget https://github.com/cli/cli/releases/download/v2.20.2/gh_2.20.2_linux_amd64.deb 43 | dpkg -i gh_2.20.2_linux_amd64.deb 44 | - name: Duplicate Shasum 45 | env: 46 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 47 | run: | 48 | gh release download ${{github.ref_name}} --pattern '*_SHA256SUMS' 49 | mv packer-plugin-cnspec_${{github.ref_name}}_SHA256SUMS packer-plugin-mondoo_${{github.ref_name}}_SHA256SUMS 50 | gh release upload ${{github.ref_name}} packer-plugin-mondoo_${{github.ref_name}}_SHA256SUMS 51 | -------------------------------------------------------------------------------- /.github/workflows/spell-check.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Spell Checking 3 | 4 | on: 5 | pull_request: 6 | types: [opened, reopened, synchronize] 7 | 8 | jobs: 9 | spelling: 10 | name: Run spell check 11 | permissions: 12 | contents: read 13 | pull-requests: read 14 | actions: read 15 | outputs: 16 | followup: ${{ steps.spelling.outputs.followup }} 17 | runs-on: ubuntu-latest 18 | if: "contains(github.event_name, 'pull_request') || github.event_name == 'push'" 19 | concurrency: 20 | group: spelling-${{ github.event.pull_request.number || github.ref }} 21 | # note: If you use only_check_changed_files, you do not want cancel-in-progress 22 | cancel-in-progress: true 23 | steps: 24 | - name: check-spelling 25 | id: spelling 26 | uses: check-spelling/check-spelling@v0.0.25 27 | with: 28 | disable_checks: noisy-file 29 | suppress_push_for_open_pull_request: 1 30 | checkout: true 31 | post_comment: 0 32 | dictionary_source_prefixes: '{"mondoo": "https://raw.githubusercontent.com/mondoohq/spellcheck-dictionary/main/", "cspell": "https://raw.githubusercontent.com/check-spelling/cspell-dicts/v20230509/dictionaries/"}' 33 | extra_dictionaries: cspell:aws/aws.txt 34 | cspell:filetypes/filetypes.txt 35 | cspell:software-terms/src/software-terms.txt 36 | cspell:software-terms/src/software-tools.txt 37 | cspell:companies/src/companies.txt 38 | mondoo:mondoo_dictionary.txt 39 | 40 | comment: 41 | name: Report 42 | runs-on: ubuntu-latest 43 | needs: spelling 44 | permissions: 45 | contents: write 46 | pull-requests: write 47 | if: (success() || failure()) && needs.spelling.outputs.followup 48 | steps: 49 | - name: comment 50 | uses: check-spelling/check-spelling@v0.0.25 51 | with: 52 | checkout: true 53 | task: ${{ needs.spelling.outputs.followup }} 54 | -------------------------------------------------------------------------------- /.github/workflows/test-plugin.yaml: -------------------------------------------------------------------------------- 1 | # This is a manually triggered action workflow. 2 | # It uses Packer at latest version to init, validate and build 3 | # an example configuration in a folder. 4 | # This action is compatible with Packer v1.7.0 or later. 5 | name: test plugin example 6 | 7 | on: 8 | workflow_dispatch: 9 | inputs: 10 | logs: 11 | description: "Set 1 to activate full logs" 12 | required: false 13 | default: "0" 14 | folder: 15 | description: "AWS folder" 16 | required: false 17 | default: "./examples/packer-aws" 18 | 19 | jobs: 20 | build: 21 | runs-on: ubuntu-latest 22 | name: init and build example 23 | steps: 24 | - name: Checkout Repository 25 | uses: actions/checkout@v4.1.1 26 | 27 | - name: Init 28 | uses: hashicorp/packer-github-actions@master 29 | with: 30 | working_directory: ${{ github.event.inputs.folder }} 31 | command: init 32 | 33 | - name: Validate 34 | uses: hashicorp/packer-github-actions@master 35 | with: 36 | working_directory: ${{ github.event.inputs.folder }} 37 | command: validate 38 | env: 39 | PACKER_LOG: ${{ github.event.inputs.logs }} 40 | 41 | - name: Build 42 | uses: hashicorp/packer-github-actions@master 43 | with: 44 | working_directory: ${{ github.event.inputs.folder }} 45 | command: build 46 | env: 47 | PACKER_LOG: ${{ github.event.inputs.logs }} 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | vendor 3 | packer_cache 4 | output.box 5 | test/alpine3.11/output-virtualbox-iso 6 | .vscode/*.log 7 | main 8 | dist/* 9 | docs-rendered/* 10 | packer-plugin-mondoo 11 | packer-plugin-cnspec 12 | .docs 13 | centos-7-x86_64.vsphere.local.json 14 | examples/*/*/manifests/* 15 | examples/*/*/artifacts/* -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | # See https://golangci-lint.run/usage/configuration/ for configuration options 5 | version: "2" 6 | run: 7 | modules-download-mode: readonly 8 | linters: 9 | exclusions: 10 | paths: 11 | - .*\.pb\.go$ 12 | - .*\.lr\.go$ 13 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | --- 5 | version: 2 6 | env: 7 | - CGO_ENABLED=0 8 | before: 9 | hooks: 10 | - go mod download 11 | - make generate 12 | # Check plugin compatibility with required version of the Packer SDK 13 | - make plugin-check 14 | builds: 15 | # building the new packer-plugin-cnspec 16 | - id: packer-plugin-cnspec-linux 17 | binary: 'packer-plugin-cnspec_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}' 18 | goos: 19 | - linux 20 | goarch: 21 | - amd64 22 | - '386' 23 | - arm64 24 | - arm 25 | ldflags: 26 | - -s -w -X go.mondoo.com/cnquery/v10.Version={{ .Env.CNSPEC_VERSION }} -X go.mondoo.com/packer-plugin-cnspec/provisioner/version.Version={{.Version}} -X go.mondoo.com/packer-plugin-cnspec/provisioner/version.Build={{.ShortCommit}} -X go.mondoo.com/packer-plugin-cnspec/provisioner/version.Date={{.Date}} 27 | - id: packer-plugin-cnspec-windows 28 | binary: 'packer-plugin-cnspec_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}' 29 | goos: 30 | - windows 31 | goarch: 32 | - amd64 33 | - arm64 34 | ldflags: 35 | - -s -w -X go.mondoo.com/cnquery/v10.Version={{ .Env.CNSPEC_VERSION }} -X go.mondoo.com/packer-plugin-cnspec/provisioner/version.Version={{.Version}} -X go.mondoo.com/packer-plugin-cnspec/provisioner/version.Build={{.ShortCommit}} -X go.mondoo.com/packer-plugin-cnspec/provisioner/version.Date={{.Date}} 36 | - id: packer-plugin-cnspec-darwin 37 | binary: 'packer-plugin-cnspec_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}' 38 | goos: 39 | - darwin 40 | goarch: 41 | - amd64 42 | - arm64 43 | ldflags: 44 | - -s -w -X go.mondoo.com/cnquery/v10.Version={{ .Env.CNSPEC_VERSION }} -X go.mondoo.com/packer-plugin-cnspec/provisioner/version.Version={{.Version}} -X go.mondoo.com/packer-plugin-cnspec/provisioner/version.Build={{.ShortCommit}} -X go.mondoo.com/packer-plugin-cnspec/provisioner/version.Date={{.Date}} 45 | 46 | # building fall-back binaries 47 | - id: packer-plugin-mondoo 48 | binary: 'packer-plugin-mondoo_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}' 49 | goos: 50 | - darwin 51 | - linux 52 | - windows 53 | goarch: 54 | - amd64 55 | - arm64 56 | ldflags: 57 | - -s -w -X go.mondoo.com/packer-plugin-cnspec/provisioner/version.Version={{.Version}} -X go.mondoo.com/packer-plugin-cnspec/provisioner/version.Build={{.ShortCommit}} -X go.mondoo.com/packer-plugin-cnspec/provisioner/version.Date={{.Date}} 58 | 59 | archives: 60 | - id: releases-packer-plugin-cnspec 61 | builds: 62 | - packer-plugin-cnspec-linux 63 | - packer-plugin-cnspec-windows 64 | - packer-plugin-cnspec-darwin 65 | name_template: 'packer-plugin-cnspec_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}' 66 | format: zip 67 | files: 68 | - none* 69 | - id: releases-packer-plugin-mondoo 70 | builds: 71 | - packer-plugin-mondoo 72 | name_template: 'packer-plugin-mondoo_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}' 73 | format: zip 74 | files: 75 | - none* 76 | checksum: 77 | name_template: 'packer-plugin-cnspec_v{{ .Version }}_SHA256SUMS' 78 | algorithm: sha256 79 | snapshot: 80 | name_template: "{{ .Tag }}-snapshot" 81 | 82 | changelog: 83 | use: github-native 84 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 2, 3 | "editor.insertSpaces": true 4 | } -------------------------------------------------------------------------------- /.web-docs/README.md: -------------------------------------------------------------------------------- 1 | Packer plugin [cnspec](https://github.com/mondoohq/cnspec) by [Mondoo](https://mondoo.com) scans Linux and Windows [HashiCorp Packer](https://www.packer.io) builds for vulnerabilities and security misconfigurations. The plugin retrieves CVE data from Mondoo, which is updated daily with the latest CVEs and advisories. Additionally, cnspec runs security scans using [cnspec-policies](https://github.com/mondoohq/cnspec-policies) to uncover common misconfigurations that open your hosts to the risk of attack. cnspec supports scanning of Linux, Windows, and macOS, as well as Docker containers. 2 | 3 | Packer plugin cnspec is designed to work in one of two modes: 4 | 5 | - **Unregistered** - In unregistered mode, the plugin works without being registered to Mondoo Platform, and is designed to provide baseline security scanning with minimal configuration. The plugin runs either the [Linux Security by Mondoo](https://github.com/mondoohq/cnspec-policies/blob/main/core/mondoo-linux-security.mql.yaml) policy on Linux builds, or the [Windows Security by Mondoo](https://github.com/mondoohq/cnspec-policies/blob/main/core/mondoo-windows-security.mql.yaml) policy on Windows builds. Each of these policies provides security hardening checks based off of industry standards for Linux and Windows. Scan results are shown in STDOUT during the Packer run. 6 | - **Registered** - In registered mode, the plugin is registered to your account in Mondoo Platform using a service account. Registered mode allows you to configure and customize any of the policies in Mondoo Platform including CIS benchmarks and more. Scan results are shown in STDOUT and sent back to Mondoo Platform for your records. 7 | 8 | ### Installation 9 | 10 | To install this plugin, copy and paste this code into your Packer configuration, then run [`packer init`](https://www.packer.io/docs/commands/init). 11 | 12 | ```hcl 13 | packer { 14 | required_plugins { 15 | cnspec = { 16 | version = ">= 10.0.0" 17 | source = "github.com/mondoohq/cnspec" 18 | } 19 | } 20 | } 21 | ``` 22 | 23 | Alternatively, you can use `packer plugins install` to manage installation of this plugin. 24 | 25 | ```sh 26 | $ packer plugins install github.com/mondoohq/cnspec 27 | ``` 28 | 29 | ### Components 30 | 31 | #### Provisioners 32 | 33 | - [cnspec](/packer/integrations/mondoohq/cnspec/latest/components/provisioner/cnspec) - Packer plugin [cnspec](https://github.com/mondoohq/cnspec) by [Mondoo](https://mondoo.com) scans 34 | Linux and Windows machine images for vulnerabilities and security misconfigurations. The plugin retrieves CVE data from Mondoo, which is updated daily with the latest CVEs and advisories. Additionally, cnspec runs policy-as-code security scans using [cnspec-policies](https://github.com/mondoohq/cnspec-policies) to uncover common misconfigurations that open your hosts to the risk of attack. 35 | - [mondoo](/packer/integrations/mondoohq/cnspec/latest/components/provisioner/mondoo) - Deprecated. Use the `cnspec` provisioner instead. 36 | 37 | ### Tutorials 38 | 39 | Check out the Packer tutorials on the Mondoo documentation site: 40 | 41 | - [Building secure AMIs with Mondoo and Packer](https://mondoo.com/docs/cnspec/cnspec-aws/cnspec-aws-packer/) 42 | - [Building secure VM images in Google Cloud with cnspec and HashiCorp Packer](https://mondoo.com/docs/cnspec/cnspec-gcp/cnspec-gcp-packer/) 43 | 44 | -------------------------------------------------------------------------------- /.web-docs/components/provisioner/cnspec/README.md: -------------------------------------------------------------------------------- 1 | Type: `cnspec` 2 | 3 | Packer plugin [cnspec](https://github.com/mondoohq/cnspec) by [Mondoo](https://mondoo.com) scans Linux and Windows machine images for vulnerabilities and security misconfigurations. The plugin retrieves CVE data from Mondoo, which is updated daily with the latest CVEs and advisories. Additionally, cnspec runs security scans using [cnspec-policies](https://github.com/mondoohq/cnspec-policies) to uncover common misconfigurations that open your hosts to the risk of attack. 4 | 5 | ## Basic Example 6 | 7 | ```hcl 8 | provisioner "cnspec" { 9 | on_failure = "continue" 10 | score_threshold = 85 11 | sudo { 12 | active = true 13 | } 14 | } 15 | ``` 16 | 17 | The following configuration shows how to set the output format to JUnit and the output target to `test-results.xml`: 18 | 19 | ```hcl 20 | provisioner "cnspec" { 21 | on_failure = "continue" 22 | output = "junit" 23 | output_target = "test-results.xml" 24 | } 25 | ``` 26 | 27 | ## Configuration Reference 28 | 29 | Optional Parameters: 30 | 31 | 32 | - `host_alias` (string) - The alias by which the host should be known. 33 | Defaults to `default`. 34 | 35 | - `user` (string) - The `user` set for your communicator. Defaults to the `user` set 36 | by packer. 37 | 38 | - `local_port` (uint) - The port on which to attempt to listen for SSH 39 | connections. This value is a starting point. The provisioner will attempt 40 | listen for SSH connections on the first available of ten ports, starting at 41 | `local_port`. A system-chosen port is used when `local_port` is missing or 42 | empty. 43 | 44 | - `ssh_host_key_file` (string) - The SSH key that will be used to run the SSH 45 | server on the host machine to forward commands to the target machine. 46 | packer connects to this server and will validate the identity of the 47 | server using the system known_hosts. The default behavior is to generate 48 | and use a onetime key. 49 | 50 | - `ssh_authorized_key_file` (string) - The SSH public key of the packer `ssh_user`. 51 | The default behavior is to generate and use a onetime key. 52 | 53 | - `use_sftp` (bool) - Deprecated: SFTP is now the default. To use SCP instead, set use_scp to true 54 | 55 | - `use_scp` (bool) - Use SCP instead of SFTP. By default, SFTP is used since 56 | SCP communication can fail on Windows 2025 and SSH systems. 57 | 58 | - `debug` (bool) - Sets the log level to `DEBUG` 59 | 60 | - `asset_name` (string) - The asset name passed to Mondoo Platform. Defaults to the hostname 61 | of the instance. 62 | 63 | - `on_failure` (string) - Configure behavior whether packer should fail if `scan_threshold` is 64 | not met. If `scan_threshold` configuration is omitted, the threshold 65 | is set to `0` and builds will pass regardless of what score is 66 | returned. 67 | If `score_threshold` is set to a value, and `on_failure = "continue"` 68 | builds will continue regardless of what score is returned. 69 | 70 | - `labels` (map[string]string) - Configure an optional map of `key/val` labels for the asset in 71 | Mondoo Platform. 72 | 73 | - `annotations` (map[string]string) - Configure an optional map of `key/val` annotations for the asset in 74 | Mondoo Platform. 75 | 76 | - `incognito` (bool) - Configures incognito mode. By default it detects if a Mondoo service account 77 | is available. When set to false, scan results will not be sent to 78 | Mondoo Platform. 79 | 80 | - `policies` ([]string) - A list of policies to be executed (will automatically activate incognito mode). 81 | 82 | - `policybundle` (string) - A path to local policy bundle file. 83 | 84 | - `sudo` (\*SudoConfig) - Runs scan with `--sudo`. Defaults to none. 85 | 86 | - `winrm_user` (string) - Configure WinRM user. Defaults to `user` set by the packer communicator. 87 | 88 | - `winrm_password` (string) - Configure WinRM user password. Defaults to `password` set by the packer 89 | communicator. 90 | 91 | - `use_proxy` (bool) - Use proxy to connect to host to scan. This configuration will fall-back to 92 | packer proxy for cases where the provisioner cannot access the target directly 93 | 94 | - `output` (string) - Set output format: compact, csv, full, json, junit, report, summary, yaml 95 | (default "compact") 96 | 97 | - `output_target` (string) - Set output target. E.g. path to local file 98 | 99 | - `score_threshold` (int) - An integer value to set the `score_threshold` of mondoo scans. Defaults to 100 | `0` which results in a passing score regardless of what scan results are 101 | returned. 102 | 103 | - `mondoo_config_path` (string) - The path to the Mondoo's service account. Defaults to 104 | `$HOME/.config/mondoo/mondoo.yml` 105 | 106 | 107 | 108 | 109 | ### SudoConfig 110 | 111 | 112 | - `active` (bool) - Active 113 | 114 | 115 | 116 | 117 | ## Get Started with cnspec 118 | 119 | If you are new to cnspec, check out [Get started with cnspec](https://mondoo.com/docs/cnspec/). 120 | 121 | ## Packer plugin cnspec tutorial 122 | 123 | Check out the Packer tutorials on the Mondoo documentation site: 124 | 125 | - [Building secure AMIs with Mondoo and Packer](https://mondoo.com/docs/cnspec/cnspec-aws/cnspec-aws-packer/) 126 | - [Building secure VM images in Google Cloud with cnspec and HashiCorp Packer](https://mondoo.com/docs/cnspec/cnspec-gcp/cnspec-gcp-packer/) 127 | 128 | ## Sample Packer Templates 129 | 130 | You can find example Packer templates in the [examples](https://github.com/mondoohq/packer-plugin-cnspec/tree/main/examples) directory in this repository. 131 | -------------------------------------------------------------------------------- /.web-docs/components/provisioner/mondoo/README.md: -------------------------------------------------------------------------------- 1 | Type: `mondoo` 2 | 3 | > [!WARNING] 4 | > This plugin has been deprecated. Migrate to [Packer plugin cnspec by Mondoo](https://developer.hashicorp.com/packer/plugins/provisioner/mondoo/cnspec) for even easier security scanning of your Packer builds. 5 | 6 | The `mondoo` provisioner scans [Packer](https://www.packer.io) builds for vulnerabilities and misconfigurations by executing security 7 | policy-as-code enabled in [Mondoo Platform](https://console.mondoo.com). Mondoo Platform comes stocked with an ever-increasing collection of 8 | certified security policies which can be easily customize to meet your needs. 9 | 10 | Mondoo supports scanning of Linux, Windows, and macOS, as well as Docker containers. 11 | 12 | ## Basic Example 13 | ```hcl 14 | provisioner "mondoo" { 15 | on_failure = "continue" 16 | mondoo_config_path = "/etc/mondoo-config.json" 17 | score_threshold = 85 18 | asset_name = "example-secure-base-image" 19 | sudo { 20 | active = true 21 | } 22 | 23 | annotations = { 24 | Source_AMI = "{{ .SourceAMI }}" 25 | Creation_Date = "{{ .SourceAMICreationDate }}" 26 | } 27 | } 28 | } 29 | ``` 30 | 31 | ## Configuration Reference 32 | 33 | Optional Parameters: 34 | 35 | 36 | - `host_alias` (string) - The alias by which the host should be known. 37 | Defaults to `default`. 38 | 39 | - `user` (string) - The `user` set for your communicator. Defaults to the `user` set 40 | by packer. 41 | 42 | - `local_port` (uint) - The port on which to attempt to listen for SSH 43 | connections. This value is a starting point. The provisioner will attempt 44 | listen for SSH connections on the first available of ten ports, starting at 45 | `local_port`. A system-chosen port is used when `local_port` is missing or 46 | empty. 47 | 48 | - `ssh_host_key_file` (string) - The SSH key that will be used to run the SSH 49 | server on the host machine to forward commands to the target machine. 50 | packer connects to this server and will validate the identity of the 51 | server using the system known_hosts. The default behavior is to generate 52 | and use a onetime key. 53 | 54 | - `ssh_authorized_key_file` (string) - The SSH public key of the packer `ssh_user`. 55 | The default behavior is to generate and use a onetime key. 56 | 57 | - `use_sftp` (bool) - Deprecated: SFTP is now the default. To use SCP instead, set use_scp to true 58 | 59 | - `use_scp` (bool) - Use SCP instead of SFTP. By default, SFTP is used since 60 | SCP communication can fail on Windows 2025 and SSH systems. 61 | 62 | - `debug` (bool) - Sets the log level to `DEBUG` 63 | 64 | - `asset_name` (string) - The asset name passed to Mondoo Platform. Defaults to the hostname 65 | of the instance. 66 | 67 | - `on_failure` (string) - Configure behavior whether packer should fail if `scan_threshold` is 68 | not met. If `scan_threshold` configuration is omitted, the threshold 69 | is set to `0` and builds will pass regardless of what score is 70 | returned. 71 | If `score_threshold` is set to a value, and `on_failure = "continue"` 72 | builds will continue regardless of what score is returned. 73 | 74 | - `labels` (map[string]string) - Configure an optional map of `key/val` labels for the asset in 75 | Mondoo Platform. 76 | 77 | - `annotations` (map[string]string) - Configure an optional map of `key/val` annotations for the asset in 78 | Mondoo Platform. 79 | 80 | - `incognito` (bool) - Configures incognito mode. By default it detects if a Mondoo service account 81 | is available. When set to false, scan results will not be sent to 82 | Mondoo Platform. 83 | 84 | - `policies` ([]string) - A list of policies to be executed (will automatically activate incognito mode). 85 | 86 | - `policybundle` (string) - A path to local policy bundle file. 87 | 88 | - `sudo` (\*SudoConfig) - Runs scan with `--sudo`. Defaults to none. 89 | 90 | - `winrm_user` (string) - Configure WinRM user. Defaults to `user` set by the packer communicator. 91 | 92 | - `winrm_password` (string) - Configure WinRM user password. Defaults to `password` set by the packer 93 | communicator. 94 | 95 | - `use_proxy` (bool) - Use proxy to connect to host to scan. This configuration will fall-back to 96 | packer proxy for cases where the provisioner cannot access the target directly 97 | 98 | - `output` (string) - Set output format: compact, csv, full, json, junit, report, summary, yaml 99 | (default "compact") 100 | 101 | - `output_target` (string) - Set output target. E.g. path to local file 102 | 103 | - `score_threshold` (int) - An integer value to set the `score_threshold` of mondoo scans. Defaults to 104 | `0` which results in a passing score regardless of what scan results are 105 | returned. 106 | 107 | - `mondoo_config_path` (string) - The path to the Mondoo's service account. Defaults to 108 | `$HOME/.config/mondoo/mondoo.yml` 109 | 110 | 111 | 112 | 113 | ### SudoConfig 114 | 115 | 116 | - `active` (bool) - Active 117 | 118 | 119 | 120 | 121 | ## Get Started with Mondoo 122 | 123 | If you are new to Mondoo you can get started by [signing up for a free account](https://mondoo.com/docs/tutorials/mondoo/account-setup/) today! 124 | 125 | Check out the Packer tutorials on the Mondoo documentation site: 126 | 127 | - [Building secure AMIs with Mondoo and Packer](https://mondoo.com/docs/cnspec/cnspec-aws/cnspec-aws-packer/) 128 | - [Building secure VM images in Google Cloud with cnspec and HashiCorp Packer](https://mondoo.com/docs/cnspec/cnspec-gcp/cnspec-gcp-packer/) 129 | 130 | ## Sample Packer Templates 131 | 132 | You can find example Packer templates in the [examples](https://github.com/mondoohq/packer-plugin-cnspec/tree/main/examples) directory in this repository. 133 | -------------------------------------------------------------------------------- /.web-docs/metadata.hcl: -------------------------------------------------------------------------------- 1 | # For full specification on the configuration of this file visit: 2 | # https://github.com/hashicorp/integration-template#metadata-configuration 3 | integration { 4 | name = "Mondoo" 5 | description = "Scans Linux and Windows HashiCorp Packer builds for vulnerabilities and security misconfigurations." 6 | identifier = "packer/mondoohq/cnspec" 7 | component { 8 | type = "provisioner" 9 | name = "Mondoo" 10 | slug = "mondoo" 11 | } 12 | component { 13 | type = "provisioner" 14 | name = "cnspec" 15 | slug = "cnspec" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.web-docs/scripts/compile-to-webdocs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Converts the folder name that the component documentation file 4 | # is stored in into the integration slug of the component. 5 | componentTypeFromFolderName() { 6 | if [[ "$1" = "builders" ]]; then 7 | echo "builder" 8 | elif [[ "$1" = "provisioners" ]]; then 9 | echo "provisioner" 10 | elif [[ "$1" = "post-processors" ]]; then 11 | echo "post-processor" 12 | elif [[ "$1" = "datasources" ]]; then 13 | echo "data-source" 14 | else 15 | echo "" 16 | fi 17 | } 18 | 19 | # $1: The content to adjust links 20 | # $2: The organization of the integration 21 | rewriteLinks() { 22 | local result="$1" 23 | local organization="$2" 24 | 25 | urlSegment="([^/]+)" 26 | urlAnchor="(#[^/]+)" 27 | 28 | # Rewrite Component Index Page links to the Integration root page. 29 | # 30 | # (\1) (\2) (\3) 31 | # /packer/plugins/datasources/amazon#anchor-tag--> 32 | # /packer/integrations/hashicorp/amazon#anchor-tag 33 | local find="\(\/packer\/plugins\/$urlSegment\/$urlSegment$urlAnchor?\)" 34 | local replace="\(\/packer\/integrations\/$organization\/\2\3\)" 35 | result="$(echo "$result" | sed -E "s/$find/$replace/g")" 36 | 37 | 38 | # Rewrite Component links to the Integration component page 39 | # 40 | # (\1) (\2) (\3) (\4) 41 | # /packer/plugins/datasources/amazon/parameterstore#anchor-tag --> 42 | # /packer/integrations/{organization}/amazon/latest/components/datasources/parameterstore 43 | local find="\(\/packer\/plugins\/$urlSegment\/$urlSegment\/$urlSegment$urlAnchor?\)" 44 | local replace="\(\/packer\/integrations\/$organization\/\2\/latest\/components\/\1\/\3\4\)" 45 | result="$(echo "$result" | sed -E "s/$find/$replace/g")" 46 | 47 | # Rewrite the Component URL segment from the Packer Plugin format 48 | # to the Integrations format 49 | result="$(echo "$result" \ 50 | | sed "s/\/datasources\//\/data-source\//g" \ 51 | | sed "s/\/builders\//\/builder\//g" \ 52 | | sed "s/\/post-processors\//\/post-processor\//g" \ 53 | | sed "s/\/provisioners\//\/provisioner\//g" \ 54 | )" 55 | 56 | echo "$result" 57 | } 58 | 59 | # $1: Docs Dir 60 | # $2: Web Docs Dir 61 | # $3: Component File 62 | # $4: The org of the integration 63 | processComponentFile() { 64 | local docsDir="$1" 65 | local webDocsDir="$2" 66 | local componentFile="$3" 67 | 68 | local escapedDocsDir="$(echo "$docsDir" | sed 's/\//\\\//g' | sed 's/\./\\\./g')" 69 | local componentTypeAndSlug="$(echo "$componentFile" | sed "s/$escapedDocsDir\///g" | sed 's/\.mdx//g')" 70 | 71 | # Parse out the Component Slug & Component Type 72 | local componentSlug="$(echo "$componentTypeAndSlug" | cut -d'/' -f 2)" 73 | local componentType="$(componentTypeFromFolderName "$(echo "$componentTypeAndSlug" | cut -d'/' -f 1)")" 74 | if [[ "$componentType" = "" ]]; then 75 | echo "Failed to process '$componentFile', unexpected folder name." 76 | echo "Documentation for components must be stored in one of:" 77 | echo "builders, provisioners, post-processors, datasources" 78 | exit 1 79 | fi 80 | 81 | 82 | # Calculate the location of where this file will ultimately go 83 | local webDocsFolder="$webDocsDir/components/$componentType/$componentSlug" 84 | mkdir -p "$webDocsFolder" 85 | local webDocsFile="$webDocsFolder/README.md" 86 | local webDocsFileTmp="$webDocsFolder/README.md.tmp" 87 | 88 | # Copy over the file to its webDocsFile location 89 | cp "$componentFile" "$webDocsFile" 90 | 91 | # Remove the Header 92 | local lastMetadataLine="$(grep -n -m 2 '^\-\-\-' "$componentFile" | tail -n1 | cut -d':' -f1)" 93 | cat "$webDocsFile" | tail -n +"$(($lastMetadataLine+2))" > "$webDocsFileTmp" 94 | mv "$webDocsFileTmp" "$webDocsFile" 95 | 96 | # Remove the top H1, as this will be added automatically on the web 97 | cat "$webDocsFile" | tail -n +3 > "$webDocsFileTmp" 98 | mv "$webDocsFileTmp" "$webDocsFile" 99 | 100 | # Rewrite Links 101 | rewriteLinks "$(cat "$webDocsFile")" "$4" > "$webDocsFileTmp" 102 | mv "$webDocsFileTmp" "$webDocsFile" 103 | } 104 | 105 | # Compiles the Packer SDC compiled docs folder down 106 | # to a integrations-compliant folder (web docs) 107 | # 108 | # $1: The directory of the plugin 109 | # $2: The directory of the SDC compiled docs files 110 | # $3: The output directory to place the web-docs files 111 | # $4: The org of the integration 112 | compileWebDocs() { 113 | local docsDir="$1/$2" 114 | local webDocsDir="$1/$3" 115 | 116 | echo "Compiling MDX docs in '$2' to Markdown in '$3'..." 117 | # Create the web-docs directory if it hasn't already been created 118 | mkdir -p "$webDocsDir" 119 | 120 | # Copy the README over 121 | cp "$docsDir/README.md" "$webDocsDir/README.md" 122 | 123 | # Process all MDX component files (exclude index files, which are unsupported) 124 | for file in $(find "$docsDir" | grep "$docsDir/.*/.*\.mdx" | grep --invert-match "index.mdx"); do 125 | processComponentFile "$docsDir" "$webDocsDir" "$file" "$4" 126 | done 127 | } 128 | 129 | compileWebDocs "$1" "$2" "$3" "$4" 130 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | See https://github.com/mondoohq/.github/blob/master/CONTRIBUTING.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | License text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved. 2 | “Business Source License” is a trademark of MariaDB Corporation Ab. 3 | 4 | Parameters 5 | 6 | Licensor: Mondoo, Inc. (“Mondoo”) 7 | Licensed Work(s): cnspec-packer-plugin version 8.23.2 and later. The Licensed Work is (c) 2024 Mondoo, Inc. 8 | Additional Use Grant: You may use, distribute or host the Licensed Work in 9 | your own or your direct customers’ production 10 | environment, provided that such use, distribution or 11 | hosting does not include offering the Licensed Work to 12 | third parties as part of or in connection with an 13 | offering that is competitive with any of Mondoo’s 14 | products. 15 | Change Date: Four years from the date the Licensed Work is published 16 | Change License: MPL 2.0 17 | 18 | For information about alternative licensing arrangements for the Licensed Work, please contact licensing@mondoo.com. 19 | 20 | Notice 21 | 22 | Business Source License 1.1 23 | 24 | Terms 25 | 26 | The Licensor hereby grants you the right to copy, modify, create derivative works, redistribute, and make non-production use of the Licensed Work. The Licensor may make an Additional Use Grant, above, permitting limited production use. 27 | 28 | Effective on the Change Date, or the fourth anniversary of the first publicly available distribution of a specific version of the Licensed Work under this License, whichever comes first, the Licensor hereby grants you rights under the terms of the Change License, and the rights granted in the paragraph above terminate. 29 | 30 | If your use of the Licensed Work does not comply with the requirements currently in effect as described in this License, you must purchase a commercial license from the Licensor, its affiliated entities, or authorized resellers, or you must refrain from using the Licensed Work. 31 | 32 | All copies of the original and modified Licensed Work, and derivative works of the Licensed Work, are subject to this License. This License applies separately for each version of the Licensed Work and the Change Date may vary for each version of the Licensed Work released by Licensor. 33 | 34 | You must conspicuously display this License on each original or modified copy of the Licensed Work. If you receive the Licensed Work in original or modified form from a third party, the terms and conditions set forth in this License apply to your use of that work. 35 | 36 | Any use of the Licensed Work in violation of this License will automatically terminate your rights under this License for the current and all other versions of the Licensed Work. 37 | 38 | This License does not grant you any right in any trademark or logo of Licensor or its affiliates (provided that you may use a trademark or logo of Licensor as expressly required by this License). 39 | 40 | TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE. 41 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | NAME=cnspec 2 | BINARY=packer-plugin-${NAME} 3 | 4 | COUNT?=1 5 | TEST?=$(shell go list ./...) 6 | HASHICORP_PACKER_PLUGIN_SDK_VERSION?=$(shell go list -m github.com/hashicorp/packer-plugin-sdk | cut -d " " -f2) 7 | 8 | ifndef LATEST_VERSION_TAG 9 | # echo "read LATEST_VERSION_TAG from git" 10 | LATEST_VERSION_TAG=$(shell git describe --abbrev=0 --tags) 11 | endif 12 | 13 | ifndef MANIFEST_VERSION 14 | # echo "read MANIFEST_VERSION from git" 15 | MANIFEST_VERSION=$(shell git describe --abbrev=0 --tags) 16 | endif 17 | 18 | ifndef TAG 19 | # echo "read TAG from git" 20 | TAG=$(shell git log --pretty=format:'%h' -n 1) 21 | endif 22 | 23 | ifndef VERSION 24 | # echo "read VERSION from git" 25 | VERSION=${LATEST_VERSION_TAG}-$(shell git rev-list --count HEAD) 26 | endif 27 | 28 | ifndef CNSPEC_VERSION 29 | CNSPEC_VERSION=$(shell go list -json -m go.mondoo.com/cnspec/v11 | jq -r ".Version") 30 | endif 31 | 32 | .PHONY: dev 33 | 34 | build: 35 | CGO_ENABLED=0 go build -o ${BINARY} -ldflags="-X go.mondoo.com/cnquery/v10.Version=${CNSPEC_VERSION} -X go.mondoo.com/packer-plugin-cnspec/provisioner/version.Version=${VERSION} -X go.mondoo.com/packer-plugin-cnspec/provisioner/version.Build=${TAG}" 36 | 37 | dev: build 38 | @mkdir -p ~/.packer.d/plugins/ 39 | @mv ${BINARY} ~/.packer.d/plugins/${BINARY} 40 | 41 | .PHONY: dev/linux 42 | dev/linux: build 43 | @mkdir -p ~/.packer.d/plugins/github.com/mondoohq/cnspec/ 44 | @mv ${BINARY} ~/.packer.d/plugins/github.com/mondoohq/cnspec/${BINARY}_${VERSION}_x5.0_linux_amd64 45 | @cat ~/.packer.d/plugins/github.com/mondoohq/cnspec/packer-plugin-cnspec_${VERSION}_x5.0_linux_amd64 | sha256sum -z --tag | cut -d"=" -f2 | tr -d " " > ~/.packer.d/plugins/github.com/mondoohq/cnspec/packer-plugin-cnspec_${VERSION}_x5.0_linux_amd64_SHA256SUM 46 | 47 | .PHONY: dev/macos 48 | dev/macos: build 49 | @mkdir -p ~/.packer.d/plugins/github.com/mondoohq/cnspec/ 50 | @mv ${BINARY} ~/.packer.d/plugins/github.com/mondoohq/cnspec/${BINARY}_v${VERSION}_macos_amd64 51 | @cat ~/.packer.d/plugins/github.com/mondoohq/cnspec/packer-plugin-cnspec_v${VERSION}_macos_amd64 | shasum --tag | cut -d"=" -f2 | tr -d " " > ~/.packer.d/plugins/github.com/mondoohq/cnspec/packer-plugin-cnspec_v${VERSION}_macos_amd64_SHA256SUM 52 | 53 | test: 54 | @go test -race -count $(COUNT) $(TEST) -timeout=3m 55 | 56 | test/golanglint: 57 | @golangci-lint run 58 | 59 | install-packer-sdc: ## Install packer software development command 60 | @go install github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc@${HASHICORP_PACKER_PLUGIN_SDK_VERSION} 61 | 62 | plugin-check: install-packer-sdc build 63 | @packer-sdc plugin-check ${BINARY} 64 | 65 | testacc: dev 66 | @PACKER_ACC=1 go test -count $(COUNT) -v $(TEST) -timeout=120m 67 | 68 | generate: install-packer-sdc 69 | @go generate ./... 70 | @rm -rf .docs 71 | @packer-sdc renderdocs -src "docs" -partials docs-partials/ -dst ".docs/" 72 | @./.web-docs/scripts/compile-to-webdocs.sh "." ".docs" ".web-docs" "mondoohq" 73 | @rm -rf ".docs" 74 | 75 | # Copywrite Check Tool: https://github.com/hashicorp/copywrite 76 | license: license/headers/check 77 | 78 | license/headers/check: 79 | copywrite headers --plan 80 | 81 | license/headers/apply: 82 | copywrite headers 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Packer Plugin for Mondoo cnspec 2 | 3 | ![packer-plugin-cnspec illustration](.github/social/preview.jpg) 4 | 5 | Packer Plugin [cnspec](https://github.com/mondoohq/cnspec) by [Mondoo](https://mondoo.com) scans Linux and Windows [HashiCorp Packer](https://www.packer.io) builds for vulnerabilities and security misconfigurations. The plugin retrieves CVE data from Mondoo that is updated daily with the latest CVEs and advisories. Additionally, cnspec runs security scans using [cnspec-policies](https://github.com/mondoohq/cnspec-policies) to uncover common misconfigurations that open your hosts to the risk of attack. cnspec supports scanning Linux, Windows, and macOS, as well as Docker containers. 6 | 7 | ## Plugin modes 8 | 9 | Packer Plugin cnspec is designed to work in one of two modes: 10 | 11 | - **Unregistered** - In unregistered mode, the plugin works without being registered with Mondoo Platform, and is designed to provide baseline security scanning with minimal configuration. On Linux builds, the plugin runs the [Linux Security by Mondoo](https://github.com/mondoohq/cnspec-policies/blob/main/core/mondoo-linux-security.mql.yaml) policy. On Windows builds, the plugin runs the [Windows Security by Mondoo](https://github.com/mondoohq/cnspec-policies/blob/main/core/mondoo-windows-security.mql.yaml) policy. Each of these policies provides security hardening checks based on industry standards for Linux and Windows. Scan results display in STDOUT during the Packer run. 12 | 13 | - **Registered** - In registered mode, the plugin is registered with your account in Mondoo Platform using a service account. This allows you to configure and customize any of the policies in Mondoo Platform, including CIS benchmarks and more. Scan results are shown in STDOUT and sent back to Mondoo Platform for your records. 14 | 15 | ## Tutorials 16 | 17 | Check out the Packer tutorials on the Mondoo documentation site: 18 | 19 | - [Build secure AMIs with Mondoo and Packer](https://mondoo.com/docs/cnspec/cnspec-aws/cnspec-aws-packer/) 20 | 21 | - [Build secure VM images in Google Cloud with cnspec and HashiCorp Packer](https://mondoo.com/docs/cnspec/cnspec-gcp/cnspec-gcp-packer/) 22 | 23 | # Install Packer plugin cnspec 24 | 25 | You can install Packer Plugin cnspec using the `packer init` command, install it manually, or build it from source. 26 | 27 | ## Install using the packer init command 28 | 29 | As of version 1.7, Packer's `packer init` command allows automatic installation of Packer plugins. For more information, read the [Packer documentation](https://www.packer.io/docs/commands/init). 30 | 31 | To install Packer Plugin cnspec: 32 | 33 | 1. Copy and paste this code into your Packer configuration. 34 | 35 | ```hcl 36 | packer { 37 | required_plugins { 38 | cnspec = { 39 | version = ">= 10.0.0" 40 | source = "github.com/mondoohq/cnspec" 41 | } 42 | } 43 | } 44 | ``` 45 | 46 | 2. Run this command: 47 | 48 | ```bash 49 | packer init /path/to/template.pkr.hcl 50 | ``` 51 | 52 | ### Install manually 53 | 54 | You can find pre-built binary releases of the plugin [here](https://github.com/mondoohq/packer-plugin-cnspec/releases). 55 | 56 | Once you have downloaded the latest archive corresponding to your target OS, uncompress it to retrieve the plugin binary file corresponding to your platform. To install the plugin, follow the Packer documentation on 57 | [installing a plugin](https://www.packer.io/docs/extending/plugins/#installing-plugins). 58 | 59 | ### Build from source 60 | 61 | If you prefer to build the plugin from source: 62 | 63 | 1. Clone this GitHub repository locally. 64 | 65 | 2. Run this command from the root directory: `go build` 66 | 67 | 3. After you successfully compile, the `packer-plugin-cnspec` plugin binary file is in the root directory. Copy the binary into `~/.packer.d/plugins/` by running this command: `make dev` 68 | 69 | 4. To install the compiled plugin, follow the Packer documentation on [installing plugins](https://developer.hashicorp.com/packer/docs/plugins/install-plugins). 70 | 71 | After building the cnspec plugin successfully, use the latest version of Packer to build a machine and verify your changes. In the [example folder](https://github.com/mondoohq/packer-plugin-cnspec/blob/main/examples) we provide a basic template. To force Packer to use the development binary installed in the previous step, comment out the `packer {}` block. 72 | 73 | To use the developer plugin, set the packer plugin environment variable: 74 | 75 | ```bash 76 | export PACKER_PLUGIN_PATH=~/.packer.d/plugins 77 | packer build amazon-linux-2.pkr.hcl 78 | ``` 79 | 80 | ## Configure Packer Plugin cnspec 81 | 82 | For detailed instructions on configuring the Packer Plugin cnspec, please visit the official HashiCorp documentation at Packer Plugin cnspec. There you'll find comprehensive guidance on setup and configuration options. 83 | 84 | ## Sample Packer Templates 85 | 86 | You can find example Packer templates in the [examples](/examples/) directory in this repository. You can also find a [GitHub Action workflow example](/examples/github-actions/packer-build-scan.yaml) of how to use cnspec to test builds as part of a CI/CD pipeline. 87 | 88 | ## Get Started with cnspec 89 | 90 | cnspec's benefits extend well beyond securing Packer builds! To start exploring, [download cnspec](https://mondoo.com/docs/cnspec/). 91 | 92 | ## Contributing 93 | 94 | If you think you've found a bug in the code or you have a question about using this software, please reach out to us by opening an issue in this GitHub repository. 95 | 96 | Contributions to this project are welcome! If you want to fix a bug, please do so by opening a pull request in this GitHub repository. If you want to add a feature, please start by opening an issue in this GitHub repository to discuss it with us beforehand. 97 | 98 | ### Join the community! 99 | 100 | Join the [Mondoo Community GitHub Discussions](https://github.com/orgs/mondoohq/discussions) to collaborate on policy as code and security automation. 101 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | v11.57.2 2 | -------------------------------------------------------------------------------- /assets/enable_policies.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mondoohq/packer-plugin-cnspec/9e780ed9261efaf0b3e31ab20211c27378451b2f/assets/enable_policies.gif -------------------------------------------------------------------------------- /assets/github.splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mondoohq/packer-plugin-cnspec/9e780ed9261efaf0b3e31ab20211c27378451b2f/assets/github.splash.png -------------------------------------------------------------------------------- /assets/service_account.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mondoohq/packer-plugin-cnspec/9e780ed9261efaf0b3e31ab20211c27378451b2f/assets/service_account.gif -------------------------------------------------------------------------------- /assets/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mondoohq/packer-plugin-cnspec/9e780ed9261efaf0b3e31ab20211c27378451b2f/assets/title.png -------------------------------------------------------------------------------- /docs-partials/provisioner/Config-not-required.mdx: -------------------------------------------------------------------------------- 1 | 2 | 3 | - `host_alias` (string) - The alias by which the host should be known. 4 | Defaults to `default`. 5 | 6 | - `user` (string) - The `user` set for your communicator. Defaults to the `user` set 7 | by packer. 8 | 9 | - `local_port` (uint) - The port on which to attempt to listen for SSH 10 | connections. This value is a starting point. The provisioner will attempt 11 | listen for SSH connections on the first available of ten ports, starting at 12 | `local_port`. A system-chosen port is used when `local_port` is missing or 13 | empty. 14 | 15 | - `ssh_host_key_file` (string) - The SSH key that will be used to run the SSH 16 | server on the host machine to forward commands to the target machine. 17 | packer connects to this server and will validate the identity of the 18 | server using the system known_hosts. The default behavior is to generate 19 | and use a onetime key. 20 | 21 | - `ssh_authorized_key_file` (string) - The SSH public key of the packer `ssh_user`. 22 | The default behavior is to generate and use a onetime key. 23 | 24 | - `use_sftp` (bool) - Deprecated: SFTP is now the default. To use SCP instead, set use_scp to true 25 | 26 | - `use_scp` (bool) - Use SCP instead of SFTP. By default, SFTP is used since 27 | SCP communication can fail on Windows 2025 and SSH systems. 28 | 29 | - `debug` (bool) - Sets the log level to `DEBUG` 30 | 31 | - `asset_name` (string) - The asset name passed to Mondoo Platform. Defaults to the hostname 32 | of the instance. 33 | 34 | - `on_failure` (string) - Configure behavior whether packer should fail if `scan_threshold` is 35 | not met. If `scan_threshold` configuration is omitted, the threshold 36 | is set to `0` and builds will pass regardless of what score is 37 | returned. 38 | If `score_threshold` is set to a value, and `on_failure = "continue"` 39 | builds will continue regardless of what score is returned. 40 | 41 | - `labels` (map[string]string) - Configure an optional map of `key/val` labels for the asset in 42 | Mondoo Platform. 43 | 44 | - `annotations` (map[string]string) - Configure an optional map of `key/val` annotations for the asset in 45 | Mondoo Platform. 46 | 47 | - `incognito` (bool) - Configures incognito mode. By default it detects if a Mondoo service account 48 | is available. When set to false, scan results will not be sent to 49 | Mondoo Platform. 50 | 51 | - `policies` ([]string) - A list of policies to be executed (will automatically activate incognito mode). 52 | 53 | - `policybundle` (string) - A path to local policy bundle file. 54 | 55 | - `sudo` (\*SudoConfig) - Runs scan with `--sudo`. Defaults to none. 56 | 57 | - `winrm_user` (string) - Configure WinRM user. Defaults to `user` set by the packer communicator. 58 | 59 | - `winrm_password` (string) - Configure WinRM user password. Defaults to `password` set by the packer 60 | communicator. 61 | 62 | - `use_proxy` (bool) - Use proxy to connect to host to scan. This configuration will fall-back to 63 | packer proxy for cases where the provisioner cannot access the target directly 64 | 65 | - `output` (string) - Set output format: compact, csv, full, json, junit, report, summary, yaml 66 | (default "compact") 67 | 68 | - `output_target` (string) - Set output target. E.g. path to local file 69 | 70 | - `score_threshold` (int) - An integer value to set the `score_threshold` of mondoo scans. Defaults to 71 | `0` which results in a passing score regardless of what scan results are 72 | returned. 73 | 74 | - `mondoo_config_path` (string) - The path to the Mondoo's service account. Defaults to 75 | `$HOME/.config/mondoo/mondoo.yml` 76 | 77 | 78 | -------------------------------------------------------------------------------- /docs-partials/provisioner/SudoConfig-not-required.mdx: -------------------------------------------------------------------------------- 1 | 2 | 3 | - `active` (bool) - Active 4 | 5 | 6 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | Packer plugin [cnspec](https://github.com/mondoohq/cnspec) by [Mondoo](https://mondoo.com) scans Linux and Windows [HashiCorp Packer](https://www.packer.io) builds for vulnerabilities and security misconfigurations. The plugin retrieves CVE data from Mondoo, which is updated daily with the latest CVEs and advisories. Additionally, cnspec runs security scans using [cnspec-policies](https://github.com/mondoohq/cnspec-policies) to uncover common misconfigurations that open your hosts to the risk of attack. cnspec supports scanning of Linux, Windows, and macOS, as well as Docker containers. 2 | 3 | Packer plugin cnspec is designed to work in one of two modes: 4 | 5 | - **Unregistered** - In unregistered mode, the plugin works without being registered to Mondoo Platform, and is designed to provide baseline security scanning with minimal configuration. The plugin runs either the [Linux Security by Mondoo](https://github.com/mondoohq/cnspec-policies/blob/main/core/mondoo-linux-security.mql.yaml) policy on Linux builds, or the [Windows Security by Mondoo](https://github.com/mondoohq/cnspec-policies/blob/main/core/mondoo-windows-security.mql.yaml) policy on Windows builds. Each of these policies provides security hardening checks based off of industry standards for Linux and Windows. Scan results are shown in STDOUT during the Packer run. 6 | - **Registered** - In registered mode, the plugin is registered to your account in Mondoo Platform using a service account. Registered mode allows you to configure and customize any of the policies in Mondoo Platform including CIS benchmarks and more. Scan results are shown in STDOUT and sent back to Mondoo Platform for your records. 7 | 8 | ### Installation 9 | 10 | To install this plugin, copy and paste this code into your Packer configuration, then run [`packer init`](https://www.packer.io/docs/commands/init). 11 | 12 | ```hcl 13 | packer { 14 | required_plugins { 15 | cnspec = { 16 | version = ">= 10.0.0" 17 | source = "github.com/mondoohq/cnspec" 18 | } 19 | } 20 | } 21 | ``` 22 | 23 | Alternatively, you can use `packer plugins install` to manage installation of this plugin. 24 | 25 | ```sh 26 | $ packer plugins install github.com/mondoohq/cnspec 27 | ``` 28 | 29 | ### Components 30 | 31 | #### Provisioners 32 | 33 | - [cnspec](/packer/integrations/mondoohq/cnspec/latest/components/provisioner/cnspec) - Packer plugin [cnspec](https://github.com/mondoohq/cnspec) by [Mondoo](https://mondoo.com) scans 34 | Linux and Windows machine images for vulnerabilities and security misconfigurations. The plugin retrieves CVE data from Mondoo, which is updated daily with the latest CVEs and advisories. Additionally, cnspec runs policy-as-code security scans using [cnspec-policies](https://github.com/mondoohq/cnspec-policies) to uncover common misconfigurations that open your hosts to the risk of attack. 35 | - [mondoo](/packer/integrations/mondoohq/cnspec/latest/components/provisioner/mondoo) - Deprecated. Use the `cnspec` provisioner instead. 36 | 37 | ### Tutorials 38 | 39 | Check out the Packer tutorials on the Mondoo documentation site: 40 | 41 | - [Building secure AMIs with Mondoo and Packer](https://mondoo.com/docs/cnspec/cnspec-aws/cnspec-aws-packer/) 42 | - [Building secure VM images in Google Cloud with cnspec and HashiCorp Packer](https://mondoo.com/docs/cnspec/cnspec-gcp/cnspec-gcp-packer/) 43 | 44 | -------------------------------------------------------------------------------- /docs/provisioners/cnspec.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | The cnspec packer provisioner by Mondoo scans machine-image builds for vulnerabilities 4 | and misconfigurations by executing security policy-as-code. 5 | page_title: cnspec - Provisioner 6 | sidebar_title: cnspec 7 | --- 8 | 9 | # cnspec Provisioner 10 | 11 | Type: `cnspec` 12 | 13 | Packer plugin [cnspec](https://github.com/mondoohq/cnspec) by [Mondoo](https://mondoo.com) scans Linux and Windows machine images for vulnerabilities and security misconfigurations. The plugin retrieves CVE data from Mondoo, which is updated daily with the latest CVEs and advisories. Additionally, cnspec runs security scans using [cnspec-policies](https://github.com/mondoohq/cnspec-policies) to uncover common misconfigurations that open your hosts to the risk of attack. 14 | 15 | ## Basic Example 16 | 17 | ```hcl 18 | provisioner "cnspec" { 19 | on_failure = "continue" 20 | score_threshold = 85 21 | sudo { 22 | active = true 23 | } 24 | } 25 | ``` 26 | 27 | The following configuration shows how to set the output format to JUnit and the output target to `test-results.xml`: 28 | 29 | ```hcl 30 | provisioner "cnspec" { 31 | on_failure = "continue" 32 | output = "junit" 33 | output_target = "test-results.xml" 34 | } 35 | ``` 36 | 37 | ## Configuration Reference 38 | 39 | Optional Parameters: 40 | @include '/provisioner/Config-not-required.mdx' 41 | 42 | ### SudoConfig 43 | @include '/provisioner/SudoConfig-not-required.mdx' 44 | 45 | ## Get Started with cnspec 46 | 47 | If you are new to cnspec, check out [Get started with cnspec](https://mondoo.com/docs/cnspec/). 48 | 49 | ## Packer plugin cnspec tutorial 50 | 51 | Check out the Packer tutorials on the Mondoo documentation site: 52 | 53 | - [Building secure AMIs with Mondoo and Packer](https://mondoo.com/docs/cnspec/cnspec-aws/cnspec-aws-packer/) 54 | - [Building secure VM images in Google Cloud with cnspec and HashiCorp Packer](https://mondoo.com/docs/cnspec/cnspec-gcp/cnspec-gcp-packer/) 55 | 56 | ## Sample Packer Templates 57 | 58 | You can find example Packer templates in the [examples](https://github.com/mondoohq/packer-plugin-cnspec/tree/main/examples) directory in this repository. 59 | -------------------------------------------------------------------------------- /docs/provisioners/mondoo.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | The Mondoo packer provisioner scans machine-image builds for vulnerabilities 4 | and misconfigurations by executing security policy-as-code. 5 | page_title: Mondoo - Provisioner 6 | sidebar_title: Mondoo 7 | --- 8 | 9 | # Mondoo Provisioner (DEPRECATED) 10 | 11 | Type: `mondoo` 12 | 13 | > [!WARNING] 14 | > This plugin has been deprecated. Migrate to [Packer plugin cnspec by Mondoo](https://developer.hashicorp.com/packer/plugins/provisioners/mondoo/cnspec) for even easier security scanning of your Packer builds. 15 | 16 | The `mondoo` provisioner scans [Packer](https://www.packer.io) builds for vulnerabilities and misconfigurations by executing security 17 | policy-as-code enabled in [Mondoo Platform](https://console.mondoo.com). Mondoo Platform comes stocked with an ever-increasing collection of 18 | certified security policies which can be easily customize to meet your needs. 19 | 20 | Mondoo supports scanning of Linux, Windows, and macOS, as well as Docker containers. 21 | 22 | ## Basic Example 23 | ```hcl 24 | provisioner "mondoo" { 25 | on_failure = "continue" 26 | mondoo_config_path = "/etc/mondoo-config.json" 27 | score_threshold = 85 28 | asset_name = "example-secure-base-image" 29 | sudo { 30 | active = true 31 | } 32 | 33 | annotations = { 34 | Source_AMI = "{{ .SourceAMI }}" 35 | Creation_Date = "{{ .SourceAMICreationDate }}" 36 | } 37 | } 38 | } 39 | ``` 40 | 41 | ## Configuration Reference 42 | 43 | Optional Parameters: 44 | @include '/provisioner/Config-not-required.mdx' 45 | 46 | ### SudoConfig 47 | @include '/provisioner/SudoConfig-not-required.mdx' 48 | 49 | ## Get Started with Mondoo 50 | 51 | If you are new to Mondoo you can get started by [signing up for a free account](https://mondoo.com/docs/tutorials/mondoo/account-setup/) today! 52 | 53 | Check out the Packer tutorials on the Mondoo documentation site: 54 | 55 | - [Building secure AMIs with Mondoo and Packer](https://mondoo.com/docs/cnspec/cnspec-aws/cnspec-aws-packer/) 56 | - [Building secure VM images in Google Cloud with cnspec and HashiCorp Packer](https://mondoo.com/docs/cnspec/cnspec-gcp/cnspec-gcp-packer/) 57 | 58 | ## Sample Packer Templates 59 | 60 | You can find example Packer templates in the [examples](https://github.com/mondoohq/packer-plugin-cnspec/tree/main/examples) directory in this repository. 61 | -------------------------------------------------------------------------------- /download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) Mondoo, Inc. 3 | # SPDX-License-Identifier: BUSL-1.1 4 | 5 | # Mondoo, Inc 6 | # This script installs the latest version of the packer plugin for cases where the new HCL format cannot be used 7 | # Please also have a look at the packer documentation https://www.packer.io/docs/plugins 8 | 9 | set +x 10 | set -e 11 | set -o pipefail 12 | 13 | os="" 14 | case "$(uname -s)" in 15 | Linux) os="linux" ;; 16 | Darwin) os="darwin" ;; 17 | DragonFly) os="dragonfly" ;; 18 | GNU/kFreeBSD) os="freebsd" ;; 19 | FreeBSD) os="freebsd" ;; 20 | OpenBSD) os="openbsd" ;; 21 | SunOS) os="solaris" ;; 22 | NetBSD) os="netbsd" ;; 23 | *) fail "Cannot detect OS" ;; 24 | esac 25 | 26 | arch="" 27 | case "$(uname -m)" in 28 | x86_64) arch="amd64" ;; 29 | i386) arch="386" ;; 30 | i686) arch="386" ;; 31 | arm) arch="arm" ;; 32 | aarch64) arch="arm64";; 33 | arm64) arch="arm64";; 34 | *) fail "Cannot detect architecture" ;; 35 | esac 36 | 37 | # automatic download of latest version 38 | version=$(curl https://api.github.com/repos/mondoohq/packer-plugin-cnspec/releases/latest | jq -r .name) 39 | # alternative set the version manually 40 | # version=v0.4.0 41 | 42 | archive="packer-plugin-cnspec_${version}_x5.0_${os}_${arch}.zip" 43 | sha="packer-plugin-cnspec_${version}_SHA256SUMS" 44 | echo Download "${archive}" from 45 | url="https://github.com/mondoohq/packer-plugin-cnspec/releases/download/${version}" 46 | echo "${url}" 47 | 48 | curl -sSL "${url}/${archive}" > "${archive}" 49 | curl -sSL "${url}/${sha}" > "${sha}" 50 | 51 | # determine sha tool based on os 52 | if [ $os = "darwin" ]; then 53 | sha256bin='shasum -a 256 -c' 54 | else 55 | sha256bin='sha256sum -c' 56 | fi 57 | 58 | echo "Validating checksum ${sha} ..." 59 | cat ${sha} | grep ${archive} | ${sha256bin} 60 | 61 | unzip "${archive}" 62 | rm "${archive}" "${sha}" 63 | 64 | mkdir -p ~/.packer.d/plugins 65 | mv "packer-plugin-cnspec_${version}_x5.0_${os}_${arch}" ~/.packer.d/plugins/packer-plugin-cnspec 66 | echo "Marking executable..." 67 | chmod +x ~/.packer.d/plugins/packer-plugin-cnspec 68 | 69 | -------------------------------------------------------------------------------- /examples/aws/amazon-linux-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": { 3 | "aws_region": "{{env `AWS_REGION`}}", 4 | "prefix": "{{env `PACKER_BUILD_PREFIX`}}", 5 | "timestamp": "{{isotime `20060102150405`}}", 6 | }, 7 | "builders": [{ 8 | "type": "amazon-ebs", 9 | "region": "{{user `aws_region`}}", 10 | "source_ami_filter": { 11 | "filters": { 12 | "virtualization-type": "hvm", 13 | "name": "amzn2-ami-kernel-5.*-x86_64-gp2", 14 | "root-device-type": "ebs" 15 | }, 16 | "owners": ["137112412989"], 17 | "most_recent": true 18 | }, 19 | "instance_type": "t2.micro", 20 | "ssh_username": "ec2-user", 21 | "ami_name": "{{user `prefix`}}-amzn2-kernel-5.10-{{user `timestamp`}}", 22 | "tags": { 23 | "Name": "Packer Builder - Amazon Linux 2", 24 | "Base_AMI_Name": "{{ .SourceAMIName }}", 25 | "Source_AMI": "{{ .SourceAMI }}", 26 | "Source_AMI_Creation_Date": "{{ .SourceAMICreationDate }}" 27 | } 28 | }], 29 | "provisioners": [ 30 | { 31 | "type": "shell", 32 | "inline":[ 33 | "ls -l /home/ec2-user" 34 | ] 35 | }, 36 | { 37 | "type": "cnspec", 38 | "on_failure": "continue", 39 | "labels": { 40 | "mondoo.app/ami-name": "{{user `ami_name`}}", 41 | "asset_name": "Packer Build - Amazon Linux 2", 42 | "created_on":"{{user `timestamp`}}" 43 | } 44 | } 45 | ] 46 | } -------------------------------------------------------------------------------- /examples/aws/amazon-linux-2.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | 5 | packer { 6 | required_plugins { 7 | amazon = { 8 | version = ">= 1.1.0" 9 | source = "github.com/hashicorp/amazon" 10 | } 11 | cnspec = { 12 | version = ">= 11.0.0" 13 | source = "github.com/mondoohq/cnspec" 14 | } 15 | } 16 | } 17 | 18 | variable "aws_region" { 19 | default = "us-east-1" 20 | type = string 21 | } 22 | 23 | variable "image_prefix" { 24 | type = string 25 | description = "Prefix to be applied to image name" 26 | default = "mondoo-amazon-linux-2-secure-base" 27 | } 28 | 29 | locals { 30 | timestamp = formatdate("YYYYMMDDhhmmss", timestamp()) 31 | } 32 | 33 | source "amazon-ebs" "amazon2" { 34 | ami_name = "${var.image_prefix}-${local.timestamp}" 35 | instance_type = "t2.micro" 36 | region = var.aws_region 37 | source_ami_filter { 38 | filters = { 39 | name = "amzn2-ami-kernel-5.*-x86_64-gp2" 40 | root-device-type = "ebs" 41 | virtualization-type = "hvm" 42 | } 43 | most_recent = true 44 | owners = ["137112412989"] 45 | } 46 | ssh_username = "ec2-user" 47 | tags = { 48 | Name = "${var.image_prefix}-${local.timestamp}" 49 | Source_AMI = "{{ .SourceAMI }}" 50 | Base_AMI_Name = "{{ .SourceAMIName }}" 51 | Creation_Date = "{{ .SourceAMICreationDate }}" 52 | } 53 | } 54 | 55 | build { 56 | name = "${var.image_prefix}-${local.timestamp}" 57 | 58 | sources = [ 59 | "source.amazon-ebs.amazon2" 60 | ] 61 | 62 | provisioner "shell" { 63 | inline = [ 64 | "sudo hostnamectl set-hostname ${var.image_prefix}-${local.timestamp}", 65 | ] 66 | } 67 | 68 | provisioner "cnspec" { 69 | on_failure = "continue" 70 | asset_name = "${var.image_prefix}-${local.timestamp}" 71 | sudo { 72 | active = true 73 | } 74 | annotations = { 75 | Name = "${var.image_prefix}-${local.timestamp}" 76 | Base_AMI_Name = "${ build.SourceAMIName }" 77 | Source_AMI = "${ build.SourceAMI }" 78 | Creation_Date = "${ build.SourceAMICreationDate }" 79 | } 80 | } 81 | } 82 | 83 | -------------------------------------------------------------------------------- /examples/aws/amazon-linux-2023.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | 5 | packer { 6 | required_plugins { 7 | amazon = { 8 | version = ">= 1.2.0" 9 | source = "github.com/hashicorp/amazon" 10 | } 11 | cnspec = { 12 | version = ">= 11.0.0" 13 | source = "github.com/mondoohq/cnspec" 14 | } 15 | } 16 | } 17 | 18 | variable "aws_region" { 19 | default = "us-east-1" 20 | type = string 21 | } 22 | 23 | variable "image_prefix" { 24 | type = string 25 | description = "Prefix to be applied to image name" 26 | default = "mondoo-amazon-linux-2023-secure-base" 27 | } 28 | 29 | locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") } 30 | 31 | source "amazon-ebs" "amazon2" { 32 | ami_name = "${var.image_prefix}-${local.timestamp}" 33 | instance_type = "t2.micro" 34 | region = var.aws_region 35 | source_ami_filter { 36 | filters = { 37 | name = "al2023-ami-2023.3.20*-x86_64" 38 | root-device-type = "ebs" 39 | virtualization-type = "hvm" 40 | } 41 | most_recent = true 42 | owners = ["137112412989"] 43 | } 44 | ssh_username = "ec2-user" 45 | tags = { 46 | Base_AMI_Name = "{{ .SourceAMIName }}" 47 | Name = "${var.image_prefix}-${local.timestamp}" 48 | Source_AMI = "{{ .SourceAMI }}" 49 | Creation_Date = "{{ .SourceAMICreationDate }}" 50 | } 51 | } 52 | 53 | build { 54 | name = "${var.image_prefix}-${local.timestamp}" 55 | 56 | sources = [ 57 | "source.amazon-ebs.amazon2" 58 | ] 59 | 60 | provisioner "shell" { 61 | inline = [ 62 | "sudo hostnamectl set-hostname ${var.image_prefix}-${local.timestamp}", 63 | ] 64 | } 65 | 66 | provisioner "cnspec" { 67 | on_failure = "continue" 68 | asset_name = "${var.image_prefix}-${local.timestamp}" 69 | sudo { 70 | active = true 71 | } 72 | annotations = { 73 | Source_AMI = "{{ .SourceAMI }}" 74 | Creation_Date = "{{ .SourceAMICreationDate }}" 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /examples/aws/ubuntu-18.04.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": { 3 | "aws_region": "{{env `AWS_REGION`}}", 4 | "prefix": "{{env `PACKER_BUILD_PREFIX`}}", 5 | "timestamp": "{{isotime `20060102150405`}}", 6 | }, 7 | "builders": [{ 8 | "type": "amazon-ebs", 9 | "region": "{{user `aws_region`}}", 10 | "source_ami_filter": { 11 | "filters": { 12 | "virtualization-type": "hvm", 13 | "name": "ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*", 14 | "root-device-type": "ebs" 15 | }, 16 | "owners": ["099720109477"], 17 | "most_recent": true 18 | }, 19 | "instance_type": "t2.micro", 20 | "ssh_username": "ubuntu", 21 | "ami_name": "{{user `prefix`}}-ubuntu1804-{{user `timestamp`}}", 22 | "tags": { 23 | "Name": "Packer Builder - Ubuntu 18.04", 24 | "Base_AMI_Name": "{{ .SourceAMIName }}", 25 | "Source_AMI": "{{ .SourceAMI }}", 26 | "Source_AMI_Creation_Date": "{{ .SourceAMICreationDate }}" 27 | } 28 | }], 29 | "provisioners": [ 30 | { 31 | "type": "shell", 32 | "inline":[ 33 | "ls -l /home/ubuntu" 34 | ] 35 | }, 36 | { 37 | "type": "cnspec", 38 | "on_failure": "continue", 39 | "labels": { 40 | "mondoo.app/ami-name": "{{user `ami_name`}}", 41 | "name":"Packer Builder - Ubuntu 18.04", 42 | "asset_name": "Packer Build - Ubuntu 18.04", 43 | "created_on":"{{user `timestamp`}}" 44 | } 45 | } 46 | ] 47 | } -------------------------------------------------------------------------------- /examples/aws/ubuntu-20.04.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": { 3 | "aws_region": "{{env `AWS_REGION`}}", 4 | "prefix": "{{env `PACKER_BUILD_PREFIX`}}", 5 | "timestamp": "{{isotime `20060102150405`}}", 6 | }, 7 | "builders": [{ 8 | "type": "amazon-ebs", 9 | "region": "{{user `aws_region`}}", 10 | "source_ami_filter": { 11 | "filters": { 12 | "virtualization-type": "hvm", 13 | "name": "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*", 14 | "root-device-type": "ebs" 15 | }, 16 | "owners": ["099720109477"], 17 | "most_recent": true 18 | }, 19 | "instance_type": "t2.micro", 20 | "ssh_username": "ubuntu", 21 | "ami_name": "{{user `prefix`}}-ubuntu2004-base-{{user `timestamp`}}", 22 | "tags": { 23 | "Name": "Packer Builder - Ubuntu 20.04", 24 | "Base_AMI_Name": "{{ .SourceAMIName }}", 25 | "Source_AMI": "{{ .SourceAMI }}", 26 | "Source_AMI_Creation_Date": "{{ .SourceAMICreationDate }}" 27 | } 28 | }], 29 | "provisioners": [ 30 | { 31 | "type": "shell", 32 | "inline":[ 33 | "ls -l /home/ubuntu" 34 | ] 35 | }, 36 | { 37 | "type": "cnspec", 38 | "on_failure": "continue", 39 | "labels": { 40 | "mondoo.app/ami-name": "{{user `ami_name`}}", 41 | "name":"Packer Builder - Ubuntu 20.04", 42 | "asset_name": "Packer Build - Ubuntu 20.04", 43 | "created_on":"{{user `timestamp`}}" 44 | } 45 | } 46 | ] 47 | } -------------------------------------------------------------------------------- /examples/aws/ubuntu-2004.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | packer { 5 | required_plugins { 6 | amazon = { 7 | version = ">= 1.1.0" 8 | source = "github.com/hashicorp/amazon" 9 | } 10 | cnspec = { 11 | version = ">= 11.0.0" 12 | source = "github.com/mondoohq/cnspec" 13 | } 14 | } 15 | } 16 | 17 | variable "aws_region" { 18 | default = "us-east-1" 19 | type = string 20 | } 21 | 22 | variable "image_prefix" { 23 | type = string 24 | description = "Prefix to be applied to image name" 25 | default = "mondoo-ubuntu-20.04-secure-base" 26 | } 27 | 28 | locals { 29 | timestamp = formatdate("YYYYMMDDhhmmss", timestamp()) 30 | } 31 | 32 | source "amazon-ebs" "ubuntu2004" { 33 | ami_name = "${var.image_prefix}-${local.timestamp}" 34 | instance_type = "t2.micro" 35 | region = var.aws_region 36 | source_ami_filter { 37 | filters = { 38 | name = "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*" 39 | root-device-type = "ebs" 40 | virtualization-type = "hvm" 41 | } 42 | most_recent = true 43 | owners = ["099720109477"] 44 | } 45 | ssh_username = "ubuntu" 46 | tags = { 47 | Name = "${var.image_prefix}-${local.timestamp}" 48 | Source_AMI = "{{ .SourceAMI }}" 49 | Base_AMI_Name = "{{ .SourceAMIName }}" 50 | Creation_Date = "{{ .SourceAMICreationDate }}" 51 | } 52 | } 53 | 54 | build { 55 | name = "${var.image_prefix}-${local.timestamp}" 56 | 57 | sources = [ 58 | "source.amazon-ebs.ubuntu2004" 59 | ] 60 | 61 | provisioner "shell" { 62 | inline = [ 63 | "sudo hostnamectl set-hostname ${var.image_prefix}-${local.timestamp}", 64 | "sudo apt-get update -y", 65 | "sudo apt-get upgrade -y" 66 | ] 67 | } 68 | 69 | provisioner "cnspec" { 70 | on_failure = "continue" 71 | asset_name = "${var.image_prefix}-${local.timestamp}" 72 | annotations = { 73 | Name = "${var.image_prefix}-${local.timestamp}" 74 | Base_AMI_Name = "${ build.SourceAMIName }" 75 | Source_AMI = "${ build.SourceAMI }" 76 | Creation_Date = "${ build.SourceAMICreationDate }" 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /examples/aws/ubuntu-2204.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | packer { 5 | required_plugins { 6 | amazon = { 7 | version = ">= 1.1.0" 8 | source = "github.com/hashicorp/amazon" 9 | } 10 | cnspec = { 11 | version = ">= 11.0.0" 12 | source = "github.com/mondoohq/cnspec" 13 | } 14 | } 15 | } 16 | 17 | variable "aws_region" { 18 | default = "us-east-1" 19 | type = string 20 | } 21 | 22 | variable "image_prefix" { 23 | type = string 24 | description = "Prefix to be applied to image name" 25 | default = "mondoo-ubuntu-22.04-secure-base" 26 | } 27 | 28 | locals { 29 | timestamp = formatdate("YYYYMMDDhhmmss", timestamp()) 30 | } 31 | 32 | source "amazon-ebs" "ubuntu2204" { 33 | ami_name = "${var.image_prefix}-${local.timestamp}" 34 | instance_type = "t2.micro" 35 | region = var.aws_region 36 | source_ami_filter { 37 | filters = { 38 | name = "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*" 39 | root-device-type = "ebs" 40 | virtualization-type = "hvm" 41 | } 42 | most_recent = true 43 | owners = ["099720109477"] 44 | } 45 | ssh_username = "ubuntu" 46 | tags = { 47 | Name = "${var.image_prefix}-${local.timestamp}" 48 | Source_AMI = "{{ .SourceAMI }}" 49 | Base_AMI_Name = "{{ .SourceAMIName }}" 50 | Creation_Date = "{{ .SourceAMICreationDate }}" 51 | } 52 | } 53 | 54 | build { 55 | name = "${var.image_prefix}-${local.timestamp}" 56 | sources = [ 57 | "source.amazon-ebs.ubuntu2204" 58 | ] 59 | 60 | provisioner "shell" { 61 | inline = [ 62 | "sudo hostnamectl set-hostname ${var.image_prefix}-${local.timestamp}", 63 | "sudo apt-get update -y", 64 | "sudo apt-get upgrade -y" 65 | ] 66 | } 67 | 68 | provisioner "cnspec" { 69 | on_failure = "continue" 70 | asset_name = "${var.image_prefix}-${local.timestamp}" 71 | 72 | annotations = { 73 | Name = "${var.image_prefix}-${local.timestamp}" 74 | Base_AMI_Name = "${ build.SourceAMIName }" 75 | Source_AMI = "${ build.SourceAMI }" 76 | Creation_Date = "${ build.SourceAMICreationDate }" 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /examples/aws/windows-2019.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | packer { 5 | required_plugins { 6 | amazon = { 7 | version = ">= 1.1.0" 8 | source = "github.com/hashicorp/amazon" 9 | } 10 | cnspec = { 11 | version = ">= 11.0.0" 12 | source = "github.com/mondoohq/cnspec" 13 | } 14 | } 15 | } 16 | 17 | variable "aws_region" { 18 | default = "us-east-1" 19 | type = string 20 | } 21 | 22 | variable "image_prefix" { 23 | type = string 24 | description = "Prefix to be applied to image name" 25 | default = "mondoo-windows2019-secure-base" 26 | } 27 | 28 | locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") } 29 | 30 | source "amazon-ebs" "windows2019" { 31 | ami_name = "${var.image_prefix}-${local.timestamp}" 32 | communicator = "winrm" 33 | instance_type = "t2.micro" 34 | region = var.aws_region 35 | source_ami_filter { 36 | filters = { 37 | name = "Windows_Server-2019-English-Full-Base-*" 38 | root-device-type = "ebs" 39 | virtualization-type = "hvm" 40 | } 41 | most_recent = true 42 | owners = ["801119661308"] 43 | } 44 | user_data_file = "../scripts/bootstrap_win.txt" 45 | winrm_password = "SuperS3cr3t!!!!" 46 | winrm_username = "Administrator" 47 | } 48 | 49 | build { 50 | name = "${var.image_prefix}-${local.timestamp}" 51 | sources = ["source.amazon-ebs.windows2019"] 52 | 53 | provisioner "cnspec" { 54 | on_failure = "continue" 55 | asset_name = "${var.image_prefix}-${local.timestamp}" 56 | annotations = { 57 | Source_AMI = "{{ .SourceAMI }}" 58 | Creation_Date = "{{ .SourceAMICreationDate }}" 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /examples/azure/README.md: -------------------------------------------------------------------------------- 1 | # Azure 2 | 3 | This example shows how to build a Windows Server 2019 image in Azure. It uses 4 | the [Azure RM Builder](https://www.packer.io/docs/builders/azure.html) to create a VM, install Windows, run a PowerShell 5 | script to configure the VM, and then run cnspec packer plugin to assess the security. 6 | 7 | As a prerequisite, you need to have an Azure account. If you don't have one, you can create a free account. Then install [Packer](https://www.packer.io/downloads.html) 8 | and [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) 9 | 10 | ```shell 11 | az login 12 | ``` 13 | 14 | ## Ubuntu 15 | 16 | The Ubuntu example will build an Ubuntu 18.04 image in Azure. 17 | 18 | ```shell 19 | cd ubuntu 20 | ``` 21 | 22 | Update the `vars.json` file with your Azure subscription ID and resource group. Then run the 23 | following command to build the image: 24 | 25 | ```shell 26 | packer build -var-file=vars.json ubuntu-18.04.json 27 | ``` 28 | 29 | 30 | ## Windows 31 | 32 | The Windows example will build a Windows Server 2019 image in Azure. 33 | 34 | ```shell 35 | cd windows 36 | ``` 37 | 38 | Update the variables.pkrvars.hcl file with your Azure subscription ID and tenant ID. Then install all the required 39 | plugins 40 | 41 | ```shell 42 | packer init windows.pkr.hcl 43 | ``` 44 | 45 | Now build the image with the following command: 46 | 47 | ```shell 48 | packer build -var-file=variables.hcl windows.pkr.hcl 49 | ``` 50 | -------------------------------------------------------------------------------- /examples/azure/ubuntu/.gitignore: -------------------------------------------------------------------------------- 1 | azure-arm*pem -------------------------------------------------------------------------------- /examples/azure/ubuntu/ubuntu-18.04.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": { 3 | "resource_group_name": null 4 | }, 5 | "builders": [{ 6 | "type": "azure-arm", 7 | "use_azure_cli_auth" : true, 8 | "subscription_id": "{{ user `subscription_id` }}", 9 | 10 | "managed_image_resource_group_name": "{{ user `resource_group_name` }}", 11 | "managed_image_name": "{{ user `image_name` }}", 12 | 13 | "os_type": "Linux", 14 | "image_publisher": "Canonical", 15 | "image_offer": "UbuntuServer", 16 | "image_sku": "18.04-LTS", 17 | 18 | "azure_tags": { 19 | "dept": "Engineering", 20 | "task": "Image deployment" 21 | }, 22 | 23 | "location": "East US", 24 | "vm_size": "Standard_DS2_v2" 25 | }], 26 | "provisioners": [{ 27 | "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'", 28 | "inline": [ 29 | "apt-get update", 30 | "apt-get upgrade -y" 31 | ], 32 | "inline_shebang": "/bin/sh -x", 33 | "type": "shell" 34 | }, { 35 | "type": "cnspec", 36 | "on_failure": "continue" 37 | }, { 38 | "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'", 39 | "inline": [ 40 | "/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync" 41 | ], 42 | "inline_shebang": "/bin/sh -x", 43 | "type": "shell" 44 | }] 45 | } 46 | -------------------------------------------------------------------------------- /examples/azure/ubuntu/vars.json: -------------------------------------------------------------------------------- 1 | { 2 | "image_name": "packer-test-vm-image", 3 | "resource_group_name": "test-vm_group" 4 | } -------------------------------------------------------------------------------- /examples/azure/windows/variables.pkrvars.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | resourceGroup = "test-vm_group" 5 | location = "westus2" 6 | 7 | imageName = "myImage" 8 | imageVersion = "1.8.0" -------------------------------------------------------------------------------- /examples/azure/windows/windows.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | packer { 5 | required_plugins { 6 | azure = { 7 | source = "github.com/hashicorp/azure" 8 | version = ">= 2" 9 | } 10 | cnspec = { 11 | version = ">= 11.0.0" 12 | source = "github.com/mondoohq/cnspec" 13 | } 14 | } 15 | } 16 | 17 | locals { 18 | random = uuidv4() 19 | date = timestamp() 20 | } 21 | 22 | variable "location" { 23 | type = string 24 | description = "The Azure region to deploy to" 25 | } 26 | 27 | variable "resourceGroup" { 28 | type = string 29 | description = "The Azure resource group to deploy to" 30 | } 31 | 32 | variable "imageName" { 33 | type = string 34 | description = "The Azure Shared Image Gallery image name" 35 | } 36 | 37 | variable "imageVersion" { 38 | type = string 39 | description = "The Azure Shared Image Gallery image version" 40 | } 41 | 42 | source "azure-arm" "windows" { 43 | use_azure_cli_auth = true 44 | 45 | os_type = "Windows" 46 | image_publisher = "MicrosoftWindowsServer" 47 | image_offer = "WindowsServer" 48 | image_sku = "2019-Datacenter" 49 | 50 | azure_tags = { 51 | packer = "true", 52 | build-id = "${local.random}" 53 | } 54 | 55 | managed_image_name = "${var.imageName}-${var.imageVersion}" 56 | managed_image_resource_group_name = var.resourceGroup 57 | 58 | location = var.location 59 | vm_size = "Standard_B4ms" 60 | 61 | communicator = "winrm" 62 | winrm_use_ssl = "true" 63 | winrm_insecure = "true" 64 | winrm_timeout = "50m" 65 | winrm_username = "packer" 66 | } 67 | 68 | build { 69 | 70 | sources = ["sources.azure-arm.windows"] 71 | 72 | provisioner "cnspec" { 73 | asset_name = "${var.imageName}-${var.imageVersion}" 74 | # score_threshold = 80 75 | on_failure = "continue" 76 | debug = false 77 | annotations = { 78 | os-type = "WindowsServer" 79 | os-version = "2019-Datacenter" 80 | image-version = "${var.imageVersion}" 81 | build-time = "${local.date}" 82 | build-id = "${local.random}" 83 | } 84 | } 85 | 86 | provisioner "powershell" { 87 | inline = [ 88 | "# If Guest Agent services are installed, make sure that they have started.", 89 | "foreach ($service in Get-Service -Name RdAgent, WindowsAzureTelemetryService, WindowsAzureGuestAgent -ErrorAction SilentlyContinue) { while ((Get-Service $service.Name).Status -ne 'Running') { Start-Sleep -s 5 } }", 90 | 91 | "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /quiet /quit /mode:vm", 92 | "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" 93 | ] 94 | } 95 | 96 | 97 | } 98 | -------------------------------------------------------------------------------- /examples/custom-policybundle/README.md: -------------------------------------------------------------------------------- 1 | # cnspec packer plugin with custom policy 2 | 3 | This example demonstrates how the cnspec packer plugin leverages custom policy bundles. 4 | 5 | 1. Create a new policy like `custom-policy.mql.yaml` 6 | 2. Include the policy bundle in provider spec 7 | 8 | ```hcl 9 | provisioner "cnspec" { 10 | policybundle = "custom-policy.mql.yaml" 11 | } 12 | ``` 13 | 14 | 3. Run `packer init docker-ubuntu.pkr.hcl` 15 | 4. Run `packer build docker-ubuntu.pkr.hcl` -------------------------------------------------------------------------------- /examples/custom-policybundle/custom-policy.mql.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | policies: 5 | - uid: custom-policy 6 | name: Packer Build Policy 7 | version: "1.0.0" 8 | scoring_system: highest impact 9 | authors: 10 | - name: Mondoo Inc 11 | email: hello@mondoo.io 12 | groups: 13 | - title: Packages 14 | filters: 15 | - mql: asset.family.contains('unix') 16 | checks: 17 | - uid: no-ssh-installed 18 | title: Ensure ssh-server is not installed 19 | mql: package("openssh-server").installed == false 20 | impact: 30 21 | 22 | - uid: no-telnet-installed 23 | title: Ensure telnet-server is not installed 24 | mql: package("telnet-server").installed == false 25 | impact: 100 -------------------------------------------------------------------------------- /examples/custom-policybundle/docker-ubuntu.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | packer { 5 | required_plugins { 6 | docker = { 7 | version = ">= 0.0.7" 8 | source = "github.com/hashicorp/docker" 9 | } 10 | cnspec = { 11 | version = ">= 11.0.0" 12 | source = "github.com/mondoohq/cnspec" 13 | } 14 | } 15 | } 16 | 17 | source "docker" "ubuntu" { 18 | image = "ubuntu:xenial" 19 | commit = true 20 | } 21 | 22 | build { 23 | name = "learn-packer" 24 | sources = [ 25 | "source.docker.ubuntu" 26 | ] 27 | 28 | provisioner "cnspec" { 29 | on_failure = "continue" 30 | policybundle = "custom-policy.mql.yaml" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/digitalocean/centos-7.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": { 3 | "api_token": "{{env `DIGITALOCEAN_TOKEN`}}" 4 | }, 5 | "provisioners": [ 6 | { 7 | "type": "cnspec", 8 | "on_failure": "continue" 9 | } 10 | ], 11 | "builders": [ 12 | { 13 | "type": "digitalocean", 14 | "api_token": "{{user `api_token`}}", 15 | "image": "centos-7-x64", 16 | "ssh_username": "root", 17 | "region": "nyc1", 18 | "size": "s-4vcpu-8gb" 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /examples/digitalocean/ubuntu-18-04.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": { 3 | "api_token": "{{env `DIGITALOCEAN_TOKEN`}}" 4 | }, 5 | "provisioners": [ 6 | { 7 | "type": "cnspec", 8 | "on_failure": "continue" 9 | } 10 | ], 11 | "builders": [ 12 | { 13 | "type": "digitalocean", 14 | "api_token": "{{user `api_token`}}", 15 | "image": "ubuntu-18-04-x64", 16 | "ssh_username": "root", 17 | "region": "nyc1", 18 | "size": "s-4vcpu-8gb" 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /examples/docker/README.md: -------------------------------------------------------------------------------- 1 | # Use Packer and cnspec to protect your container image 2 | 3 | ## Pre-requisites 4 | 5 | - [Packer](https://www.packer.io/) 6 | - [Docker](https://www.docker.com/) 7 | - Service account with Mondoo Platform 8 | 9 | ## Run Packer 10 | 11 | To run Packer, you need to have a `.pkr.hcl` file. In this example, we have a `docker-ubuntu.pkr.hcl` file. 12 | 13 | With the init command, Packer will download the cnspec plugin and install it in the `.packer.d/plugins` directory. 14 | 15 | ```shell 16 | packer init docker-ubuntu.pkr.hcl 17 | ``` 18 | 19 | Configure Mondoo Platform service account credentials either via `cnspec login` or as environment variables. 20 | 21 | ```shell 22 | export MONDOO_CONFIG_PATH=~/.config/mondoo/space-service-account.yml 23 | ``` 24 | 25 | Now, you can run the build command to create the Docker image. 26 | 27 | ```shell 28 | packer build docker-ubuntu.pkr.hcl 29 | ``` 30 | 31 | ```shell 32 | packer build docker-ubuntu.pkr.hcl 33 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: output will be in this color. 34 | 35 | ==> mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: Creating a temporary directory for sharing data... 36 | ==> mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: Pulling Docker image: ubuntu:jammy 37 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: jammy: Pulling from library/ubuntu 38 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: Digest: sha256:e9569c25505f33ff72e88b2990887c9dcf230f23259da296eb814fc2b41af999 39 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: Status: Image is up to date for ubuntu:jammy 40 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: docker.io/library/ubuntu:jammy 41 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: What's Next? 42 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: View a summary of image vulnerabilities and recommendations → docker scout quickview ubuntu:jammy 43 | ==> mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: Starting docker container... 44 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: Run command: docker run -v /Users/chris/.packer.d/tmp892498143:/packer-files -d -i -t --entrypoint=/bin/sh -- ubuntu:jammy 45 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: Container ID: b59be8cb5e2acf5e1abb02f4cec4896840e53e6489101d2506fbf216284b27cf 46 | ==> mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: Using docker communicator to connect: 172.17.0.2 47 | ==> mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: Provisioning with shell script: /var/folders/rw/y7r077vs25l2d43bqjbhq_r80000gn/T/packer-shell2801450226 48 | ==> mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: Running cnspec packer provisioner by Mondoo (Version: 10.0.3, Build: b2dd4a6) 49 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: detected packer container image build 50 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: load config from detected /Users/chris/.config/mondoo/optimistic-chebyshev-158847.yml 51 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: using service account credentials 52 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: scan packer build 53 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: scan completed successfully 54 | ==> mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: Committing the container 55 | mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: Image ID: sha256:2df9972417cd375642401b53f52c070f5f257498b41e709cbaa0f1aa9a49e2ef 56 | ==> mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: Killing the container: b59be8cb5e2acf5e1abb02f4cec4896840e53e6489101d2506fbf216284b27cf 57 | Build 'mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu' finished after 20 seconds 795 milliseconds. 58 | 59 | ==> Wait completed after 20 seconds 795 milliseconds 60 | 61 | ==> Builds finished. The artifacts of successful builds are: 62 | --> mondoo-docker-ubuntu-2004-secure-base.docker.ubuntu: Imported Docker image: sha256:2df9972417cd375642401b53f52c070f5f257498b41e709cbaa0f1aa9a49e2ef 63 | ``` 64 | 65 | In this example we configured the junit export to `test-results.xml` and the `cnspec` plugin will export the scan results in junit format. 66 | 67 | ```hcl 68 | provisioner "cnspec" { 69 | ... 70 | output = "junit" 71 | output_target = "test-results.xml" 72 | } 73 | ``` 74 | 75 | The exported junit file will contain the scan results and can be used in CI/CD pipelines. 76 | 77 | ```xml 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | ... 87 | ``` -------------------------------------------------------------------------------- /examples/docker/docker-ubuntu.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | packer { 5 | required_plugins { 6 | docker = { 7 | version = ">= 0.0.7" 8 | source = "github.com/hashicorp/docker" 9 | } 10 | cnspec = { 11 | version = ">= 11.0.0" 12 | source = "github.com/mondoohq/cnspec" 13 | } 14 | } 15 | } 16 | 17 | variable "image_prefix" { 18 | type = string 19 | description = "Prefix to be applied to image name" 20 | default = "mondoo-ubuntu-2004-secure-base" 21 | } 22 | 23 | locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") } 24 | 25 | source "docker" "ubuntu" { 26 | image = "ubuntu:jammy" 27 | commit = true 28 | } 29 | 30 | build { 31 | name = "mondoo-docker-ubuntu-2004-secure-base" 32 | sources = [ 33 | "source.docker.ubuntu" 34 | ] 35 | 36 | provisioner "shell" { 37 | inline = [ 38 | "echo \"${var.image_prefix}-${local.timestamp}\" > /etc/hostname", 39 | ] 40 | } 41 | 42 | provisioner "cnspec" { 43 | on_failure = "continue" 44 | asset_name = "${var.image_prefix}-${local.timestamp}" 45 | annotations = { 46 | Name = "${var.image_prefix}-${local.timestamp}" 47 | Description = "Mondoo Secure Ubuntu 20.04 Base Image" 48 | # see https://developer.hashicorp.com/packer/docs/templates/hcl_templates/contextual-variables#build-variables 49 | Build = "${ build.PackerRunUUID }" 50 | Source = "${ source.name }" 51 | SourceImageDigest = "${ build.SourceImageDigest }" 52 | } 53 | output = "junit" 54 | output_target = "test-results.xml" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /examples/gcp/ubuntu2004.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | packer { 5 | required_plugins { 6 | googlecompute = { 7 | version = ">= 1.0.0" 8 | source = "github.com/hashicorp/googlecompute" 9 | } 10 | cnspec = { 11 | version = ">= 11.0.0" 12 | source = "github.com/mondoohq/cnspec" 13 | } 14 | } 15 | } 16 | 17 | variable "zone" { 18 | default = "us-east5-a" 19 | } 20 | 21 | variable "project_id" { 22 | type = string 23 | description = "The project ID that will be used to launch instances and store images" 24 | } 25 | 26 | variable "image_prefix" { 27 | type = string 28 | description = "Prefix to be applied to image name" 29 | default = "mondoo-gcp-ubuntu-2004-secure-base" 30 | } 31 | 32 | locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") } 33 | 34 | source "googlecompute" "ubuntu2004" { 35 | image_name = "${var.image_prefix}-${local.timestamp}" 36 | machine_type = "e2-small" 37 | source_image = "ubuntu-pro-2004-focal-v20220627a" 38 | ssh_username = "packer" 39 | temporary_key_pair_type = "rsa" 40 | temporary_key_pair_bits = 2048 41 | zone = var.zone 42 | project_id = var.project_id 43 | } 44 | 45 | build { 46 | name = "mondoo-gcp-ubuntu-2004-secure-base" 47 | 48 | sources = ["source.googlecompute.ubuntu2004"] 49 | provisioner "shell" { 50 | inline = [ 51 | "sudo hostnamectl set-hostname ${var.image_prefix}-${local.timestamp}", 52 | ] 53 | } 54 | 55 | provisioner "cnspec" { 56 | on_failure = "continue" 57 | asset_name = "${var.image_prefix}-${local.timestamp}" 58 | annotations = { 59 | Name = "${var.image_prefix}-${local.timestamp}" 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /examples/github-actions/packer-build-scan.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | name: Packer AMI Build and Scan 5 | 6 | on: 7 | push: 8 | 9 | env: 10 | PRODUCT_VERSION: "1.8.6" # or: "latest" 11 | MONDOO_CONFIG_BASE64: ${{ secrets.MONDOO_CONFIG_BASE64 }} 12 | PACKER_TEMPLATE: image.pkr.hcl 13 | 14 | jobs: 15 | packer-build-and-test: 16 | runs-on: ubuntu-latest 17 | name: packer 18 | 19 | steps: 20 | - name: Checkout Repository 21 | uses: actions/checkout@v3 22 | 23 | - name: Configure AWS Credentials 24 | uses: aws-actions/configure-aws-credentials@v4 25 | with: 26 | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} 27 | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 28 | aws-region: us-east-1 29 | 30 | - name: Setup Packer 31 | uses: hashicorp/setup-packer@main 32 | id: setup 33 | with: 34 | version: ${{ env.PRODUCT_VERSION }} 35 | 36 | - name: Initialize Packer Template 37 | id: init 38 | run: packer init ${{ env.PACKER_TEMPLATE }} 39 | 40 | - name: Validate Packer Template 41 | id: validate 42 | run: packer validate ${{ env.PACKER_TEMPLATE }} 43 | 44 | - name: Build Packer AMI 45 | run: packer build -color=false -on-error=abort ${{ env.PACKER_TEMPLATE }} 46 | -------------------------------------------------------------------------------- /examples/scripts/bootstrap_win.txt: -------------------------------------------------------------------------------- 1 | 2 | # Set administrator password 3 | net user Administrator SuperS3cr3t!!!! 4 | wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE 5 | 6 | # First, make sure WinRM can't be connected to 7 | netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=block 8 | 9 | # Delete any existing WinRM listeners 10 | winrm delete winrm/config/listener?Address=*+Transport=HTTP 2>$Null 11 | winrm delete winrm/config/listener?Address=*+Transport=HTTPS 2>$Null 12 | 13 | # Disable group policies which block basic authentication and unencrypted login 14 | 15 | Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WinRM\Client -Name AllowBasic -Value 1 16 | Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WinRM\Client -Name AllowUnencryptedTraffic -Value 1 17 | Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WinRM\Service -Name AllowBasic -Value 1 18 | Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WinRM\Service -Name AllowUnencryptedTraffic -Value 1 19 | 20 | 21 | # Create a new WinRM listener and configure 22 | winrm create winrm/config/listener?Address=*+Transport=HTTP 23 | winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="0"}' 24 | winrm set winrm/config '@{MaxTimeoutms="7200000"}' 25 | winrm set winrm/config/service '@{AllowUnencrypted="true"}' 26 | winrm set winrm/config/service '@{MaxConcurrentOperationsPerUser="12000"}' 27 | winrm set winrm/config/service/auth '@{Basic="true"}' 28 | winrm set winrm/config/client/auth '@{Basic="true"}' 29 | 30 | # Configure UAC to allow privilege elevation in remote shells 31 | $Key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' 32 | $Setting = 'LocalAccountTokenFilterPolicy' 33 | Set-ItemProperty -Path $Key -Name $Setting -Value 1 -Force 34 | 35 | # Run Updates 36 | 37 | # Configure and restart the WinRM Service; Enable the required firewall exception 38 | Stop-Service -Name WinRM 39 | Set-Service -Name WinRM -StartupType Automatic 40 | netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new action=allow localip=any remoteip=any 41 | Start-Service -Name WinRM 42 | -------------------------------------------------------------------------------- /examples/vsphere/centos7/README.md: -------------------------------------------------------------------------------- 1 | # CentOS 7 Example 2 | 3 | ## Build with vsphere plugin 4 | 5 | Create the `centos-7-x86_64.vsphere.json` file with your credentials. 6 | 7 | ```json 8 | { 9 | "vsphere_endpoint":"vsphere ip", 10 | "vsphere_username":"admin@vsphere.local", 11 | "vsphere_password":"password", 12 | "vsphere_host": "esxi host", 13 | "vsphere_datacenter": "datacenter", 14 | "vsphere_datastore" : "datastore-packer", 15 | "vsphere_network" : "VM Network" 16 | } 17 | ``` 18 | 19 | Then run packer build: 20 | 21 | ``` 22 | packer build --force -var-file centos-7-x86_64.vsphere.json centos-7-x86_64.vsphere.pkr.hcl 23 | ``` -------------------------------------------------------------------------------- /examples/vsphere/centos7/centos-7-x86_64.vsphere.json: -------------------------------------------------------------------------------- 1 | { 2 | "vsphere_endpoint":"vsphere ip", 3 | "vsphere_username":"admin@vsphere.local", 4 | "vsphere_password":"password", 5 | "vsphere_host": "esxi host", 6 | "vsphere_datacenter": "datacenter", 7 | "vsphere_datastore" : "datastore-packer", 8 | "vsphere_network" : "VM Network" 9 | } -------------------------------------------------------------------------------- /examples/vsphere/centos7/centos-7-x86_64.vsphere.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | packer { 5 | required_version = ">= 1.8.4" 6 | required_plugins { 7 | git = { 8 | version = ">= 0.3.2" 9 | source = "github.com/ethanmdavidson/git" 10 | } 11 | vsphere = { 12 | version = ">= v1.1.1" 13 | source = "github.com/hashicorp/vsphere" 14 | } 15 | cnspec = { 16 | version = ">= 11.0.0" 17 | source = "github.com/mondoohq/cnspec" 18 | } 19 | } 20 | } 21 | 22 | variable "vsphere_endpoint" { 23 | type = string 24 | } 25 | 26 | variable "vsphere_username" { 27 | type = string 28 | } 29 | 30 | variable "vsphere_password" { 31 | type = string 32 | } 33 | 34 | variable "vsphere_host" { 35 | type = string 36 | } 37 | 38 | variable "vsphere_datacenter" { 39 | type = string 40 | } 41 | 42 | variable "vsphere_datastore" { 43 | type = string 44 | } 45 | 46 | variable "vsphere_network" { 47 | type = string 48 | } 49 | 50 | locals { 51 | data_source_content = { 52 | "/ks.cfg" = templatefile("${abspath(path.root)}/http/kickstart.cfg", {}) 53 | } 54 | data_source_command = "inst.ks=cdrom:/ks.cfg" 55 | } 56 | 57 | source "vsphere-iso" "centos7" { 58 | CPUs = 1 59 | RAM = 1024 60 | RAM_reserve_all = true 61 | boot_command = [ 62 | "", 63 | "text ${local.data_source_command}", 64 | "", 65 | "", 66 | ] 67 | # boot_command = [" text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/kickstart.cfg", "", ""] 68 | boot_wait = "10s" 69 | disk_controller_type = ["pvscsi"] 70 | guest_os_type = "centos7_64Guest" 71 | cd_content = local.data_source_content 72 | 73 | iso_checksum = "sha256:d68f92f41ab008f94bd89ec4e2403920538c19a7b35b731e770ce24d66be129a" 74 | iso_url = "http://ftp.halifax.rwth-aachen.de/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-Minimal-2207-02.iso" 75 | 76 | vm_name = "example-centos" 77 | shutdown_command = "echo 'vagrant'| sudo -S /sbin/poweroff" 78 | ssh_password = "vagrant" 79 | ssh_port = 22 80 | ssh_timeout = "10m" 81 | ssh_username = "vagrant" 82 | 83 | network_adapters { 84 | network = var.vsphere_network 85 | network_card = "vmxnet3" 86 | } 87 | 88 | storage { 89 | disk_size = 32768 90 | disk_thin_provisioned = true 91 | } 92 | 93 | // vCenter Server Endpoint Settings and Credentials 94 | vcenter_server = "${var.vsphere_endpoint}" 95 | host = "${var.vsphere_host}" 96 | username = "${var.vsphere_username}" 97 | password = "${var.vsphere_password}" 98 | insecure_connection = "true" 99 | datacenter = "${var.vsphere_datacenter}" 100 | datastore = "${var.vsphere_datastore}" 101 | } 102 | 103 | build { 104 | description = "Build CentOS 7 x86_64" 105 | 106 | sources = ["source.vsphere-iso.centos7"] 107 | 108 | provisioner "shell" { 109 | scripts = ["scripts/prepare.sh"] 110 | } 111 | 112 | provisioner "cnspec" { 113 | use_proxy = true 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /examples/vsphere/centos7/http/kickstart.cfg: -------------------------------------------------------------------------------- 1 | install 2 | lang en_US.UTF-8 3 | keyboard us 4 | timezone UTC 5 | auth --enableshadow --passalgo=sha512 --kickstart 6 | firewall --disabled 7 | selinux --disabled 8 | eula --agreed 9 | ignoredisk --only-use=sda 10 | skipx 11 | text 12 | reboot 13 | 14 | bootloader --location=mbr 15 | zerombr 16 | clearpart --all --initlabel 17 | ## autopart 18 | part swap --asprimary --fstype="swap" --size=1024 19 | part /boot --fstype xfs --size=200 20 | part pv.01 --size=1 --grow 21 | volgroup rootvg01 pv.01 22 | logvol / --fstype xfs --name=lv01 --vgname=rootvg01 --size=1 --grow 23 | 24 | network --bootproto=dhcp 25 | rootpw vagrant 26 | user --name=vagrant --plaintext --password vagrant 27 | 28 | %packages --nobase --ignoremissing --excludedocs --instLangs=en_US.utf8 29 | # vagrant needs this to copy initial files via scp 30 | openssh-clients 31 | sudo 32 | kernel-headers 33 | kernel-devel 34 | gcc 35 | make 36 | perl 37 | selinux-policy-devel 38 | wget 39 | nfs-utils 40 | net-tools 41 | bzip2 42 | deltarpm 43 | rsync 44 | -fprintd-pam 45 | -intltool 46 | 47 | # unnecessary firmware 48 | -aic94xx-firmware 49 | -atmel-firmware 50 | -b43-openfwwf 51 | -bfa-firmware 52 | -ipw2100-firmware 53 | -ipw2200-firmware 54 | -ivtv-firmware 55 | -iwl100-firmware 56 | -iwl1000-firmware 57 | -iwl3945-firmware 58 | -iwl4965-firmware 59 | -iwl5000-firmware 60 | -iwl5150-firmware 61 | -iwl6000-firmware 62 | -iwl6000g2a-firmware 63 | -iwl6050-firmware 64 | -libertas-usb8388-firmware 65 | -ql2100-firmware 66 | -ql2200-firmware 67 | -ql23xx-firmware 68 | -ql2400-firmware 69 | -ql2500-firmware 70 | -rt61pci-firmware 71 | -rt73usb-firmware 72 | -xorg-x11-drv-ati-firmware 73 | -zd1211-firmware 74 | %end 75 | 76 | %post 77 | exec < /dev/tty3 > /dev/tty3 78 | chvt 3 79 | echo 80 | echo "################################" 81 | echo "# Running Post Configuration #" 82 | echo "################################" 83 | ( 84 | echo "vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers 85 | sed -i "s/^.*requiretty/#Defaults requiretty/" /etc/sudoers 86 | ) 2>&1 | /usr/bin/tee /var/log/post_install.log 87 | chvt 1 88 | 89 | # Install sdc-vmtools guest tools 90 | echo "Installing VM Tools..." 91 | # Install open-vm-tools, required to detect IP when building on ESXi 92 | sudo yum -y install open-vm-tools 93 | sudo systemctl enable vmtoolsd 94 | sudo systemctl start vmtoolsd 95 | %end 96 | -------------------------------------------------------------------------------- /examples/vsphere/centos7/scripts/prepare.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | set -ux 5 | 6 | # speeds up testing 7 | # yum -y update 8 | 9 | echo "UseDNS no" >> /etc/ssh/sshd_config 10 | 11 | # prep vagrant 12 | date > /etc/vagrant_box_build_time 13 | mkdir -pm 700 /home/vagrant/.ssh 14 | curl -o /home/vagrant/.ssh/authorized_keys 'https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub' 15 | chown -R vagrant:vagrant /home/vagrant/.ssh 16 | chmod -R go-rwsx /home/vagrant/.ssh 17 | 18 | # virtual box 19 | yum -y install bzip2 perl kernel-devel-`uname -r` dkms gcc 20 | yum_rev=$(yum history stats | grep -E "^Transactions:" | cut -d : -f 2) 21 | 22 | VBOX_VERSION=$(cat /home/vagrant/.vbox_version) 23 | cd /tmp 24 | mount -o loop /home/vagrant/VBoxGuestAdditions_$VBOX_VERSION.iso /mnt 25 | sh /mnt/VBoxLinuxAdditions.run 26 | umount /mnt 27 | rm -rf /home/vagrant/VBoxGuestAdditions_*.iso 28 | 29 | [[ -n "$yum_rev" ]] && yum -y history undo $yum_rev 30 | 31 | # clean 32 | yum -y clean all 33 | dd if=/dev/zero of=/EMPTY bs=1M 34 | rm -f /EMPTY 35 | sync -------------------------------------------------------------------------------- /examples/vsphere/photon4/README.md: -------------------------------------------------------------------------------- 1 | # Photon OS 4 2 | 3 | This example builds Photon OS 4 with vSphere. 4 | 5 | Edit the `variables.pkrvars.hcl` file to configure the credentials for the default account on machine images. 6 | 7 | ```hcl title="variables.pkrvars.hcl" 8 | build_username = "example" 9 | build_password = "" 10 | build_password_encrypted = "" 11 | build_key = "" 12 | ``` 13 | 14 | Run the following command to generate a SHA-512 encrypted password for the `build_password_encrypted` using mkpasswd. 15 | 16 | ```shell 17 | docker run -it --rm alpine:latest 18 | mkpasswd -m sha512 19 | ``` 20 | 21 | Then run packer build: 22 | 23 | ``` 24 | packer build -force -var-file variables.pkrvars.hcl . 25 | ``` 26 | 27 | Kudos: This example is based on [packer-examples-for-vsphere](https://github.com/vmware-samples/packer-examples-for-vsphere/tree/main/builds/linux/photon/5) -------------------------------------------------------------------------------- /examples/vsphere/photon4/data/ks.pkrtpl.hcl: -------------------------------------------------------------------------------- 1 | { 2 | "hostname": "photon", 3 | "password": 4 | { 5 | "crypted": true, 6 | "text": "${build_password_encrypted}" 7 | }, 8 | "disk": "/dev/sda", 9 | "partitions": [ 10 | {"mountpoint": "/", "size": 0, "filesystem": "ext4"}, 11 | {"mountpoint": "/boot", "size": 128, "filesystem": "ext4"}, 12 | {"mountpoint": "/root", "size": 128, "filesystem": "ext4"}, 13 | {"size": 128, "filesystem": "swap"} 14 | ], 15 | "bootmode": "efi", 16 | "packages": [ 17 | "minimal", 18 | "linux-esx", 19 | "initramfs", 20 | "sudo", 21 | "vim", 22 | "cloud-utils", 23 | "parted" 24 | ], 25 | "postinstall": [ 26 | "#!/bin/sh", 27 | "useradd -m -p '${build_password_encrypted}' -s /bin/bash ${build_username}", 28 | "usermod -aG sudo ${build_username}", 29 | "echo \"${build_username} ALL=(ALL) NOPASSWD: ALL\" >> /etc/sudoers.d/${build_username}", 30 | "chage -I -1 -m 0 -M 99999 -E -1 root", 31 | "chage -I -1 -m 0 -M 99999 -E -1 ${build_username}" 32 | ], 33 | "linux_flavor": "linux-esx", 34 | "network": { 35 | "type": "dhcp" 36 | } 37 | } -------------------------------------------------------------------------------- /examples/vsphere/photon4/photon.auto.pkrvars.hcl: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Broadcom. All rights reserved. 2 | # SPDX-License-Identifier: BSD-2 3 | 4 | /* 5 | DESCRIPTION: 6 | VMware Photon OS 4 build variables. 7 | Packer Plugin for VMware vSphere: 'vsphere-iso' builder. 8 | */ 9 | 10 | // Guest Operating Systtem Metadata 11 | vm_guest_os_family = "linux" 12 | vm_guest_os_name = "photon" 13 | vm_guest_os_version = "4.0" 14 | 15 | // Virtual Machine Guest Operating Systtem Setting 16 | vm_guest_os_type = "vmwarePhoton64Guest" 17 | 18 | // Virtual Machine Hardware Settings 19 | vm_firmware = "efi-secure" 20 | vm_cdrom_type = "sata" 21 | vm_cpu_count = 2 22 | vm_cpu_cores = 1 23 | vm_cpu_hot_add = false 24 | vm_mem_size = 2048 25 | vm_mem_hot_add = false 26 | vm_disk_size = 40960 27 | vm_disk_controller_type = ["pvscsi"] 28 | vm_disk_thin_provisioned = true 29 | vm_network_card = "vmxnet3" 30 | 31 | // Removable Media Settings 32 | // see https://github.com/vmware/photon/wiki/Downloading-Photon-OS 33 | iso_path = "packer_cache/" 34 | iso_file = "photon-4.0-c001795b8.iso" 35 | iso_url = "https://packages.vmware.com/photon/4.0/Rev2/iso/photon-4.0-c001795b8.iso" 36 | iso_checksum_type = "md5" 37 | iso_checksum_value = "5af288017d0d1198dd6bd02ad40120eb" 38 | 39 | // Boot Settings 40 | vm_boot_order = "disk,cdrom" 41 | vm_boot_wait = "3s" 42 | 43 | // Communicator Settings 44 | communicator_port = 22 45 | communicator_timeout = "30m" -------------------------------------------------------------------------------- /examples/vsphere/photon4/variables.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Broadcom. All rights reserved. 2 | # SPDX-License-Identifier: BSD-2 3 | 4 | /* 5 | DESCRIPTION: 6 | VMware Photon OS 5 input variables. 7 | Packer Plugin for VMware vSphere: 'vsphere-iso' builder. 8 | */ 9 | 10 | // BLOCK: variable 11 | // Defines the input variables. 12 | 13 | // vSphere Credentials 14 | 15 | variable "vsphere_endpoint" { 16 | type = string 17 | description = "The fully qualified domain name or IP address of the vCenter Server instance." 18 | } 19 | 20 | variable "vsphere_username" { 21 | type = string 22 | description = "The username to login to the vCenter Server instance." 23 | sensitive = true 24 | } 25 | 26 | variable "vsphere_password" { 27 | type = string 28 | description = "The password for the login to the vCenter Server instance." 29 | sensitive = true 30 | } 31 | 32 | variable "vsphere_insecure_connection" { 33 | type = bool 34 | description = "Do not validate vCenter Server TLS certificate." 35 | } 36 | 37 | // vSphere Settings 38 | 39 | variable "vsphere_datacenter" { 40 | type = string 41 | description = "The name of the target vSphere datacenter." 42 | default = "" 43 | } 44 | 45 | variable "vsphere_cluster" { 46 | type = string 47 | description = "The name of the target vSphere cluster." 48 | default = "" 49 | } 50 | 51 | variable "vsphere_host" { 52 | type = string 53 | description = "The name of the target ESXi host." 54 | default = "" 55 | } 56 | 57 | variable "vsphere_datastore" { 58 | type = string 59 | description = "The name of the target vSphere datastore." 60 | } 61 | 62 | variable "vsphere_network" { 63 | type = string 64 | description = "The name of the target vSphere network segment." 65 | } 66 | 67 | variable "vsphere_folder" { 68 | type = string 69 | description = "The name of the target vSphere folder." 70 | default = "" 71 | } 72 | 73 | variable "vsphere_resource_pool" { 74 | type = string 75 | description = "The name of the target vSphere resource pool." 76 | default = "" 77 | } 78 | 79 | variable "vsphere_set_host_for_datastore_uploads" { 80 | type = bool 81 | description = "Set this to true if packer should use the host for uploading files to the datastore." 82 | default = false 83 | } 84 | 85 | // Virtual Machine Settings 86 | 87 | variable "vm_guest_os_family" { 88 | type = string 89 | description = "The guest operating system family. Used for naming and VMware Tools." 90 | } 91 | 92 | variable "vm_guest_os_name" { 93 | type = string 94 | description = "The guest operating system name. Used for naming." 95 | } 96 | 97 | variable "vm_guest_os_version" { 98 | type = string 99 | description = "The guest operating system version. Used for naming." 100 | } 101 | 102 | variable "vm_guest_os_type" { 103 | type = string 104 | description = "The guest operating system type, also know as guestid." 105 | } 106 | 107 | variable "vm_firmware" { 108 | type = string 109 | description = "The virtual machine firmware." 110 | default = "efi" 111 | } 112 | 113 | variable "vm_cdrom_type" { 114 | type = string 115 | description = "The virtual machine CD-ROM type." 116 | default = "sata" 117 | } 118 | 119 | variable "vm_cpu_count" { 120 | type = number 121 | description = "The number of virtual CPUs." 122 | } 123 | 124 | variable "vm_cpu_cores" { 125 | type = number 126 | description = "The number of virtual CPUs cores per socket." 127 | } 128 | 129 | variable "vm_cpu_hot_add" { 130 | type = bool 131 | description = "Enable hot add CPU." 132 | default = false 133 | } 134 | 135 | variable "vm_mem_size" { 136 | type = number 137 | description = "The size for the virtual memory in MB." 138 | } 139 | 140 | variable "vm_mem_hot_add" { 141 | type = bool 142 | description = "Enable hot add memory." 143 | default = false 144 | } 145 | 146 | variable "vm_disk_size" { 147 | type = number 148 | description = "The size for the virtual disk in MB." 149 | } 150 | 151 | variable "vm_disk_controller_type" { 152 | type = list(string) 153 | description = "The virtual disk controller types in sequence." 154 | default = ["pvscsi"] 155 | } 156 | 157 | variable "vm_disk_thin_provisioned" { 158 | type = bool 159 | description = "Thin provision the virtual disk." 160 | default = true 161 | } 162 | 163 | variable "vm_network_card" { 164 | type = string 165 | description = "The virtual network card type." 166 | default = "vmxnet3" 167 | } 168 | 169 | variable "common_vm_version" { 170 | type = number 171 | description = "The vSphere virtual hardware version." 172 | } 173 | 174 | variable "common_tools_upgrade_policy" { 175 | type = bool 176 | description = "Upgrade VMware Tools on reboot." 177 | default = true 178 | } 179 | 180 | variable "common_remove_cdrom" { 181 | type = bool 182 | description = "Remove the virtual CD-ROM(s)." 183 | default = true 184 | } 185 | 186 | // Template and Content Library Settings 187 | 188 | variable "common_template_conversion" { 189 | type = bool 190 | description = "Convert the virtual machine to template. Must be 'false' for content library." 191 | default = false 192 | } 193 | 194 | variable "common_content_library_name" { 195 | type = string 196 | description = "The name of the target vSphere content library, if used." 197 | default = null 198 | } 199 | 200 | variable "common_content_library_ovf" { 201 | type = bool 202 | description = "Export to content library as an OVF template." 203 | default = true 204 | } 205 | 206 | variable "common_content_library_destroy" { 207 | type = bool 208 | description = "Delete the virtual machine after exporting to the content library." 209 | default = true 210 | } 211 | 212 | variable "common_content_library_skip_export" { 213 | type = bool 214 | description = "Skip exporting the virtual machine to the content library. Option allows for testing/debugging without saving the machine image." 215 | default = false 216 | } 217 | 218 | // OVF Export Settings 219 | 220 | variable "common_ovf_export_enabled" { 221 | type = bool 222 | description = "Enable OVF artifact export." 223 | default = false 224 | } 225 | 226 | variable "common_ovf_export_overwrite" { 227 | type = bool 228 | description = "Overwrite existing OVF artifact." 229 | default = true 230 | } 231 | 232 | // Removable Media Settings 233 | 234 | variable "common_iso_datastore" { 235 | type = string 236 | description = "The name of the source vSphere datastore for the guest operating system ISO." 237 | } 238 | 239 | variable "iso_url" { 240 | type = string 241 | description = "The URL source of the ISO image. (e.g. 'https://artifactory.rainpole.io/.../os.iso')" 242 | } 243 | 244 | variable "iso_path" { 245 | type = string 246 | description = "The path on the source vSphere datastore for ISO image. (e.g. 'iso/linux/rocky')" 247 | } 248 | 249 | variable "iso_file" { 250 | type = string 251 | description = "The file name of the ISO image used by the vendor. (e.g. 'Rocky--x86_64-dvd1.iso')" 252 | } 253 | 254 | variable "iso_checksum_type" { 255 | type = string 256 | description = "The checksum algorithm used by the vendor. (e.g. 'sha256')" 257 | } 258 | 259 | variable "iso_checksum_value" { 260 | type = string 261 | description = "The checksum value provided by the vendor." 262 | } 263 | 264 | // Boot Settings 265 | 266 | variable "common_data_source" { 267 | type = string 268 | description = "The provisioning data source. One of `http` or `disk`." 269 | } 270 | 271 | variable "common_http_ip" { 272 | type = string 273 | description = "Define an IP address on the host to use for the HTTP server." 274 | default = null 275 | } 276 | 277 | variable "common_http_port_min" { 278 | type = number 279 | description = "The start of the HTTP port range." 280 | } 281 | 282 | variable "common_http_port_max" { 283 | type = number 284 | description = "The end of the HTTP port range." 285 | } 286 | 287 | variable "vm_boot_order" { 288 | type = string 289 | description = "The boot order for virtual machines devices." 290 | default = "disk,cdrom" 291 | } 292 | 293 | variable "vm_boot_wait" { 294 | type = string 295 | description = "The time to wait before boot." 296 | } 297 | 298 | variable "common_ip_wait_timeout" { 299 | type = string 300 | description = "Time to wait for guest operating system IP address response." 301 | } 302 | 303 | variable "common_ip_settle_timeout" { 304 | type = string 305 | description = "Time to wait for guest operating system IP to settle down." 306 | default = "5s" 307 | } 308 | 309 | variable "common_shutdown_timeout" { 310 | type = string 311 | description = "Time to wait for guest operating system shutdown." 312 | } 313 | 314 | // Communicator Settings and Credentials 315 | 316 | variable "build_username" { 317 | type = string 318 | description = "The username to login to the guest operating system." 319 | sensitive = true 320 | } 321 | 322 | variable "build_password" { 323 | type = string 324 | description = "The password to login to the guest operating system." 325 | sensitive = true 326 | } 327 | 328 | variable "build_password_encrypted" { 329 | type = string 330 | description = "The SHA-512 encrypted password to login to the guest operating system." 331 | sensitive = true 332 | } 333 | 334 | variable "build_key" { 335 | type = string 336 | description = "The public key to login to the guest operating system." 337 | sensitive = true 338 | } 339 | 340 | variable "communicator_proxy_host" { 341 | type = string 342 | description = "The proxy server to use for SSH connection. (Optional)" 343 | default = null 344 | } 345 | 346 | variable "communicator_proxy_port" { 347 | type = number 348 | description = "The port to connect to the proxy server. (Optional)" 349 | default = null 350 | } 351 | 352 | variable "communicator_proxy_username" { 353 | type = string 354 | description = "The username to authenticate with the proxy server. (Optional)" 355 | default = null 356 | } 357 | 358 | variable "communicator_proxy_password" { 359 | type = string 360 | description = "The password to authenticate with the proxy server. (Optional)" 361 | sensitive = true 362 | default = null 363 | } 364 | 365 | variable "communicator_port" { 366 | type = string 367 | description = "The port for the communicator protocol." 368 | } 369 | 370 | variable "communicator_timeout" { 371 | type = string 372 | description = "The timeout for the communicator protocol." 373 | } 374 | 375 | variable "vm_name" { 376 | type = string 377 | } 378 | -------------------------------------------------------------------------------- /examples/vsphere/photon4/variables.pkrvars.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | // vSphere Settings 5 | vsphere_endpoint = "sfo-w01-vc01.sfo.rainpole.io" 6 | vsphere_username = "svc-packer-vsphere@rainpole.io" 7 | vsphere_password = "" 8 | vsphere_insecure_connection = true 9 | vsphere_datacenter = "sfo-w01-dc01" 10 | vsphere_cluster = "sfo-w01-cl01" 11 | vsphere_datastore = "sfo-w01-cl01-ds-vsan01" 12 | vsphere_network = "sfo-w01-seg-dhcp" 13 | // Removable Media Settings 14 | common_iso_datastore = "sfo-w01-cl01-ds-vsan01" 15 | 16 | // Build Variables 17 | build_username = "rainpole" 18 | build_password = "" 19 | build_password_encrypted = "" 20 | build_key = "" 21 | // VM Settings 22 | vm_name = "mondoo-photon-05" 23 | 24 | // Virtual Machine Settings 25 | common_vm_version = 19 26 | common_tools_upgrade_policy = true 27 | common_remove_cdrom = true 28 | 29 | // Template and Content Library Settings 30 | common_template_conversion = false 31 | common_content_library_name = null 32 | common_content_library_ovf = true 33 | common_content_library_destroy = true 34 | 35 | // OVF Export Settings 36 | common_ovf_export_enabled = false 37 | common_ovf_export_overwrite = true 38 | 39 | // Boot and Provisioning Settings 40 | common_data_source = "disk" // makes sure the disk is used as the data source 41 | common_http_ip = null 42 | common_http_port_min = 8000 43 | common_http_port_max = 8099 44 | common_ip_wait_timeout = "20m" 45 | common_shutdown_timeout = "15m" -------------------------------------------------------------------------------- /examples/vsphere/rocky8/README.md: -------------------------------------------------------------------------------- 1 | # Rocky Linux 8 2 | 3 | This example builds Rocky Linux 8 with vSphere. 4 | 5 | Edit the `variables.pkrvars.hcl` file to configure the credentials for the default account on machine images. 6 | 7 | ```hcl title="variables.pkrvars.hcl" 8 | build_username = "example" 9 | build_password = "" 10 | build_password_encrypted = "" 11 | build_key = "" 12 | ``` 13 | 14 | Run the following command to generate a SHA-512 encrypted password for the `build_password_encrypted` using mkpasswd. 15 | 16 | ```shell 17 | docker run -it --rm alpine:latest 18 | mkpasswd -m sha512 19 | ``` 20 | 21 | Then run packer build: 22 | 23 | ``` 24 | packer build -force -var-file variables.pkrvars.hcl . 25 | ``` 26 | 27 | Kudos: This example is based on [packer-examples-for-vsphere](https://github.com/vmware-samples/packer-examples-for-vsphere/tree/main/builds/linux/rocky/8) -------------------------------------------------------------------------------- /examples/vsphere/rocky8/data/ks.pkrtpl.hcl: -------------------------------------------------------------------------------- 1 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 2 | # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 3 | # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 4 | # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 5 | 6 | # Rocky Linux 8 7 | 8 | ### Installs from the first attached CD-ROM/DVD on the system. 9 | cdrom 10 | 11 | ### Performs the kickstart installation in text mode. 12 | ### By default, kickstart installations are performed in graphical mode. 13 | text 14 | 15 | ### Accepts the End User License Agreement. 16 | eula --agreed 17 | 18 | ### Sets the language to use during installation and the default language to use on the installed system. 19 | lang ${vm_guest_os_language} 20 | 21 | ### Sets the default keyboard type for the system. 22 | keyboard ${vm_guest_os_keyboard} 23 | 24 | ### Configure network information for target system and activate network devices in the installer environment (optional) 25 | ### --onboot enable device at a boot time 26 | ### --device device to be activated and / or configured with the network command 27 | ### --bootproto method to obtain networking configuration for device (default dhcp) 28 | ### --noipv6 disable IPv6 on this device 29 | ### 30 | ### network --bootproto=static --ip=172.16.11.200 --netmask=255.255.255.0 --gateway=172.16.11.200 --nameserver=172.16.11.4 --hostname centos-linux-8 31 | network --hostname=${hostname} --bootproto=dhcp 32 | 33 | ### Lock the root account. 34 | rootpw --lock 35 | 36 | ### The selected profile will restrict root login. 37 | ### Add a user that can login and escalate privileges. 38 | user --name=${build_username} --iscrypted --password=${build_password_encrypted} --groups=wheel 39 | 40 | ### Configure firewall settings for the system. 41 | ### --enabled reject incoming connections that are not in response to outbound requests 42 | ### --ssh allow sshd service through the firewall 43 | firewall --enabled --ssh 44 | 45 | ### Sets up the authentication options for the system. 46 | ### The SSDD profile sets sha512 to hash passwords. Passwords are shadowed by default 47 | ### See the manual page for authselect-profile for a complete list of possible options. 48 | authselect select sssd 49 | 50 | ### Sets the state of SELinux on the installed system. 51 | ### Defaults to enforcing. 52 | selinux --enforcing 53 | 54 | ### Sets the system time zone. 55 | timezone ${vm_guest_os_timezone} 56 | 57 | ### Sets how the boot loader should be installed. 58 | bootloader --location=mbr 59 | 60 | ### Initialize any invalid partition tables found on disks. 61 | zerombr 62 | 63 | ### Removes partitions from the system, prior to creation of new partitions. 64 | ### By default, no partitions are removed. 65 | ### --linux erases all Linux partitions. 66 | ### --initlabel Initializes a disk (or disks) by creating a default disk label for all disks in their respective architecture. 67 | clearpart --all --initlabel 68 | 69 | ### Modify partition sizes for the virtual machine hardware. 70 | ### Create primary system partitions. 71 | part /boot --fstype xfs --size=1024 --label=BOOTFS 72 | part /boot/efi --fstype vfat --size=1024 --label=EFIFS 73 | part pv.01 --size=100 --grow 74 | 75 | ### Create a logical volume management (LVM) group. 76 | volgroup sysvg --pesize=4096 pv.01 77 | 78 | ### Modify logical volume sizes for the virtual machine hardware. 79 | ### Create logical volumes. 80 | logvol swap --fstype swap --name=lv_swap --vgname=sysvg --size=1024 --label=SWAPFS 81 | logvol / --fstype xfs --name=lv_root --vgname=sysvg --size=12288 --label=ROOTFS 82 | logvol /home --fstype xfs --name=lv_home --vgname=sysvg --size=4096 --label=HOMEFS --fsoptions="nodev,nosuid" 83 | logvol /opt --fstype xfs --name=lv_opt --vgname=sysvg --size=2048 --label=OPTFS --fsoptions="nodev" 84 | logvol /tmp --fstype xfs --name=lv_tmp --vgname=sysvg --size=4096 --label=TMPFS --fsoptions="nodev,noexec,nosuid" 85 | logvol /var --fstype xfs --name=lv_var --vgname=sysvg --size=4096 --label=VARFS --fsoptions="nodev" 86 | logvol /var/log --fstype xfs --name=lv_log --vgname=sysvg --size=4096 --label=LOGFS --fsoptions="nodev,noexec,nosuid" 87 | logvol /var/log/audit --fstype xfs --name=lv_audit --vgname=sysvg --size=4096 --label=AUDITFS --fsoptions="nodev,noexec,nosuid" 88 | ### Modifies the default set of services that will run under the default runlevel. 89 | services --enabled=NetworkManager,sshd 90 | ### Do not configure X on the installed system. 91 | skipx 92 | ### Packages selection. 93 | %packages --ignoremissing --excludedocs 94 | @core 95 | -iwl*firmware 96 | %end 97 | ### Post-installation commands. 98 | %post 99 | dnf makecache 100 | dnf install epel-release -y 101 | dnf makecache 102 | dnf install -y sudo open-vm-tools perl 103 | echo "${build_username} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/${build_username} 104 | sed -i "s/^.*requiretty/#Defaults requiretty/" /etc/sudoers 105 | %end 106 | 107 | ### Reboot after the installation is complete. 108 | ### --eject attempt to eject the media before rebooting. 109 | reboot --eject -------------------------------------------------------------------------------- /examples/vsphere/rocky8/rocky-8.auto.pkrvars.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | /* 5 | DESCRIPTION: 6 | Rocky Linux 8 variables used by the Packer Plugin for VMware vSphere (vsphere-iso). 7 | */ 8 | 9 | // Guest Operating System Metadata 10 | vm_guest_os_language = "en_US" 11 | vm_guest_os_keyboard = "us" 12 | vm_guest_os_timezone = "UTC" 13 | vm_guest_os_family = "linux" 14 | vm_guest_os_name = "rocky" 15 | vm_guest_os_version = "8.7" 16 | 17 | // Virtual Machine Guest Operating System Setting 18 | vm_guest_os_type = "other4xLinux64Guest" 19 | 20 | // Virtual Machine Hardware Settings 21 | vm_firmware = "efi" 22 | vm_cdrom_type = "sata" 23 | vm_cpu_count = 2 24 | vm_cpu_cores = 1 25 | vm_cpu_hot_add = false 26 | vm_mem_size = 2048 27 | vm_mem_hot_add = false 28 | vm_disk_size = 40960 29 | vm_disk_controller_type = ["pvscsi"] 30 | vm_disk_thin_provisioned = true 31 | vm_network_card = "vmxnet3" 32 | 33 | // Removable Media Settings 34 | iso_url = "https://download.rockylinux.org/pub/rocky/8/isos/x86_64/Rocky-8.9-x86_64-minimal.iso" 35 | iso_path = "packer_cache/" 36 | iso_file = "06019fd7c4f956b2b0ed37393e81c577885e4ebd518add249769846711a09dc4.iso" 37 | iso_checksum_type = "sha256" 38 | iso_checksum_value = "06019fd7c4f956b2b0ed37393e81c577885e4ebd518add249769846711a09dc4" 39 | 40 | // Boot Settings 41 | vm_boot_order = "disk,cdrom" 42 | vm_boot_wait = "2s" 43 | 44 | // Communicator Settings 45 | communicator_port = 22 46 | communicator_timeout = "30m" 47 | -------------------------------------------------------------------------------- /examples/vsphere/rocky8/rocky-8.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | /* 5 | DESCRIPTION: 6 | Rocky Linux 8 template using the Packer Builder for VMware vSphere (vsphere-iso). 7 | */ 8 | 9 | // BLOCK: packer 10 | // The Packer configuration. 11 | 12 | packer { 13 | required_version = ">= 1.8.4" 14 | required_plugins { 15 | git = { 16 | version = ">= 0.6.2" 17 | source = "github.com/ethanmdavidson/git" 18 | } 19 | vsphere = { 20 | version = ">= 1.2.7" 21 | source = "github.com/hashicorp/vsphere" 22 | } 23 | cnspec = { 24 | version = ">= 11.0.0" 25 | source = "github.com/mondoohq/cnspec" 26 | } 27 | } 28 | } 29 | 30 | // BLOCK: data 31 | // Defines the data sources. 32 | 33 | data "git-repository" "cwd" {} 34 | 35 | // BLOCK: locals 36 | // Defines the local variables. 37 | 38 | locals { 39 | build_by = "Built by: HashiCorp Packer ${packer.version}" 40 | build_date = formatdate("YYYY-MM-DD hh:mm ZZZ", timestamp()) 41 | build_version = data.git-repository.cwd.head 42 | build_description = "Version: ${local.build_version}\nBuilt on: ${local.build_date}\n${local.build_by}" 43 | iso_paths = ["[${var.common_iso_datastore}] ${var.iso_path}/${var.iso_file}"] 44 | iso_checksum = "${var.iso_checksum_type}:${var.iso_checksum_value}" 45 | manifest_date = formatdate("YYYY-MM-DD hh:mm:ss", timestamp()) 46 | manifest_path = "${path.cwd}/manifests/" 47 | manifest_output = "${local.manifest_path}${local.manifest_date}.json" 48 | ovf_export_path = "${path.cwd}/artifacts/${local.vm_name}" 49 | data_source_content = { 50 | "/ks.cfg" = templatefile("${abspath(path.root)}/data/ks.pkrtpl.hcl", { 51 | hostname = replace("${var.vm_guest_os_family}-${var.vm_guest_os_name}-${var.vm_guest_os_version}", ".", "-") 52 | build_username = var.build_username 53 | build_password = var.build_password 54 | build_password_encrypted = var.build_password_encrypted 55 | vm_guest_os_language = var.vm_guest_os_language 56 | vm_guest_os_keyboard = var.vm_guest_os_keyboard 57 | vm_guest_os_timezone = var.vm_guest_os_timezone 58 | }) 59 | } 60 | data_source_command = var.common_data_source == "http" ? "inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg" : "inst.ks=cdrom:/ks.cfg" 61 | vm_name = "${var.vm_guest_os_family}-${var.vm_guest_os_name}-${var.vm_guest_os_version}-${local.build_version}" 62 | bucket_name = replace("${var.vm_guest_os_family}-${var.vm_guest_os_name}-${var.vm_guest_os_version}", ".", "") 63 | bucket_description = "${var.vm_guest_os_family} ${var.vm_guest_os_name} ${var.vm_guest_os_version}" 64 | } 65 | 66 | // BLOCK: source 67 | // Defines the builder configuration blocks. 68 | 69 | source "vsphere-iso" "linux-rocky" { 70 | 71 | // vCenter Server Endpoint Settings and Credentials 72 | vcenter_server = var.vsphere_endpoint 73 | username = var.vsphere_username 74 | password = var.vsphere_password 75 | insecure_connection = var.vsphere_insecure_connection 76 | 77 | // vSphere Settings 78 | datacenter = var.vsphere_datacenter 79 | cluster = var.vsphere_cluster 80 | datastore = var.vsphere_datastore 81 | 82 | // Virtual Machine Settings 83 | vm_name = local.vm_name 84 | guest_os_type = var.vm_guest_os_type 85 | firmware = var.vm_firmware 86 | CPUs = var.vm_cpu_count 87 | cpu_cores = var.vm_cpu_cores 88 | CPU_hot_plug = var.vm_cpu_hot_add 89 | RAM = var.vm_mem_size 90 | RAM_hot_plug = var.vm_mem_hot_add 91 | cdrom_type = var.vm_cdrom_type 92 | disk_controller_type = var.vm_disk_controller_type 93 | storage { 94 | disk_size = var.vm_disk_size 95 | disk_thin_provisioned = var.vm_disk_thin_provisioned 96 | } 97 | network_adapters { 98 | network = var.vsphere_network 99 | network_card = var.vm_network_card 100 | } 101 | vm_version = var.common_vm_version 102 | remove_cdrom = var.common_remove_cdrom 103 | tools_upgrade_policy = var.common_tools_upgrade_policy 104 | notes = local.build_description 105 | 106 | // Removable Media Settings 107 | iso_url = var.iso_url 108 | iso_paths = local.iso_paths 109 | iso_checksum = local.iso_checksum 110 | http_content = var.common_data_source == "http" ? local.data_source_content : null 111 | cd_content = var.common_data_source == "disk" ? local.data_source_content : null 112 | 113 | // Boot and Provisioning Settings 114 | http_ip = var.common_data_source == "http" ? var.common_http_ip : null 115 | http_port_min = var.common_data_source == "http" ? var.common_http_port_min : null 116 | http_port_max = var.common_data_source == "http" ? var.common_http_port_max : null 117 | boot_order = var.vm_boot_order 118 | boot_wait = var.vm_boot_wait 119 | boot_command = [ 120 | "", 121 | "e", 122 | "", 123 | "text ${local.data_source_command}", 124 | "x" 125 | ] 126 | ip_wait_timeout = var.common_ip_wait_timeout 127 | shutdown_command = "echo '${var.build_password}' | sudo -S -E shutdown -P now" 128 | shutdown_timeout = var.common_shutdown_timeout 129 | 130 | // Communicator Settings and Credentials 131 | communicator = "ssh" 132 | ssh_proxy_host = var.communicator_proxy_host 133 | ssh_proxy_port = var.communicator_proxy_port 134 | ssh_proxy_username = var.communicator_proxy_username 135 | ssh_proxy_password = var.communicator_proxy_password 136 | ssh_username = var.build_username 137 | ssh_password = var.build_password 138 | ssh_port = var.communicator_port 139 | ssh_timeout = var.communicator_timeout 140 | 141 | // Template and Content Library Settings 142 | convert_to_template = var.common_template_conversion 143 | dynamic "content_library_destination" { 144 | for_each = var.common_content_library_name != null ? [1] : [] 145 | content { 146 | library = var.common_content_library_name 147 | description = local.build_description 148 | ovf = var.common_content_library_ovf 149 | destroy = var.common_content_library_destroy 150 | skip_import = var.common_content_library_skip_export 151 | } 152 | } 153 | 154 | // OVF Export Settings 155 | dynamic "export" { 156 | for_each = var.common_ovf_export_enabled == true ? [1] : [] 157 | content { 158 | name = local.vm_name 159 | force = var.common_ovf_export_overwrite 160 | options = [ 161 | "extraconfig" 162 | ] 163 | output_directory = local.ovf_export_path 164 | } 165 | } 166 | } 167 | 168 | // BLOCK: build 169 | // Defines the builders to run, provisioners, and post-processors. 170 | 171 | build { 172 | sources = ["source.vsphere-iso.linux-rocky"] 173 | 174 | provisioner "cnspec" { 175 | on_failure = "continue" 176 | #score_threshold = 85 177 | mondoo_config_path = "/Users/chris/.config/mondoo/acme-gcp.yml" 178 | asset_name = local.vm_name 179 | debug = true 180 | sudo { 181 | active = true 182 | } 183 | annotations = { 184 | build_date = local.build_date 185 | os_family = var.vm_guest_os_family 186 | os_name = var.vm_guest_os_name 187 | os_version = var.vm_guest_os_version 188 | templateName = local.vm_name 189 | } 190 | } 191 | 192 | dynamic "hcp_packer_registry" { 193 | for_each = var.common_hcp_packer_registry_enabled ? [1] : [] 194 | content { 195 | bucket_name = local.bucket_name 196 | description = local.bucket_description 197 | bucket_labels = { 198 | "os_family" : var.vm_guest_os_family, 199 | "os_name" : var.vm_guest_os_name, 200 | "os_version" : var.vm_guest_os_version, 201 | } 202 | build_labels = { 203 | "build_version" : local.build_version, 204 | "packer_version" : packer.version, 205 | } 206 | } 207 | } 208 | } -------------------------------------------------------------------------------- /examples/vsphere/rocky8/variables.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | /* 5 | DESCRIPTION: 6 | Rocky Linux 8 variables using the Packer Builder for VMware vSphere (vsphere-iso). 7 | */ 8 | 9 | // BLOCK: variable 10 | // Defines the input variables. 11 | 12 | // vSphere Credentials 13 | 14 | variable "vsphere_endpoint" { 15 | type = string 16 | description = "The fully qualified domain name or IP address of the vCenter Server instance. (e.g. 'sfo-w01-vc01.sfo.rainpole.io')" 17 | } 18 | 19 | variable "vsphere_username" { 20 | type = string 21 | description = "The username to login to the vCenter Server instance. (e.g. 'svc-packer-vsphere@rainpole.io')" 22 | sensitive = true 23 | } 24 | 25 | variable "vsphere_password" { 26 | type = string 27 | description = "The password for the login to the vCenter Server instance." 28 | sensitive = true 29 | } 30 | 31 | variable "vsphere_insecure_connection" { 32 | type = bool 33 | description = "Do not validate vCenter Server TLS certificate." 34 | } 35 | 36 | // vSphere Settings 37 | 38 | variable "vsphere_datacenter" { 39 | type = string 40 | description = "The name of the target vSphere datacenter. (e.g. 'sfo-w01-dc01')" 41 | } 42 | 43 | variable "vsphere_cluster" { 44 | type = string 45 | description = "The name of the target vSphere cluster. (e.g. 'sfo-w01-cl01')" 46 | } 47 | 48 | variable "vsphere_datastore" { 49 | type = string 50 | description = "The name of the target vSphere datastore. (e.g. 'sfo-w01-cl01-vsan01')" 51 | } 52 | 53 | variable "vsphere_network" { 54 | type = string 55 | description = "The name of the target vSphere network segment. (e.g. 'sfo-w01-dhcp')" 56 | } 57 | 58 | // Virtual Machine Settings 59 | 60 | variable "vm_guest_os_language" { 61 | type = string 62 | description = "The guest operating system lanugage." 63 | default = "en_US" 64 | } 65 | 66 | variable "vm_guest_os_keyboard" { 67 | type = string 68 | description = "The guest operating system keyboard input." 69 | default = "us" 70 | } 71 | 72 | variable "vm_guest_os_timezone" { 73 | type = string 74 | description = "The guest operating system timezone." 75 | default = "UTC" 76 | } 77 | 78 | variable "vm_guest_os_family" { 79 | type = string 80 | description = "The guest operating system family. Used for naming and VMware tools. (e.g. 'linux')" 81 | } 82 | 83 | variable "vm_guest_os_name" { 84 | type = string 85 | description = "The guest operating system name. Used for naming . (e.g. 'rocky')" 86 | } 87 | 88 | variable "vm_guest_os_version" { 89 | type = string 90 | description = "The guest operating system version. Used for naming. (e.g. '8')" 91 | } 92 | 93 | variable "vm_guest_os_type" { 94 | type = string 95 | description = "The guest operating system type, also know as guestid. (e.g. 'other4xLinux64Guest')" 96 | } 97 | 98 | variable "vm_firmware" { 99 | type = string 100 | description = "The virtual machine firmware. (e.g. 'efi-secure', 'efi', or 'bios')" 101 | default = "efi" 102 | } 103 | 104 | variable "vm_cdrom_type" { 105 | type = string 106 | description = "The virtual machine CD-ROM type. (e.g. 'sata', or 'ide')" 107 | default = "sata" 108 | } 109 | 110 | variable "vm_cpu_count" { 111 | type = number 112 | description = "The number of virtual CPUs. (e.g. '2')" 113 | } 114 | 115 | variable "vm_cpu_cores" { 116 | type = number 117 | description = "The number of virtual CPUs cores per socket. (e.g. '1')" 118 | } 119 | 120 | variable "vm_cpu_hot_add" { 121 | type = bool 122 | description = "Enable hot add CPU." 123 | default = false 124 | } 125 | 126 | variable "vm_mem_size" { 127 | type = number 128 | description = "The size for the virtual memory in MB. (e.g. '2048')" 129 | } 130 | 131 | variable "vm_mem_hot_add" { 132 | type = bool 133 | description = "Enable hot add memory." 134 | default = false 135 | } 136 | 137 | variable "vm_disk_size" { 138 | type = number 139 | description = "The size for the virtual disk in MB. (e.g. '40960')" 140 | } 141 | 142 | variable "vm_disk_controller_type" { 143 | type = list(string) 144 | description = "The virtual disk controller types in sequence. (e.g. 'pvscsi')" 145 | default = ["pvscsi"] 146 | } 147 | 148 | variable "vm_disk_thin_provisioned" { 149 | type = bool 150 | description = "Thin provision the virtual disk." 151 | default = true 152 | } 153 | 154 | variable "vm_network_card" { 155 | type = string 156 | description = "The virtual network card type. (e.g. 'vmxnet3' or 'e1000e')" 157 | default = "vmxnet3" 158 | } 159 | 160 | variable "common_vm_version" { 161 | type = number 162 | description = "The vSphere virtual hardware version. (e.g. '19')" 163 | } 164 | 165 | variable "common_tools_upgrade_policy" { 166 | type = bool 167 | description = "Upgrade VMware Tools on reboot." 168 | default = true 169 | } 170 | 171 | variable "common_remove_cdrom" { 172 | type = bool 173 | description = "Remove the virtual CD-ROM(s)." 174 | default = true 175 | } 176 | 177 | // Template and Content Library Settings 178 | 179 | variable "common_template_conversion" { 180 | type = bool 181 | description = "Convert the virtual machine to template. Must be 'false' for content library." 182 | default = false 183 | } 184 | 185 | variable "common_content_library_name" { 186 | type = string 187 | description = "The name of the target vSphere content library, if used. (e.g. 'sfo-w01-cl01-lib01')" 188 | default = null 189 | } 190 | 191 | variable "common_content_library_ovf" { 192 | type = bool 193 | description = "Export to content library as an OVF template." 194 | default = true 195 | } 196 | 197 | variable "common_content_library_destroy" { 198 | type = bool 199 | description = "Delete the virtual machine after exporting to the content library." 200 | default = true 201 | } 202 | 203 | variable "common_content_library_skip_export" { 204 | type = bool 205 | description = "Skip exporting the virtual machine to the content library. Option allows for testing / debugging without saving the machine image." 206 | default = false 207 | } 208 | 209 | // OVF Export Settings 210 | 211 | variable "common_ovf_export_enabled" { 212 | type = bool 213 | description = "Enable OVF artifact export." 214 | default = false 215 | } 216 | 217 | variable "common_ovf_export_overwrite" { 218 | type = bool 219 | description = "Overwrite existing OVF artifact." 220 | default = true 221 | } 222 | 223 | // Removable Media Settings 224 | 225 | variable "common_iso_datastore" { 226 | type = string 227 | description = "The name of the source vSphere datastore for ISO images. (e.g. 'sfo-w01-cl01-nfs01')" 228 | } 229 | 230 | variable "iso_url" { 231 | type = string 232 | description = "The URL source of the ISO image. (e.g. 'https://artifactory.rainpole.io/.../os.iso')" 233 | } 234 | 235 | variable "iso_path" { 236 | type = string 237 | description = "The path on the source vSphere datastore for ISO image. (e.g. 'iso/linux/rocky')" 238 | } 239 | 240 | variable "iso_file" { 241 | type = string 242 | description = "The file name of the ISO image used by the vendor. (e.g. 'Rocky--x86_64-dvd1.iso')" 243 | } 244 | 245 | variable "iso_checksum_type" { 246 | type = string 247 | description = "The checksum algorithm used by the vendor. (e.g. 'sha256')" 248 | } 249 | 250 | variable "iso_checksum_value" { 251 | type = string 252 | description = "The checksum value provided by the vendor." 253 | } 254 | 255 | // Boot Settings 256 | 257 | variable "common_data_source" { 258 | type = string 259 | description = "The provisioning data source. (e.g. 'http' or 'disk')" 260 | } 261 | 262 | variable "common_http_ip" { 263 | type = string 264 | description = "Define an IP address on the host to use for the HTTP server." 265 | default = null 266 | } 267 | 268 | variable "common_http_port_min" { 269 | type = number 270 | description = "The start of the HTTP port range." 271 | } 272 | 273 | variable "common_http_port_max" { 274 | type = number 275 | description = "The end of the HTTP port range." 276 | } 277 | 278 | variable "vm_boot_order" { 279 | type = string 280 | description = "The boot order for virtual machines devices. (e.g. 'disk,cdrom')" 281 | default = "disk,cdrom" 282 | } 283 | 284 | variable "vm_boot_wait" { 285 | type = string 286 | description = "The time to wait before boot." 287 | } 288 | 289 | variable "common_ip_wait_timeout" { 290 | type = string 291 | description = "Time to wait for guest operating system IP address response." 292 | } 293 | 294 | variable "common_shutdown_timeout" { 295 | type = string 296 | description = "Time to wait for guest operating system shutdown." 297 | } 298 | 299 | // Communicator Settings and Credentials 300 | 301 | variable "build_username" { 302 | type = string 303 | description = "The username to login to the guest operating system. (e.g. 'rainpole')" 304 | sensitive = true 305 | } 306 | 307 | variable "build_password" { 308 | type = string 309 | description = "The password to login to the guest operating system." 310 | sensitive = true 311 | } 312 | 313 | variable "build_password_encrypted" { 314 | type = string 315 | description = "The SHA-512 encrypted password to login to the guest operating system." 316 | sensitive = true 317 | } 318 | 319 | variable "communicator_proxy_host" { 320 | type = string 321 | description = "A SOCKS proxy host to use for SSH connection." 322 | default = null 323 | } 324 | 325 | variable "communicator_proxy_port" { 326 | type = number 327 | description = "A port of the SOCKS proxy." 328 | default = null 329 | } 330 | 331 | variable "communicator_proxy_username" { 332 | type = string 333 | description = "The optional username to authenticate with the proxy server." 334 | default = null 335 | } 336 | 337 | variable "communicator_proxy_password" { 338 | type = string 339 | description = "The optional password to use to authenticate with the proxy server." 340 | sensitive = true 341 | default = null 342 | } 343 | 344 | variable "communicator_port" { 345 | type = string 346 | description = "The port for the communicator protocol." 347 | } 348 | 349 | variable "communicator_timeout" { 350 | type = string 351 | description = "The timeout for the communicator protocol." 352 | } 353 | 354 | // HCP Packer Settings 355 | 356 | variable "common_hcp_packer_registry_enabled" { 357 | type = bool 358 | description = "Enable the HCP Packer registry." 359 | default = false 360 | } 361 | -------------------------------------------------------------------------------- /examples/vsphere/rocky8/variables.pkrvars.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | // vSphere Settings 5 | vsphere_endpoint = "sfo-w01-vc01.sfo.rainpole.io" 6 | vsphere_username = "svc-packer-vsphere@rainpole.io" 7 | vsphere_password = "" 8 | vsphere_insecure_connection = true 9 | vsphere_datacenter = "sfo-w01-dc01" 10 | vsphere_cluster = "sfo-w01-cl01" 11 | vsphere_datastore = "sfo-w01-cl01-ds-vsan01" 12 | vsphere_network = "sfo-w01-seg-dhcp" 13 | 14 | // Build Variables 15 | build_username = "rainpole" 16 | build_password = "" 17 | build_password_encrypted = "" 18 | build_key = "" 19 | 20 | // Virtual Machine Settings 21 | common_vm_version = 19 22 | common_tools_upgrade_policy = true 23 | common_remove_cdrom = true 24 | 25 | // Template and Content Library Settings 26 | common_template_conversion = false 27 | common_content_library_name = null 28 | common_content_library_ovf = true 29 | common_content_library_destroy = true 30 | 31 | // OVF Export Settings 32 | common_ovf_export_enabled = false 33 | common_ovf_export_overwrite = true 34 | 35 | // Removable Media Settings 36 | common_iso_datastore = "sfo-w01-cl01-ds-nfs01" 37 | 38 | // Boot and Provisioning Settings 39 | common_data_source = "disk" // makes sure the disk is used as the data source 40 | common_http_ip = null 41 | common_http_port_min = 8000 42 | common_http_port_max = 8099 43 | common_ip_wait_timeout = "20m" 44 | common_shutdown_timeout = "15m" 45 | 46 | // HCP Packer 47 | common_hcp_packer_registry_enabled = false -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Mondoo, Inc. 2 | // SPDX-License-Identifier: BUSL-1.1 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | 10 | "github.com/hashicorp/packer-plugin-sdk/plugin" 11 | "go.mondoo.com/packer-plugin-cnspec/provisioner" 12 | "go.mondoo.com/packer-plugin-cnspec/provisioner/version" 13 | ) 14 | 15 | func main() { 16 | pps := plugin.NewSet() 17 | pps.RegisterProvisioner(plugin.DEFAULT_NAME, new(provisioner.Provisioner)) 18 | pps.SetVersion(version.PluginVersion) 19 | err := pps.Run() 20 | 21 | if err != nil { 22 | fmt.Fprintln(os.Stderr, err.Error()) 23 | os.Exit(1) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /provisioner/buildinfo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Mondoo, Inc. 2 | // SPDX-License-Identifier: BUSL-1.1 3 | 4 | package provisioner 5 | 6 | // https://www.packer.io/docs/templates/legacy_json_templates/engine 7 | type BuildInfo struct { 8 | // depending on the cloud povider, the type changes 9 | ID interface{} `json:"ID"` 10 | ConnType string `json:"ConnType"` 11 | Host string `json:"Host"` 12 | Port int `json:"Port"` 13 | User string `json:"User"` 14 | 15 | PackerHTTPAddr string `json:"PackerHTTPAddr"` 16 | PackerHTTPIP string `json:"PackerHTTPIP"` 17 | PackerHTTPPort string `json:"PackerHTTPPort"` 18 | PackerRunUUID string `json:"PackerRunUUID"` 19 | Password string `json:"Password"` 20 | 21 | SSHAgentAuth bool `json:"SSHAgentAuth"` 22 | SSHPrivateKey string `json:"SSHPrivateKey"` 23 | SSHPublicKey string `json:"SSHPublicKey"` 24 | } 25 | -------------------------------------------------------------------------------- /provisioner/buildinfo_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Mondoo, Inc. 2 | // SPDX-License-Identifier: BUSL-1.1 3 | 4 | package provisioner 5 | 6 | import ( 7 | "encoding/json" 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | func TestBuildInfo(t *testing.T) { 15 | 16 | data := ` 17 | {"ConnType":"ssh","Host":"127.0.0.1","ID":"packer-alpine-1599666417","PackerHTTPAddr":"10.0.2.2:8644","PackerHTTPIP":"10.0.2.2","PackerHTTPPort":"8644","PackerRunUUID":"6ef27e2e-f4ea-be8e-7dc9-b1089998c001","Password":"vagrant","Port":2463,"SSHAgentAuth":false,"SSHPrivateKey":"priv-key","SSHPublicKey":"pub-key","User":"vagrant","WinRMPassword":""} 18 | ` 19 | var buildInfo BuildInfo 20 | err := json.Unmarshal([]byte(data), &buildInfo) 21 | require.NoError(t, err) 22 | assert.Equal(t, "packer-alpine-1599666417", buildInfo.ID) 23 | assert.Equal(t, "ssh", buildInfo.ConnType) 24 | assert.Equal(t, "127.0.0.1", buildInfo.Host) 25 | assert.Equal(t, 2463, buildInfo.Port) 26 | assert.Equal(t, "vagrant", buildInfo.User) 27 | assert.Equal(t, "vagrant", buildInfo.Password) 28 | assert.Equal(t, "10.0.2.2:8644", buildInfo.PackerHTTPAddr) 29 | assert.Equal(t, "10.0.2.2", buildInfo.PackerHTTPIP) 30 | assert.Equal(t, "8644", buildInfo.PackerHTTPPort) 31 | assert.Equal(t, "6ef27e2e-f4ea-be8e-7dc9-b1089998c001", buildInfo.PackerRunUUID) 32 | assert.False(t, buildInfo.SSHAgentAuth) 33 | assert.Equal(t, "priv-key", buildInfo.SSHPrivateKey) 34 | assert.Equal(t, "pub-key", buildInfo.SSHPublicKey) 35 | } 36 | -------------------------------------------------------------------------------- /provisioner/provisioner.hcl2spec.go: -------------------------------------------------------------------------------- 1 | // Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT. 2 | 3 | package provisioner 4 | 5 | import ( 6 | "github.com/hashicorp/hcl/v2/hcldec" 7 | "github.com/zclconf/go-cty/cty" 8 | ) 9 | 10 | // FlatConfig is an auto-generated flat version of Config. 11 | // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. 12 | type FlatConfig struct { 13 | PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"` 14 | PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"` 15 | PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"` 16 | PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"` 17 | PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"` 18 | PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"` 19 | PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"` 20 | PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"` 21 | HostAlias *string `mapstructure:"host_alias" cty:"host_alias" hcl:"host_alias"` 22 | User *string `mapstructure:"user" cty:"user" hcl:"user"` 23 | LocalPort *uint `mapstructure:"local_port" cty:"local_port" hcl:"local_port"` 24 | SSHHostKeyFile *string `mapstructure:"ssh_host_key_file" cty:"ssh_host_key_file" hcl:"ssh_host_key_file"` 25 | SSHAuthorizedKeyFile *string `mapstructure:"ssh_authorized_key_file" cty:"ssh_authorized_key_file" hcl:"ssh_authorized_key_file"` 26 | UseSFTP *bool `mapstructure:"use_sftp" cty:"use_sftp" hcl:"use_sftp"` 27 | UseSCP *bool `mapstructure:"use_scp" cty:"use_scp" hcl:"use_scp"` 28 | Debug *bool `mapstructure:"debug" cty:"debug" hcl:"debug"` 29 | AssetName *string `mapstructure:"asset_name" cty:"asset_name" hcl:"asset_name"` 30 | OnFailure *string `mapstructure:"on_failure" cty:"on_failure" hcl:"on_failure"` 31 | Labels map[string]string `mapstructure:"labels" cty:"labels" hcl:"labels"` 32 | Annotations map[string]string `mapstructure:"annotations" cty:"annotations" hcl:"annotations"` 33 | Incognito *bool `mapstructure:"incognito" cty:"incognito" hcl:"incognito"` 34 | Policies []string `mapstructure:"policies" cty:"policies" hcl:"policies"` 35 | PolicyBundle *string `mapstructure:"policybundle" cty:"policybundle" hcl:"policybundle"` 36 | Sudo *FlatSudoConfig `mapstructure:"sudo" cty:"sudo" hcl:"sudo"` 37 | WinRMUser *string `mapstructure:"winrm_user" cty:"winrm_user" hcl:"winrm_user"` 38 | WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password" hcl:"winrm_password"` 39 | UseProxy *bool `mapstructure:"use_proxy" cty:"use_proxy" hcl:"use_proxy"` 40 | Output *string `mapstructure:"output" cty:"output" hcl:"output"` 41 | OutputTarget *string `mapstructure:"output_target" cty:"output_target" hcl:"output_target"` 42 | ScoreThreshold *int `mapstructure:"score_threshold" cty:"score_threshold" hcl:"score_threshold"` 43 | MondooConfigPath *string `mapstructure:"mondoo_config_path" cty:"mondoo_config_path" hcl:"mondoo_config_path"` 44 | } 45 | 46 | // FlatMapstructure returns a new FlatConfig. 47 | // FlatConfig is an auto-generated flat version of Config. 48 | // Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. 49 | func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { 50 | return new(FlatConfig) 51 | } 52 | 53 | // HCL2Spec returns the hcl spec of a Config. 54 | // This spec is used by HCL to read the fields of Config. 55 | // The decoded values from this spec will then be applied to a FlatConfig. 56 | func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { 57 | s := map[string]hcldec.Spec{ 58 | "packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false}, 59 | "packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false}, 60 | "packer_core_version": &hcldec.AttrSpec{Name: "packer_core_version", Type: cty.String, Required: false}, 61 | "packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false}, 62 | "packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false}, 63 | "packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false}, 64 | "packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false}, 65 | "packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false}, 66 | "host_alias": &hcldec.AttrSpec{Name: "host_alias", Type: cty.String, Required: false}, 67 | "user": &hcldec.AttrSpec{Name: "user", Type: cty.String, Required: false}, 68 | "local_port": &hcldec.AttrSpec{Name: "local_port", Type: cty.Number, Required: false}, 69 | "ssh_host_key_file": &hcldec.AttrSpec{Name: "ssh_host_key_file", Type: cty.String, Required: false}, 70 | "ssh_authorized_key_file": &hcldec.AttrSpec{Name: "ssh_authorized_key_file", Type: cty.String, Required: false}, 71 | "use_sftp": &hcldec.AttrSpec{Name: "use_sftp", Type: cty.Bool, Required: false}, 72 | "use_scp": &hcldec.AttrSpec{Name: "use_scp", Type: cty.Bool, Required: false}, 73 | "debug": &hcldec.AttrSpec{Name: "debug", Type: cty.Bool, Required: false}, 74 | "asset_name": &hcldec.AttrSpec{Name: "asset_name", Type: cty.String, Required: false}, 75 | "on_failure": &hcldec.AttrSpec{Name: "on_failure", Type: cty.String, Required: false}, 76 | "labels": &hcldec.AttrSpec{Name: "labels", Type: cty.Map(cty.String), Required: false}, 77 | "annotations": &hcldec.AttrSpec{Name: "annotations", Type: cty.Map(cty.String), Required: false}, 78 | "incognito": &hcldec.AttrSpec{Name: "incognito", Type: cty.Bool, Required: false}, 79 | "policies": &hcldec.AttrSpec{Name: "policies", Type: cty.List(cty.String), Required: false}, 80 | "policybundle": &hcldec.AttrSpec{Name: "policybundle", Type: cty.String, Required: false}, 81 | "sudo": &hcldec.BlockSpec{TypeName: "sudo", Nested: hcldec.ObjectSpec((*FlatSudoConfig)(nil).HCL2Spec())}, 82 | "winrm_user": &hcldec.AttrSpec{Name: "winrm_user", Type: cty.String, Required: false}, 83 | "winrm_password": &hcldec.AttrSpec{Name: "winrm_password", Type: cty.String, Required: false}, 84 | "use_proxy": &hcldec.AttrSpec{Name: "use_proxy", Type: cty.Bool, Required: false}, 85 | "output": &hcldec.AttrSpec{Name: "output", Type: cty.String, Required: false}, 86 | "output_target": &hcldec.AttrSpec{Name: "output_target", Type: cty.String, Required: false}, 87 | "score_threshold": &hcldec.AttrSpec{Name: "score_threshold", Type: cty.Number, Required: false}, 88 | "mondoo_config_path": &hcldec.AttrSpec{Name: "mondoo_config_path", Type: cty.String, Required: false}, 89 | } 90 | return s 91 | } 92 | 93 | // FlatSudoConfig is an auto-generated flat version of SudoConfig. 94 | // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. 95 | type FlatSudoConfig struct { 96 | Active *bool `mapstructure:"active" cty:"active" hcl:"active"` 97 | } 98 | 99 | // FlatMapstructure returns a new FlatSudoConfig. 100 | // FlatSudoConfig is an auto-generated flat version of SudoConfig. 101 | // Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. 102 | func (*SudoConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { 103 | return new(FlatSudoConfig) 104 | } 105 | 106 | // HCL2Spec returns the hcl spec of a SudoConfig. 107 | // This spec is used by HCL to read the fields of SudoConfig. 108 | // The decoded values from this spec will then be applied to a FlatSudoConfig. 109 | func (*FlatSudoConfig) HCL2Spec() map[string]hcldec.Spec { 110 | s := map[string]hcldec.Spec{ 111 | "active": &hcldec.AttrSpec{Name: "active", Type: cty.Bool, Required: false}, 112 | } 113 | return s 114 | } 115 | -------------------------------------------------------------------------------- /provisioner/sshkey.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Mondoo, Inc. 2 | // SPDX-License-Identifier: BUSL-1.1 3 | 4 | package provisioner 5 | 6 | import ( 7 | "crypto/rand" 8 | "crypto/rsa" 9 | "crypto/x509" 10 | "encoding/pem" 11 | "errors" 12 | "os" 13 | 14 | "github.com/hashicorp/packer-plugin-sdk/tmp" 15 | "golang.org/x/crypto/ssh" 16 | ) 17 | 18 | type userKey struct { 19 | ssh.PublicKey 20 | privKeyFile string 21 | } 22 | 23 | func newUserKey(pubKeyFile string) (*userKey, error) { 24 | userKey := new(userKey) 25 | if len(pubKeyFile) > 0 { 26 | pubKeyBytes, err := os.ReadFile(pubKeyFile) 27 | if err != nil { 28 | return nil, errors.New("failed to read public key") 29 | } 30 | userKey.PublicKey, _, _, _, err = ssh.ParseAuthorizedKey(pubKeyBytes) 31 | if err != nil { 32 | return nil, errors.New("failed to parse authorized key") 33 | } 34 | 35 | return userKey, nil 36 | } 37 | 38 | key, err := rsa.GenerateKey(rand.Reader, 2048) 39 | if err != nil { 40 | return nil, errors.New("failed to generate key pair") 41 | } 42 | userKey.PublicKey, err = ssh.NewPublicKey(key.Public()) 43 | if err != nil { 44 | return nil, errors.New("failed to extract public key from generated key pair") 45 | } 46 | 47 | // To support mondoo calling back to us we need to write this file down 48 | privateKeyDer := x509.MarshalPKCS1PrivateKey(key) 49 | privateKeyBlock := pem.Block{ 50 | Type: "RSA PRIVATE KEY", 51 | Headers: nil, 52 | Bytes: privateKeyDer, 53 | } 54 | tf, err := tmp.File("mondoo-key") 55 | if err != nil { 56 | return nil, errors.New("failed to create temp file for generated key") 57 | } 58 | _, err = tf.Write(pem.EncodeToMemory(&privateKeyBlock)) 59 | if err != nil { 60 | return nil, errors.New("failed to write private key to temp file") 61 | } 62 | 63 | err = tf.Close() 64 | if err != nil { 65 | return nil, errors.New("failed to close private key temp file") 66 | } 67 | userKey.privKeyFile = tf.Name() 68 | 69 | return userKey, nil 70 | } 71 | 72 | type signer struct { 73 | ssh.Signer 74 | } 75 | 76 | func newSigner(privKeyFile string) (*signer, error) { 77 | signer := new(signer) 78 | 79 | if len(privKeyFile) > 0 { 80 | privateBytes, err := os.ReadFile(privKeyFile) 81 | if err != nil { 82 | return nil, errors.New("failed to load private host key") 83 | } 84 | 85 | signer.Signer, err = ssh.ParsePrivateKey(privateBytes) 86 | if err != nil { 87 | return nil, errors.New("failed to parse private host key") 88 | } 89 | 90 | return signer, nil 91 | } 92 | 93 | key, err := rsa.GenerateKey(rand.Reader, 2048) 94 | if err != nil { 95 | return nil, errors.New("failed to generate server key pair") 96 | } 97 | 98 | signer.Signer, err = ssh.NewSignerFromKey(key) 99 | if err != nil { 100 | return nil, errors.New("failed to extract private key from generated key pair") 101 | } 102 | 103 | return signer, nil 104 | } 105 | -------------------------------------------------------------------------------- /provisioner/version/version.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Mondoo, Inc. 2 | // SPDX-License-Identifier: BUSL-1.1 3 | 4 | package version 5 | 6 | import "github.com/hashicorp/packer-plugin-sdk/version" 7 | 8 | var ( 9 | // Version is set via ldflags 10 | Version string 11 | 12 | // Build version is set via ldflags 13 | Build string 14 | 15 | // Build date is set via ldflags 16 | Date string 17 | 18 | // VersionPrerelease is A pre-release marker for the Version. If this is "" 19 | // (empty string) then it means that it is a final release. Otherwise, this 20 | // is a pre-release such as "dev" (in development), "beta", "rc1", etc. 21 | VersionPrerelease = "" 22 | 23 | // PluginVersion is used by the plugin set to allow Packer to recognize 24 | // what version this plugin is. 25 | PluginVersion = version.NewPluginVersion(Version, VersionPrerelease, "") 26 | ) 27 | -------------------------------------------------------------------------------- /test/alpine3.11/README.md: -------------------------------------------------------------------------------- 1 | # Alpine Linux Test 2 | 3 | ``` 4 | vagrant init alpine-3.9-x86_64 5 | ``` 6 | 7 | Start the box: 8 | 9 | ``` 10 | vagrant up 11 | ``` 12 | -------------------------------------------------------------------------------- /test/alpine3.11/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.configure(2) do |config| 5 | config.vm.define 'alpine39' do |alpine| 6 | alpine.vm.box = 'alpine-3.9-x86_64' 7 | alpine.vm.provider 'virtualbox' do |vb| 8 | vb.name = 'alpine3.9' 9 | vb.cpus = 1 10 | vb.memory = 1024 11 | vb.customize [ 12 | 'modifyvm', :id, 13 | '--natdnshostresolver1', 'on', 14 | '--nic1', 'nat', 15 | '--cableconnected1', 'on' 16 | ] 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /test/alpine3.11/alpine-3.11-x86_64.json: -------------------------------------------------------------------------------- 1 | { 2 | "builders": [ 3 | { 4 | "boot_command": [ 5 | "root", 6 | "ifconfig eth0 up \u0026\u0026 udhcpc -i eth0", 7 | "wget http://{{ .HTTPIP }}:{{ .HTTPPort }}/answers", 8 | "setup-alpine -f $PWD/answers", 9 | "{{user `root_password`}}", 10 | "{{user `root_password`}}", 11 | "y", 12 | "", 13 | "reboot", 14 | "", 15 | "root", 16 | "{{user `root_password`}}", 17 | "echo http://dl-cdn.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories", 18 | "apk add sudo", 19 | "echo 'Defaults env_keep += \"http_proxy https_proxy\"' > /etc/sudoers.d/wheel", 20 | "echo '%wheel ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/wheel", 21 | "adduser {{user `ssh_username`}}", 22 | "{{user `ssh_password`}}", 23 | "{{user `ssh_password`}}", 24 | "adduser {{user `ssh_username`}} wheel", 25 | "apk add virtualbox-guest-additions virtualbox-guest-modules-virt", 26 | "" 27 | ], 28 | "boot_wait": "10s", 29 | "communicator": "ssh", 30 | "disk_size": "{{user `disk_size`}}", 31 | "guest_additions_mode": "disable", 32 | "guest_os_type": "Linux26_64", 33 | "hard_drive_interface": "sata", 34 | "headless": false, 35 | "http_directory": "http", 36 | "iso_checksum": "sha256:86c511faf8232eace478760695f5dbeeb93a16003576317e16a9e3816355e6b7", 37 | "iso_urls": [ 38 | "isos/alpine-virt-3.11.6-x86_64.iso", 39 | "http://dl-cdn.alpinelinux.org/alpine/v3.11/releases/x86_64/alpine-virt-3.11.6-x86_64.iso" 40 | ], 41 | "shutdown_command": "echo {{user `ssh_password`}} | sudo -S /sbin/poweroff", 42 | "ssh_file_transfer_method": "scp", 43 | "ssh_password": "{{user `ssh_password`}}", 44 | "ssh_timeout": "10m", 45 | "ssh_username": "{{user `ssh_username`}}", 46 | "type": "virtualbox-iso", 47 | "vboxmanage": [ 48 | [ 49 | "modifyvm", 50 | "{{.Name}}", 51 | "--memory", 52 | "{{user `memory`}}" 53 | ], 54 | [ 55 | "modifyvm", 56 | "{{.Name}}", 57 | "--cpus", 58 | "{{user `cpus`}}" 59 | ] 60 | ], 61 | "virtualbox_version_file": ".vbox_version" 62 | } 63 | ], 64 | "description": "Build Alpine Linux x86_64", 65 | "post-processors": [ 66 | [ 67 | { 68 | "output": "output.box", 69 | "type": "vagrant", 70 | "vagrantfile_template": "Vagrantfile" 71 | } 72 | ] 73 | ], 74 | "provisioners": [ 75 | { 76 | "override": { 77 | "virtualbox-iso": { 78 | "execute_command": "/bin/sh '{{.Path}}'" 79 | } 80 | }, 81 | "scripts": [ 82 | "scripts/prepare.sh" 83 | ], 84 | "type": "shell" 85 | }, 86 | { 87 | "type": "cnspec", 88 | "asset_name": "my custom asset name", 89 | "on_failure": "continue" 90 | } 91 | ], 92 | "variables": { 93 | "cpus": "1", 94 | "disk_size": "10240", 95 | "memory": "1024", 96 | "root_password": "password!", 97 | "ssh_password": "vagrant", 98 | "ssh_username": "vagrant" 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /test/alpine3.11/http/answers: -------------------------------------------------------------------------------- 1 | KEYMAPOPTS="us us" 2 | HOSTNAMEOPTS="-n alpine311" 3 | INTERFACESOPTS="auto lo 4 | iface lo inet loopback 5 | 6 | auto eth0 7 | iface eth0 inet dhcp 8 | hostname alpine39 9 | " 10 | TIMEZONEOPTS="-z UTC" 11 | PROXYOPTS="none" 12 | APKREPOSOPTS="http://dl-cdn.alpinelinux.org/alpine/v3.11/main" 13 | SSHDOPTS="-c openssh" 14 | NTPOPTS="-c openntpd" 15 | DISKOPTS="-m sys /dev/sda" -------------------------------------------------------------------------------- /test/alpine3.11/scripts/prepare.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | set -ux 5 | 6 | # update all packages 7 | sudo apk update && apk upgrade 8 | 9 | # add ssh, bash for login and curl to fetch vagrant ssh key 10 | sudo apk add bash curl -------------------------------------------------------------------------------- /test/hcl-docker/docker-ubuntu.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | packer { 5 | required_plugins { 6 | docker = { 7 | version = ">= 0.0.7" 8 | source = "github.com/hashicorp/docker" 9 | } 10 | cnspec = { 11 | version = ">= 10.0.0" 12 | source = "github.com/mondoohq/cnspec" 13 | } 14 | } 15 | } 16 | 17 | source "docker" "ubuntu" { 18 | image = "ubuntu:xenial" 19 | commit = true 20 | } 21 | 22 | build { 23 | name = "learn-packer" 24 | sources = [ 25 | "source.docker.ubuntu" 26 | ] 27 | 28 | provisioner "cnspec" { 29 | on_failure = "continue" 30 | 31 | asset_name = "test-name" 32 | output = "compact" 33 | 34 | annotations = { 35 | name = "Packer Builder" 36 | custom_key = "custom_value" 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/hcl-virtualbox/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.configure(2) do |config| 5 | config.vm.define 'alpine39' do |alpine| 6 | alpine.vm.box = 'alpine-3.9-x86_64' 7 | alpine.vm.provider 'virtualbox' do |vb| 8 | vb.name = 'alpine3.9' 9 | vb.cpus = 1 10 | vb.memory = 1024 11 | vb.customize [ 12 | 'modifyvm', :id, 13 | '--natdnshostresolver1', 'on', 14 | '--nic1', 'nat', 15 | '--cableconnected1', 'on' 16 | ] 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /test/hcl-virtualbox/alpine.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | 5 | source "virtualbox-iso" "alpine" { 6 | iso_urls = [ 7 | "isos/alpine-virt-3.15.3-x86_64.iso", 8 | "http://dl-cdn.alpinelinux.org/alpine/v3.15/releases/x86_64/alpine-virt-3.15.3-x86_64.iso" 9 | ] 10 | iso_checksum = "sha256:b432eb9a71b7f5531cb7868c82f405cc63c052358698f44fbfe06103b40fa1bb" 11 | 12 | communicator = "ssh" 13 | ssh_username = var.sshusername 14 | ssh_password = var.sshpassword 15 | shutdown_command = "echo vagrant | sudo -S /sbin/poweroff" 16 | 17 | guest_additions_mode = "disable" 18 | guest_os_type = "Linux26_64" 19 | http_directory = "http" 20 | 21 | boot_wait = "10s" 22 | boot_command = [ 23 | "root", 24 | "ifconfig eth0 up && udhcpc -i eth0", 25 | "wget http://{{ .HTTPIP }}:{{ .HTTPPort }}/answers", 26 | "setup-alpine -f $PWD/answers", 27 | "${var.rootpassword}", 28 | "${var.rootpassword}", 29 | "y", 30 | "", 31 | "reboot", 32 | "", 33 | "root", 34 | "${var.rootpassword}", 35 | "echo http://dl-cdn.alpinelinux.org/alpine/v3.15/community/ >> /etc/apk/repositories", 36 | "apk add sudo", 37 | "echo 'Defaults env_keep += \"http_proxy https_proxy\"' > /etc/sudoers.d/wheel", 38 | "echo '%wheel ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/wheel", 39 | "adduser ${var.sshusername}", 40 | "${var.sshpassword}", 41 | "${var.sshpassword}", 42 | "adduser ${var.sshusername} wheel", 43 | "apk add virtualbox-guest-additions virtualbox-guest-additions-openrc", 44 | "" 45 | ] 46 | } 47 | 48 | build { 49 | sources = [ 50 | "source.virtualbox-iso.alpine", 51 | ] 52 | 53 | provisioner "shell" { 54 | scripts = [ 55 | "scripts/prepare.sh" 56 | ] 57 | } 58 | 59 | provisioner "cnspec" { 60 | on_failure = "continue" 61 | 62 | asset_name = "test-name" 63 | output = "json" 64 | score_threshold = 50 65 | 66 | annotations = { 67 | name = "Packer Builder" 68 | custom_key = "custom_value" 69 | } 70 | 71 | # enable sudo configuration 72 | # sudo { 73 | # active = true 74 | # } 75 | 76 | # use incognito to keep the report locally 77 | # incognito = true 78 | } 79 | 80 | post-processor "vagrant" { 81 | vagrantfile_template = "Vagrantfile" 82 | output = "output.box" 83 | } 84 | } -------------------------------------------------------------------------------- /test/hcl-virtualbox/http/answers: -------------------------------------------------------------------------------- 1 | KEYMAPOPTS="us us" 2 | HOSTNAMEOPTS="-n alpine" 3 | INTERFACESOPTS="auto lo 4 | iface lo inet loopback 5 | 6 | auto eth0 7 | iface eth0 inet dhcp 8 | hostname alpine 9 | " 10 | TIMEZONEOPTS="-z UTC" 11 | PROXYOPTS="none" 12 | APKREPOSOPTS="http://dl-cdn.alpinelinux.org/alpine/v3.15/main" 13 | SSHDOPTS="-c openssh" 14 | NTPOPTS="-c openntpd" 15 | DISKOPTS="-m sys /dev/sda" -------------------------------------------------------------------------------- /test/hcl-virtualbox/scripts/prepare.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | set -ux 5 | 6 | # update all packages 7 | sudo apk update && apk upgrade 8 | 9 | # add ssh, bash for login and curl to fetch vagrant ssh key 10 | sudo apk add bash curl -------------------------------------------------------------------------------- /test/hcl-virtualbox/variables.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | 5 | variable "rootpassword" { 6 | description = "root password" 7 | default = "password" 8 | type = string 9 | } 10 | 11 | variable "sshusername" { 12 | description = "ssh username" 13 | default = "vagrant" 14 | type = string 15 | } 16 | 17 | variable "sshpassword" { 18 | description = "ssh password" 19 | default = "vagrant" 20 | type = string 21 | } -------------------------------------------------------------------------------- /test/hcl-vmware-arm/alpine.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | packer { 5 | required_plugins { 6 | vmware = { 7 | version = ">= 1.0.0" 8 | source = "github.com/hashicorp/vmware" 9 | } 10 | cnspec = { 11 | version = ">= 10.0.0" 12 | source = "github.com/mondoohq/cnspec" 13 | } 14 | } 15 | } 16 | 17 | source "vmware-iso" "alpine" { 18 | iso_urls = [ 19 | "isos/alpine-virt-3.15.0-aarch64.iso", 20 | "http://dl-cdn.alpinelinux.org/alpine/v3.15/releases/aarch64/alpine-virt-3.15.0-aarch64.iso" 21 | ] 22 | iso_checksum = "sha256:f302cf1b2dbbd0661b8f53b167f24131c781b86ab3ae059654db05cd62d3c39c" 23 | 24 | communicator = "ssh" 25 | ssh_username = var.sshusername 26 | ssh_password = var.sshpassword 27 | shutdown_command = "echo vagrant | sudo -S /sbin/poweroff" 28 | 29 | http_directory = "http" 30 | 31 | boot_wait = "10s" 32 | boot_command = [ 33 | "root", 34 | "ifconfig eth0 up && udhcpc -i eth0", 35 | "wget http://{{ .HTTPIP }}:{{ .HTTPPort }}/answers", 36 | "setup-alpine -f $PWD/answers", 37 | "${var.rootpassword}", 38 | "${var.rootpassword}", 39 | "y", 40 | "", 41 | "reboot", 42 | "", 43 | "root", 44 | "${var.rootpassword}", 45 | "echo http://dl-cdn.alpinelinux.org/alpine/v3.16/community/ >> /etc/apk/repositories", 46 | "apk add sudo", 47 | "echo 'Defaults env_keep += \"http_proxy https_proxy\"' > /etc/sudoers.d/wheel", 48 | "echo '%wheel ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/wheel", 49 | "adduser ${var.sshusername}", 50 | "${var.sshpassword}", 51 | "${var.sshpassword}", 52 | "adduser ${var.sshusername} wheel", 53 | "apk add virtualbox-guest-additions virtualbox-guest-additions-openrc", 54 | "" 55 | ] 56 | 57 | guest_os_type = "arm-other5xlinux-64" 58 | 59 | version = "19" 60 | disk_adapter_type = "nvme" 61 | network_adapter_type = "e1000e" 62 | 63 | vmx_data = { 64 | "usb_xhci:4.present" = "TRUE" 65 | "usb:1.present" = "TRUE" 66 | } 67 | } 68 | 69 | build { 70 | sources = [ 71 | "source.vmware-iso.alpine", 72 | ] 73 | 74 | provisioner "shell" { 75 | scripts = [ 76 | "scripts/prepare.sh" 77 | ] 78 | } 79 | 80 | provisioner "cnspec" { 81 | on_failure = "continue" 82 | 83 | asset_name = "test-name" 84 | output = "json" 85 | score_threshold = 50 86 | 87 | annotations = { 88 | name = "Packer Builder" 89 | custom_key = "custom_value" 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /test/hcl-vmware-arm/http/answers: -------------------------------------------------------------------------------- 1 | KEYMAPOPTS="us us" 2 | HOSTNAMEOPTS="-n alpine" 3 | INTERFACESOPTS="auto lo 4 | iface lo inet loopback 5 | 6 | auto eth0 7 | iface eth0 inet dhcp 8 | hostname alpine 9 | " 10 | TIMEZONEOPTS="-z UTC" 11 | PROXYOPTS="none" 12 | APKREPOSOPTS="http://dl-cdn.alpinelinux.org/alpine/v3.15/main" 13 | SSHDOPTS="-c openssh" 14 | NTPOPTS="-c openntpd" 15 | DISKOPTS="-m sys /dev/sda" -------------------------------------------------------------------------------- /test/hcl-vmware-arm/scripts/prepare.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | set -ux 5 | 6 | # update all packages 7 | sudo apk update && apk upgrade 8 | 9 | # add ssh, bash for login and curl to fetch vagrant ssh key 10 | sudo apk add bash curl -------------------------------------------------------------------------------- /test/hcl-vmware-arm/variables.pkr.hcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | 5 | variable "rootpassword" { 6 | description = "root password" 7 | default = "password" 8 | type = string 9 | } 10 | 11 | variable "sshusername" { 12 | description = "ssh username" 13 | default = "vagrant" 14 | type = string 15 | } 16 | 17 | variable "sshpassword" { 18 | description = "ssh password" 19 | default = "vagrant" 20 | type = string 21 | } -------------------------------------------------------------------------------- /test/policybundle/centos-7.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": { 3 | "api_token": "{{env `DIGITALOCEAN_TOKEN`}}" 4 | }, 5 | "provisioners": [ 6 | { 7 | "type": "shell", 8 | "inline": [ 9 | "sudo yum -y update", 10 | "sudo yum -y upgrade", 11 | "sudo yum install -y https://repo.saltstack.com/py3/redhat/salt-py3-repo-latest.el7.noarch.rpm", 12 | "sudo yum clean expire-cache", 13 | "sudo yum install -y salt-master salt-minion salt-ssh salt-syndic salt-cloud salt-api", 14 | "sudo mkdir -p /etc/salt/minion_id", 15 | "sudo yum install -y nmap-ncat tmux bind-utils perl git", 16 | "sudo yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm", 17 | "sudo yum install jq -y", 18 | "mkdir -p /etc/ssh && echo 'WARNING' > /etc/ssh/sshd-banner", 19 | "echo 'Banner /etc/ssh/sshd-banner' >> /etc/ssh/sshd_config" 20 | ] 21 | }, 22 | { 23 | "type": "cnspec", 24 | "use_proxy": true, 25 | "incognito": true, 26 | "policybundle": "centos7-policy.yaml" 27 | } 28 | ], 29 | "builders": [ 30 | { 31 | "type": "digitalocean", 32 | "api_token": "{{user `api_token`}}", 33 | "image": "centos-7-x64", 34 | "ssh_username": "root", 35 | "region": "nyc1", 36 | "size": "s-4vcpu-8gb" 37 | } 38 | ] 39 | } -------------------------------------------------------------------------------- /test/policybundle/centos7-policy.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) Mondoo, Inc. 2 | # SPDX-License-Identifier: BUSL-1.1 3 | 4 | policies: 5 | - uid: custom-centos7-policy 6 | name: CentOS 7 Virtual Machine Configuration Policy 7 | version: 1.0.0 8 | authors: 9 | - name: Mondoo Inc 10 | email: hello@mondoo.io 11 | tags: 12 | date: 18-09-2020 13 | specs: 14 | - asset_filter: 15 | query: | 16 | platform.name == "centos" 17 | scoring_queries: 18 | verify-centos-version: 19 | verify-salt-configuration: 20 | tools-installed: 21 | verify-sshd-config: 22 | mount-fs-root: 23 | user-configuration: 24 | scoring_system: 2 25 | queries: 26 | - uid: verify-centos-version 27 | query: | 28 | platform.release == /7.9.2009/ 29 | - uid: salt-repo-and-package-installed 30 | title: Ensure the salt repo is configured and its package is installed 31 | query: | 32 | package('salt-minion').installed 33 | 34 | yum.repo('salt-latest') { 35 | enabled 36 | } 37 | - uid: verify-salt-configuration 38 | title: Ensure the Salt Minion is registered 39 | query: | 40 | file('/etc/salt/minion.d') { 41 | exists 42 | permissions.isDirectory 43 | } 44 | - uid: tools-installed 45 | title: Ensure standard tools are installed 46 | query: | 47 | package('nmap-ncat').installed 48 | package('tmux').installed 49 | package('bind-utils').installed 50 | package('perl').installed 51 | package('git').installed 52 | file('/usr/bin/jq').exists 53 | - uid: verify-sshd-config 54 | title: Ensure SSH Protocol and Banner are set correctly 55 | query: | 56 | // It's not configured by default as the default is version 2 57 | sshd.config.params['Protocol'] == null 58 | sshd.config.params['Protocol'] != 1 59 | 60 | // Check the ssh banner 61 | sshd.config.params['Banner'] == '/etc/ssh/sshd-banner' 62 | file('/etc/ssh/sshd-banner') { 63 | content == /WARNING/ 64 | } 65 | - uid: mount-fs-root 66 | title: Ensure correct settings for / partition 67 | query: | 68 | // ensure the mountpoint exists 69 | mount.one( path == "/" ) 70 | 71 | // check the configuration 72 | mount.where( path == "/" ).list { 73 | device == '/dev/vda1' 74 | fstype == 'xfs' 75 | 76 | options['rw'] != null 77 | options['relatime'] != null 78 | options['seclabel'] != null 79 | options['attr2'] != null 80 | options['inode64'] != null 81 | options['noquota'] != null 82 | } 83 | - uid: user-configuration 84 | title: Ensure the monitoring user exists and has a configured ssh public key setup 85 | query: | 86 | // ensure the user exists 87 | users.one( name == 'centos') 88 | 89 | // ensure we have authorized_keys 90 | user(name: 'centos').authorizedkeys.length == 1 91 | 92 | // ensure authorized file permissions 93 | user(name: 'centos').authorizedkeys.file { 94 | size > 128 95 | permissions { 96 | mode == 0600 97 | } 98 | user.name == 'centos' 99 | } 100 | 101 | // ensure the user can run sudo 102 | groups.where(name == 'wheel').list { members.one( name == 'centos') } -------------------------------------------------------------------------------- /tools.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Mondoo, Inc. 2 | // SPDX-License-Identifier: BUSL-1.1 3 | 4 | //go:build tools 5 | // +build tools 6 | 7 | package main 8 | 9 | import ( 10 | _ "github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc" 11 | ) 12 | --------------------------------------------------------------------------------