Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

terraform init for apply pipeline fails when using modules inside same repo #1586

Open
rochana-atapattu opened this issue Mar 14, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@rochana-atapattu
Copy link
Contributor

rochana-atapattu commented Mar 14, 2024

tfaction version

1.2.3

Overview

I have modules in the same repo

module "actions_service_accounts" {
  source = "git::https://github.com/org/infrastructure//modules/gh-oidc?ref=gh-oidc-0.1.4"
...
}

the plan step works but when applying the pipeline terraform init fails

How to reproduce

tfaction-root.yaml

tfaction.yaml

GitHub Actions Workflow

---
name: apply
on:
  push:
    branches: [main]
env:
  TFACTION_IS_APPLY: 'true'
jobs:
  setup:
    runs-on: ubuntu-latest
    permissions:
      contents: read # For checkout a private repository
      pull-requests: write # For ci-info and github-comment
    outputs:
      targets: ${{ steps.list-targets.outputs.targets }}
    steps:
      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
      - uses: aquaproj/aqua-installer@7c7338067bdb97d5bea2acc82b5870afca470d18 # v2.3.0
        with:
          aqua_version: v2.24.0

      - uses: suzuki-shunsuke/tfaction/list-targets@72536e0b22961437dbca58cb4f3ea20a6b50b58f # v1.2.1
        id: list-targets

  apply:
    name: "apply (${{matrix.target.target}})"
    runs-on: ${{matrix.target.runs_on}}
    needs: setup
    # if services is empty, the build job is skipped
    if: "join(fromJSON(needs.setup.outputs.targets), '') != ''"
    strategy:
      fail-fast: false
      matrix:
        target: ${{fromJSON(needs.setup.outputs.targets)}}
    env:
      TFACTION_TARGET: ${{matrix.target.target}}
      TFACTION_JOB_TYPE: ${{matrix.target.job_type}}
    permissions:
      id-token: write # For OIDC
      contents: read # To checkout a private repository
    steps:
      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

      - name: Generate token for aqua-installer
        id: aqua_installer_token
        uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.APP_PRIVATE_KEY }}
          # If you use private registries, contents:read is required
          permissions: >-
            {}
          # If you use private registries, please add private repositories
          repositories: >-
            []

      - uses: aquaproj/aqua-installer@7c7338067bdb97d5bea2acc82b5870afca470d18 # v2.3.0
        with:
          aqua_version: v2.24.0
        env:
          AQUA_GITHUB_TOKEN: ${{ steps.aqua_installer_token.outputs.token }}

      - uses: suzuki-shunsuke/tfaction/export-secrets@72536e0b22961437dbca58cb4f3ea20a6b50b58f # v1.2.1
        with:
          secrets: ${{ toJSON(secrets) }}

      - name: Generate token to download private Terraform Modules
        id: gh_setup_token
        uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.APP_PRIVATE_KEY }}
          # If you use private registries, contents:read is required
          permissions: >-
            {
              "contents": "read"
            }
          # private repositories hosting private modules
          repositories: >-
            [
              "${{github.event.repository.name}}"
            ]

      # This is required to download private modules in `terraform init`
      - run: gh auth setup-git
        env:
          GITHUB_TOKEN: ${{ steps.gh_setup_token.outputs.token }}

      - name: Generate token to update drift issues
        id: drift_issue_token
        uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.APP_PRIVATE_KEY }}
          # issues:write - Create and update drift issues
          permissions: >-
            {
              "issues": "write"
            }
          # GitHub Repository where Drift Detection issues are hosted
          # https://suzuki-shunsuke.github.io/tfaction/docs/feature/drift-detection
          repositories: >-
            [
              "${{github.event.repository.name}}"
            ]

      - run: tfaction get-or-create-drift-issue
        shell: bash
        env:
          GITHUB_TOKEN: ${{ steps.drift_issue_token.outputs.token }}

      - name: Generate token for setup
        id: setup_token
        uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.APP_PRIVATE_KEY }}
          # pull_requests:write - Post comments
          # issues:write - Update drift issues
          permissions: >-
            {
              "pull_requests": "write",
              "issues": "write"
            }
          repositories: >-
            [
              "${{github.event.repository.name}}"
            ]

      - uses: suzuki-shunsuke/tfaction/setup@72536e0b22961437dbca58cb4f3ea20a6b50b58f # v1.2.1
        with:
          github_token: ${{ steps.setup_token.outputs.token }}
          ssh_key: ${{ secrets.TERRAFORM_PRIVATE_MODULE_SSH_KEY }} # This isn't needed if you don't use SSH key to checkout private Terraform Modules

      - name: Generate token for apply
        id: apply_token
        uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.APP_PRIVATE_KEY }}
          # pull_requests:write - Post comments
          # actions:read - Download plan files
          # issues:write - Update drift issues
          # contents:write - Update related pull requests
          permissions: >-
            {
              "pull_requests": "write",
              "actions": "read",
              "contents": "write",
              "issues": "write"
            }
          repositories: >-
            [
              "${{github.event.repository.name}}"
            ]

      - uses: suzuki-shunsuke/tfaction/apply@72536e0b22961437dbca58cb4f3ea20a6b50b58f # v1.2.1
        with:
          github_token: ${{ steps.apply_token.outputs.token }}

      - name: Generate token for creating follow up pr
        id: follow_up_pr_token
        if: failure()
        uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.APP_PRIVATE_KEY }}
          # contents:write - Push commits
          # pull_requests:write - Create a pull request
          permissions: >-
            {
              "contents": "write",
              "pull_requests": "write"
            }
          repositories: >-
            [
              "${{github.event.repository.name}}"
            ]

      - uses: suzuki-shunsuke/tfaction/create-follow-up-pr@72536e0b22961437dbca58cb4f3ea20a6b50b58f # v1.2.1
        if: failure()
        with:
          github_token: ${{steps.follow_up_pr_token.outputs.token}}

      - uses: suzuki-shunsuke/tfaction/update-drift-issue@72536e0b22961437dbca58cb4f3ea20a6b50b58f # v1.2.1
        if: always()
        with:
          status: ${{job.status}}
          github_token: ${{steps.drift_issue_token.outputs.token}}

