{"id":48661022,"url":"https://github.com/askb/packer-build-action","last_synced_at":"2026-04-10T10:09:33.304Z","repository":{"id":319430551,"uuid":"1078631216","full_name":"askb/packer-build-action","owner":"askb","description":"GitHub Action for building OpenStack images with Packer via bastion hosts","archived":false,"fork":false,"pushed_at":"2025-11-06T03:38:51.000Z","size":201,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-06T05:36:08.880Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/askb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-18T04:47:48.000Z","updated_at":"2025-11-06T03:38:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"0390b91f-58fe-4360-be55-6a4b48b08b04","html_url":"https://github.com/askb/packer-build-action","commit_stats":null,"previous_names":["askb/packer-build-action"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/askb/packer-build-action","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askb%2Fpacker-build-action","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askb%2Fpacker-build-action/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askb%2Fpacker-build-action/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askb%2Fpacker-build-action/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/askb","download_url":"https://codeload.github.com/askb/packer-build-action/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askb%2Fpacker-build-action/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31637769,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-10T07:40:12.752Z","status":"ssl_error","status_checked_at":"2026-04-10T07:40:11.664Z","response_time":98,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-10T10:09:32.876Z","updated_at":"2026-04-10T10:09:33.298Z","avatar_url":"https://github.com/askb.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Packer Build Action\n\nGitHub Action for validating and building OpenStack images using HashiCorp Packer through a Tailscale bastion host.\n\n## Features\n\n- 🔍 **Validate Mode**: Syntax-only validation (no credentials required)\n- 🔨 **Build Mode**: Full image builds via Tailscale bastion host\n- 📦 **Ansible Integration**: Automatic Ansible Galaxy role installation\n- 🔄 **Auto-discovery**: Finds Packer templates and var files automatically\n- 🌐 **Multi-cloud Ready**: Configurable for any OpenStack environment\n- 🔐 **OAuth Ephemeral Keys**: Uses Tailscale OAuth for secure, temporary connections\n\n## Architecture\n\nThis action works in conjunction with [tailscale-openstack-bastion-action](https://github.com/askb/tailscale-openstack-bastion-action) to:\n\n1. **Bastion Setup**: Creates an ephemeral OpenStack instance with Tailscale\n2. **Packer Build**: Executes Packer build through the bastion's secure tunnel\n3. **Cleanup**: Automatically tears down the bastion after build completion\n\n## Usage\n\n### Validate Packer Templates\n\nValidation mode performs syntax checking without requiring cloud credentials or a bastion:\n\n```yaml\n- name: Validate Packer templates\n  uses: lfreleng-actions/packer-build-action@v1\n  with:\n    mode: validate\n    packer_working_dir: packer\n```\n\n### Build Images with Bastion\n\nComplete workflow showing bastion setup, build, and teardown:\n\n```yaml\njobs:\n  build-image:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n\n      # Step 1: Setup bastion with Tailscale\n      - name: Setup bastion\n        id: bastion\n        uses: lfreleng-actions/tailscale-openstack-bastion-action@v1\n        with:\n          mode: setup\n          tailscale-oauth-client-id: ${{ secrets.TAILSCALE_OAUTH_CLIENT_ID }}\n          tailscale-oauth-secret: ${{ secrets.TAILSCALE_OAUTH_SECRET }}\n          openstack-auth-url: ${{ secrets.OPENSTACK_AUTH_URL }}\n          openstack-project-id: ${{ secrets.OPENSTACK_PROJECT_ID }}\n          openstack-username: ${{ secrets.OPENSTACK_USERNAME }}\n          openstack-password-b64: ${{ secrets.OPENSTACK_PASSWORD_B64 }}\n          openstack-region: ${{ secrets.OPENSTACK_REGION }}\n          bastion-name: \"packer-build-${{ github.run_id }}\"\n          bastion-flavor: \"v3-standard-2\"\n          bastion-image: \"Ubuntu 22.04.5 LTS (x86_64) [2025-03-27]\"\n          bastion-network: \"your-network-name\"\n\n      # Step 2: Build with Packer\n      - name: Build image\n        uses: lfreleng-actions/packer-build-action@v1\n        with:\n          mode: build\n          bastion_ip: ${{ steps.bastion.outputs.bastion_ip }}\n          bastion_ssh_user: ${{ steps.bastion.outputs.bastion_ssh_user }}\n          packer_template: templates/builder.pkr.hcl\n          packer_vars_file: vars/ubuntu-22.04.pkrvars.hcl\n          openstack_auth_url: ${{ secrets.OPENSTACK_AUTH_URL }}\n          openstack_project_id: ${{ secrets.OPENSTACK_PROJECT_ID }}\n          openstack_username: ${{ secrets.OPENSTACK_USERNAME }}\n          openstack_password: ${{ secrets.OPENSTACK_PASSWORD }}\n          openstack_network_id: ${{ secrets.OPENSTACK_NETWORK_ID }}\n\n      # Cleanup bastion\n      - name: Teardown bastion\n        if: always()\n        uses: lfreleng-actions/openstack-bastion-action@v1\n        with:\n          mode: teardown\n          bastion_id: ${{ steps.bastion.outputs.bastion_id }}\n          openstack_auth_url: ${{ secrets.OPENSTACK_AUTH_URL }}\n          openstack_project_id: ${{ secrets.OPENSTACK_PROJECT_ID }}\n          openstack_username: ${{ secrets.OPENSTACK_USERNAME }}\n          openstack_password: ${{ secrets.OPENSTACK_PASSWORD }}\n```\n\n## Inputs\n\n### Required Inputs\n\n| Input  | Description                           | Default    |\n| ------ | ------------------------------------- | ---------- |\n| `mode` | Operation mode: `validate` or `build` | `validate` |\n\n### Build Mode Required Inputs\n\n| Input                  | Description                              |\n| ---------------------- | ---------------------------------------- |\n| `bastion_ip`           | Bastion Tailscale IP from bastion action |\n| `openstack_auth_url`   | OpenStack authentication URL             |\n| `openstack_project_id` | OpenStack project/tenant ID              |\n| `openstack_username`   | OpenStack username                       |\n| `openstack_password`   | OpenStack password                       |\n| `openstack_network_id` | OpenStack network UUID                   |\n\n### Optional Inputs\n\n| Input                | Description               | Default       |\n| -------------------- | ------------------------- | ------------- |\n| `packer_template`    | Path to Packer template   | Auto-discover |\n| `packer_vars_file`   | Path to vars file         | Auto-discover |\n| `packer_working_dir` | Working directory         | `.`           |\n| `path_prefix`        | Path prefix for execution | `target-repo` |\n| `packer_version`     | Packer version            | `1.11.2`      |\n| `ansible_version`    | Ansible version           | `2.17.0`      |\n| `python_version`     | Python version            | `3.11`        |\n| `bastion_ssh_user`   | SSH user for bastion      | `ubuntu`      |\n\n## Outputs\n\n| Output              | Description                   |\n| ------------------- | ----------------------------- |\n| `validation_result` | Validation result summary     |\n| `image_name`        | Built image name (build mode) |\n| `image_id`          | Built image ID (build mode)   |\n| `build_status`      | Build completion status       |\n\n## Requirements\n\n### For Validate Mode\n\n- Packer templates with valid HCL syntax\n- No credentials required\n\n### For Build Mode\n\n- Active bastion host (from `openstack-bastion-action`)\n- OpenStack credentials\n- Packer templates configured for OpenStack\n- Ansible roles (if using common-packer)\n\n## Project Structure\n\n```\npacker-build-action/\n├── action.yaml              # Action definition\n├── scripts/\n│   └── validate-packer.sh   # Validation script\n├── docs/\n│   ├── USAGE.md            # Detailed usage guide\n│   ├── PACKER_TEMPLATES.md # Template requirements\n│   └── TROUBLESHOOTING.md  # Common issues\n└── examples/\n    └── workflows/          # Example workflows\n```\n\n## Documentation\n\n- [Usage Guide](docs/USAGE.md) - Detailed usage instructions\n- [Packer Templates](docs/PACKER_TEMPLATES.md) - Template requirements\n- [Troubleshooting](docs/TROUBLESHOOTING.md) - Common issues and solutions\n- [Development](docs/DEVELOPMENT.md) - Contributing guide\n\n## Test Workflows\n\nThis repository includes test workflows for each Tailscale authentication method supported by the bastion action:\n\n### 1. OAuth with Ephemeral Keys (Recommended) ⭐\n\n**Workflow:** `.github/workflows/test-build-minimal.yaml`\n\n**Description:** Tests Packer build using Tailscale OAuth with ephemeral keys. This is the **recommended** authentication method for production use.\n\n**Status:** ✅ **WORKING** (as of 2025-10-21 after fixes to `openstack-bastion-action`)\n\n**Benefits:**\n\n- ✅ Automatic key rotation (no 90-day manual rotation like legacy auth keys)\n- ✅ Better security (keys expire automatically)\n- ✅ No manual key management\n- ✅ Persistent nodes (survive network disconnects)\n- ✅ Production-ready\n\n**Recent Fixes (2025-10-21):**\nThe `openstack-bastion-action` dependency was updated with two critical fixes:\n\n1. Changed `EPHEMERAL=false` - Creates persistent nodes instead of auto-removed ephemeral nodes\n2. Changed runner tags to `tag:ci` - Correct ACL permissions for GitHub Actions runner\n\nThese fixes ensure OAuth ephemeral authentication works reliably for production workloads.\n\n**Bastion Configuration:**\n\n```yaml\ntailscale_oauth_client_id: ${{ secrets.TAILSCALE_OAUTH_CLIENT_ID }}\ntailscale_oauth_secret: ${{ secrets.TAILSCALE_OAUTH_SECRET }}\ntailscale_use_ephemeral_keys: \"true\" # Generates OAuth ephemeral keys\ntailscale_tags: \"tag:bastion\" # Required for proper ACL permissions\n```\n\n**Required Secrets:**\n\n- `TAILSCALE_OAUTH_CLIENT_ID`\n- `TAILSCALE_OAUTH_SECRET`\n\n---\n\n### 2. OAuth with Reusable Keys ⚠️ **NOT SUPPORTED**\n\n**Workflow:** `.github/workflows/test-build-oauth-reusable.yaml` **[DISABLED]**\n\n**Status:** ❌ **This authentication method is currently not supported by the bastion action.**\n\n**Reason:** The bastion VM uses cloud-init to configure Tailscale, and cloud-init cannot use OAuth directly. OAuth with reusable keys (ephemeral=false) requires direct OAuth authentication which is not possible in the cloud-init environment.\n\n**Alternatives:**\n\n- Use **OAuth with Ephemeral Keys** (recommended) - generates temporary keys from OAuth\n- Use **Legacy Auth Key** - uses pre-created Tailscale auth key\n\n**Technical Details:**\n\n```yaml\n# This configuration will FAIL:\ntailscale_oauth_client_id: ${{ secrets.TAILSCALE_OAUTH_CLIENT_ID }}\ntailscale_oauth_secret: ${{ secrets.TAILSCALE_OAUTH_SECRET }}\ntailscale_use_ephemeral_keys: \"false\" # ❌ Not supported for bastion\n```\n\n**Error Message:**\n\n```\nError: OAuth without ephemeral keys is not supported for bastion hosts\nThe bastion (cloud-init) cannot use OAuth directly.\n```\n\nThe workflow file is kept for reference but is disabled (no auto-triggers) and will always fail.\n\n---\n\n### 3. Legacy Auth Key (Deprecated)\n\n**Workflow:** `.github/workflows/test-build-authkey.yaml`\n\n**Description:** Tests Packer build using the legacy Tailscale auth key method. This method is **deprecated** but still supported for backwards compatibility.\n\n**Bastion Configuration:**\n\n```yaml\ntailscale_auth_key: ${{ secrets.TAILSCALE_AUTH_KEY }}\n```\n\n**Required Secrets:**\n\n- `TAILSCALE_AUTH_KEY`\n\n**Note:** OAuth methods are recommended over legacy auth keys.\n\n---\n\n### Running Tests\n\n**Via GitHub UI:**\n\n1. Go to the Actions tab\n2. Select the workflow you want to run\n3. Click \"Run workflow\"\n4. Optionally customize inputs\n5. Click the \"Run workflow\" button\n\n**Via GitHub CLI:**\n\n```bash\n# OAuth Ephemeral (recommended)\ngh workflow run test-build-minimal.yaml\n\n# Legacy Auth Key\ngh workflow run test-build-authkey.yaml\n\n# OAuth Reusable - DISABLED (not supported, will fail)\n# gh workflow run test-build-oauth-reusable.yaml\n```\n\n---\n\n### Authentication Method Comparison\n\n| Method          | Security | Complexity | Supported | Recommended   | Key Management      |\n| --------------- | -------- | ---------- | --------- | ------------- | ------------------- |\n| OAuth Ephemeral | ⭐⭐⭐   | Low        | ✅ Yes    | ✅ Yes        | Automatic           |\n| OAuth Reusable  | ⭐⭐     | Low        | ❌ **No** | ❌ No         | N/A (not supported) |\n| Legacy Auth Key | ⭐       | Very Low   | ✅ Yes    | ⚠️ Deprecated | Manual rotation     |\n\n---\n\n### How Tailscale SSH Works with Packer\n\nThe two supported authentication methods (OAuth Ephemeral and Legacy Auth Key) result in the same SSH behavior:\n\n1. **Bastion Setup:** The bastion action sets up Tailscale on both the GitHub runner and the bastion instance\n2. **Network Join:** Both join the same Tailscale network using the chosen auth method\n3. **Packer Connection:** Packer uses `ssh_bastion_agent_auth = true` to satisfy its validation requirement\n4. **SSH Agent:** An empty SSH agent is started (required by Packer, even though not used)\n5. **Tailscale Intercept:** When Packer connects, Tailscale SSH intercepts and handles authentication automatically\n6. **No Traditional Keys:** No SSH private keys, passwords, or agent keys are needed\n\n**Key Insight:** The authentication method only affects how the runner and bastion join the Tailscale network, not how Packer connects through the bastion.\n\n---\n\n## Related Actions\n\n- [tailscale-openstack-bastion-action](https://github.com/askb/tailscale-openstack-bastion-action) - Bastion host management with Tailscale\n\n## Contributing\n\nWe welcome contributions! Please follow these guidelines:\n\n1. **Fork the repository**\n2. **Create a feature branch:** `git checkout -b feature/amazing-feature`\n3. **Commit your changes with DCO sign-off:** `git commit -s`\n4. **Push to the branch:** `git push origin feature/amazing-feature`\n5. **Open a Pull Request**\n\n### Commit Message Format\n\nFollow [Conventional Commits](https://www.conventionalcommits.org/):\n\n```\n\u003ctype\u003e: \u003cdescription\u003e\n\n[optional body]\n\nSigned-off-by: Your Name \u003cyour.email@example.com\u003e\n```\n\n**Types:** Feat, Fix, Chore, Docs, Style, Refactor, Perf, Test, CI, Build\n\n### Code Quality\n\n- Run `pre-commit run --all-files` before committing\n- Ensure all tests pass\n- Follow existing code style\n- Add tests for new features\n\n## License\n\nApache License 2.0 - see [LICENSE](LICENSE) for details.\n\nCopyright © 2025 The Linux Foundation\n\n## Support\n\nFor issues and questions:\n\n- GitHub Issues: [Report a bug](https://github.com/lfreleng-actions/packer-build-action/issues)\n- Documentation: [docs/](docs/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faskb%2Fpacker-build-action","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faskb%2Fpacker-build-action","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faskb%2Fpacker-build-action/lists"}