Other related code such as local Registry


GitHub Actions' log

│ Error: Failed to download module
│ 
│   on main.tf line 31:
│   31: module "actions_service_accounts" {
│ 
│ Could not download module "actions_service_accounts" (main.tf:31) source
│ code from
│ "git::https://github.com/org/infrastructure?ref=gh-oidc-0.1.3":
│ error downloading
│ 'https://github.com/org/infrastructure?ref=gh-oidc-0.1.3':
│ /usr/bin/git exited with 128: Cloning into
│ '.terraform/modules/actions_service_accounts'...
│ remote: Repository not found.
│ fatal: repository 'https://github.com/org/infrastructure/' not
│ found
│ 
╵

run a command: exit status 1
Error: Process completed with exit code 1.

Expected behaviour

terraform inti in plan and apply pipelines should complete without error since we have

      - name: Generate token to download private Terraform Modules
        id: gh_setup_token
        uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.APP_PRIVATE_KEY }}
          # If you use private registries, contents:read is required
          permissions: >-
            {
              "contents": "read"
            }
          # private repositories hosting private modules
          repositories: >-
            []

      # This is required to download private modules in `terraform init`
      - run: gh auth setup-git
        env:
          GITHUB_TOKEN: ${{ steps.gh_setup_token.outputs.token }}

Actual behaviour

but it also seems to depend on

      - name: Generate token for setup
        id: setup_token
        uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.APP_PRIVATE_KEY }}
          # pull_requests:write - Post comments
          # issues:write - Update drift issues
          permissions: >-
            {
              "pull_requests": "write",
              "issues": "write",
              "contents": "read"
            }
          repositories: >-
            [
              "${{github.event.repository.name}}"
            ]

Important Factoids

No response

Note

to fix the issue i have to give content: read to

- name: Generate token for setup
        id: setup_token
        uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.APP_PRIVATE_KEY }}
          # pull_requests:write - Post comments
          # issues:write - Update drift issues
          permissions: >-
            {
              "pull_requests": "write",
              "issues": "write",
              "contents": "read"
            }
          repositories: >-
            [
              "${{github.event.repository.name}}"
            ]
@rochana-atapattu rochana-atapattu added the bug Something isn't working label Mar 14, 2024
@rochana-atapattu
Copy link
Contributor Author

rochana-atapattu commented Mar 14, 2024

weird thing is, i tried removing the follwoing block and leaving in the fix mentioned above. again the pipeline fails. seems like it needs both sections.

      - name: Generate token to download private Terraform Modules
        id: gh_setup_token
        uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.APP_PRIVATE_KEY }}
          # If you use private registries, contents:read is required
          permissions: >-
            {
              "contents": "read"
            }
          # private repositories hosting private modules
          repositories: >-
            []

      # This is required to download private modules in `terraform init`
      - run: gh auth setup-git
        env:
          GITHUB_TOKEN: ${{ steps.gh_setup_token.outputs.token }}

@suzuki-shunsuke
Copy link
Owner

suzuki-shunsuke commented Mar 14, 2024

Thank you for your feedback.

https://developer.hashicorp.com/terraform/language/modules/sources#generic-git-repository

Terraform installs modules from Git repositories by running git clone, and so it will respect any local Git configuration set on your system, including credentials.
To access a non-public Git repository, configure Git with suitable credentials for that repository.

I think a GitHub token set by gh auth setup-git is used.

Maybe a GitHub token set by actions/checkout action is used, but if so the access token should have contents:read permission because the module is hosted at the same repository.

According to the above code, a GitHub token set by gh auth setup-git has contents:read permission.
So it's weird.

@suzuki-shunsuke suzuki-shunsuke moved this to In Progress in main Mar 14, 2024
@rochana-atapattu
Copy link
Contributor Author

rochana-atapattu commented Mar 15, 2024

but the setup step was able to download modules when i gave content: read permissions to Generate token for setup

@suzuki-shunsuke
Copy link
Owner

Hmm. It's weird. I'm not sure why.
If we can reproduce the issue without tfaction, it would be helpful to understand the issue and we may be able to ask Terraform community for help.

@suzuki-shunsuke suzuki-shunsuke moved this from In Progress to Backlog in main Mar 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
No open projects
Status: Backlog
Development

No branches or pull requests

2 participants