Code Monkey home page Code Monkey logo

setup-terraform's Introduction

setup-terraform

Continuous Integration Setup Terraform

The hashicorp/setup-terraform action is a JavaScript action that sets up Terraform CLI in your GitHub Actions workflow by:

  • Downloading a specific version of Terraform CLI and adding it to the PATH.
  • Configuring the Terraform CLI configuration file with a HCP Terraform/Terraform Enterprise hostname and API token.
  • Installing a wrapper script to wrap subsequent calls of the terraform binary and expose its STDOUT, STDERR, and exit code as outputs named stdout, stderr, and exitcode respectively. (This can be optionally skipped if subsequent steps in the same job do not need to access the results of Terraform commands.)

After you've used the action, subsequent steps in the same job can run arbitrary Terraform commands using the GitHub Actions run syntax. This allows most Terraform commands to work exactly like they do on your local command line.

Usage

This action can be run on ubuntu-latest, windows-latest, and macos-latest GitHub Actions runners. When running on windows-latest the shell should be set to Bash. When running on self-hosted GitHub Actions runners, NodeJS must be previously installed with the version specified in the action.yml.

The default configuration installs the latest version of Terraform CLI and installs the wrapper script to wrap subsequent calls to the terraform binary:

steps:
- uses: hashicorp/setup-terraform@v3

A specific version of Terraform CLI can be installed:

steps:
- uses: hashicorp/setup-terraform@v3
  with:
    terraform_version: "1.1.7"

Credentials for HCP Terraform (app.terraform.io) can be configured:

steps:
- uses: hashicorp/setup-terraform@v3
  with:
    cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}

Credentials for Terraform Enterprise (TFE) can be configured:

steps:
- uses: hashicorp/setup-terraform@v3
  with:
    cli_config_credentials_hostname: 'terraform.example.com'
    cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}

The wrapper script installation can be skipped by setting the terraform_wrapper variable to false:

steps:
- uses: hashicorp/setup-terraform@v3
  with:
    terraform_wrapper: false

Subsequent steps can access outputs when the wrapper script is installed:

steps:
- uses: hashicorp/setup-terraform@v3

- run: terraform init

- id: plan
  run: terraform plan -no-color

- run: echo ${{ steps.plan.outputs.stdout }}
- run: echo ${{ steps.plan.outputs.stderr }}
- run: echo ${{ steps.plan.outputs.exitcode }}

Outputs can be used in subsequent steps to comment on the pull request:

Notice: There's a limit to the number of characters inside a GitHub comment (65535).

Due to that limitation, you might end up with a failed workflow run even if the plan succeeded.

Another approach is to append your plan into the $GITHUB_STEP_SUMMARY environment variable which supports markdown.

defaults:
  run:
    working-directory: ${{ env.tf_actions_working_dir }}
permissions:
  pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3

- name: Terraform fmt
  id: fmt
  run: terraform fmt -check
  continue-on-error: true

- name: Terraform Init
  id: init
  run: terraform init

- name: Terraform Validate
  id: validate
  run: terraform validate -no-color

- name: Terraform Plan
  id: plan
  run: terraform plan -no-color
  continue-on-error: true

- uses: actions/github-script@v7
  if: github.event_name == 'pull_request'
  env:
    PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    script: |
      const output = `#### Terraform Format and Style ๐Ÿ–Œ\`${{ steps.fmt.outcome }}\`
      #### Terraform Initialization โš™๏ธ\`${{ steps.init.outcome }}\`
      #### Terraform Validation ๐Ÿค–\`${{ steps.validate.outcome }}\`
      <details><summary>Validation Output</summary>

      \`\`\`\n
      ${{ steps.validate.outputs.stdout }}
      \`\`\`

      </details>

      #### Terraform Plan ๐Ÿ“–\`${{ steps.plan.outcome }}\`

      <details><summary>Show Plan</summary>

      \`\`\`\n
      ${process.env.PLAN}
      \`\`\`

      </details>

      *Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`, Working Directory: \`${{ env.tf_actions_working_dir }}\`, Workflow: \`${{ github.workflow }}\`*`;

      github.rest.issues.createComment({
        issue_number: context.issue.number,
        owner: context.repo.owner,
        repo: context.repo.repo,
        body: output
      })

Instead of creating a new comment each time, you can also update an existing one:

defaults:
  run:
    working-directory: ${{ env.tf_actions_working_dir }}
permissions:
  pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3

- name: Terraform fmt
  id: fmt
  run: terraform fmt -check
  continue-on-error: true

- name: Terraform Init
  id: init
  run: terraform init

- name: Terraform Validate
  id: validate
  run: terraform validate -no-color

- name: Terraform Plan
  id: plan
  run: terraform plan -no-color
  continue-on-error: true

- uses: actions/github-script@v7
  if: github.event_name == 'pull_request'
  env:
    PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    script: |
      // 1. Retrieve existing bot comments for the PR
      const { data: comments } = await github.rest.issues.listComments({
        owner: context.repo.owner,
        repo: context.repo.repo,
        issue_number: context.issue.number,
      })
      const botComment = comments.find(comment => {
        return comment.user.type === 'Bot' && comment.body.includes('Terraform Format and Style')
      })

      // 2. Prepare format of the comment
      const output = `#### Terraform Format and Style ๐Ÿ–Œ\`${{ steps.fmt.outcome }}\`
      #### Terraform Initialization โš™๏ธ\`${{ steps.init.outcome }}\`
      #### Terraform Validation ๐Ÿค–\`${{ steps.validate.outcome }}\`
      <details><summary>Validation Output</summary>

      \`\`\`\n
      ${{ steps.validate.outputs.stdout }}
      \`\`\`

      </details>

      #### Terraform Plan ๐Ÿ“–\`${{ steps.plan.outcome }}\`

      <details><summary>Show Plan</summary>

      \`\`\`\n
      ${process.env.PLAN}
      \`\`\`

      </details>

      *Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`, Working Directory: \`${{ env.tf_actions_working_dir }}\`, Workflow: \`${{ github.workflow }}\`*`;

      // 3. If we have a comment, update it, otherwise create a new one
      if (botComment) {
        github.rest.issues.updateComment({
          owner: context.repo.owner,
          repo: context.repo.repo,
          comment_id: botComment.id,
          body: output
        })
      } else {
        github.rest.issues.createComment({
          issue_number: context.issue.number,
          owner: context.repo.owner,
          repo: context.repo.repo,
          body: output
        })
      }

Inputs

The action supports the following inputs:

  • cli_config_credentials_hostname - (optional) The hostname of a HCP Terraform/Terraform Enterprise instance to place within the credentials block of the Terraform CLI configuration file. Defaults to app.terraform.io.
  • cli_config_credentials_token - (optional) The API token for a HCP Terraform/Terraform Enterprise instance to place within the credentials block of the Terraform CLI configuration file.
  • terraform_version - (optional) The version of Terraform CLI to install. Instead of a full version string, you can also specify a constraint string (see Semver Ranges for available range specifications). Examples are: "<1.2.0", "~1.1.0", "1.1.7" (all three installing the latest available 1.1 version). Prerelease versions can be specified and a range will stay within the given tag such as beta or rc. If no version is given, it will default to latest.
  • terraform_wrapper - (optional) Whether to install a wrapper to wrap subsequent calls of the terraform binary and expose its STDOUT, STDERR, and exit code as outputs named stdout, stderr, and exitcode respectively. Defaults to true.

Outputs

This action does not configure any outputs directly. However, when you set the terraform_wrapper input to true, the following outputs are available for subsequent steps that call the terraform binary:

  • stdout - The STDOUT stream of the call to the terraform binary.
  • stderr - The STDERR stream of the call to the terraform binary.
  • exitcode - The exit code of the call to the terraform binary.

License

Mozilla Public License v2.0

Code of Conduct

Code of Conduct

Experimental Status

By using the software in this repository (the "Software"), you acknowledge that: (1) the Software is still in development, may change, and has not been released as a commercial product by HashiCorp and is not currently supported in any way by HashiCorp; (2) the Software is provided on an "as-is" basis, and may include bugs, errors, or other issues; (3) the Software is NOT INTENDED FOR PRODUCTION USE, use of the Software may result in unexpected results, loss of data, or other unexpected results, and HashiCorp disclaims any and all liability resulting from use of the Software; and (4) HashiCorp reserves all rights to make all decisions about the features, functionality and commercial release (or non-release) of the Software, at any time and without any obligation or liability whatsoever.

Contributing

License Headers

All source code files (excluding autogenerated files like package.json, prose, and files excluded in .copywrite.hcl) must have a license header at the top.

This can be autogenerated by installing the HashiCorp copywrite tool and running copywrite headers in the root of the repository.

setup-terraform's People

Contributors

aeschright avatar alexjurkiewicz avatar austinvalle avatar bendbennett avatar bflad avatar bookshelfdave avatar brignano avatar chenrui333 avatar dannyibishev avatar dependabot[bot] avatar detro avatar hashicorp-tsccr[bot] avatar hc-github-team-tf-provider-devex avatar jpogran avatar krrrr38 avatar ksatirli avatar magnetikonline avatar ndrone-kr avatar nicklarsennz avatar ojford avatar paultyng avatar rabun788 avatar rdhar avatar rnsc avatar sbgoods avatar shouichi avatar skorfmann avatar skpy avatar sudomateo avatar tobiasbueschel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

setup-terraform's Issues

Run on self-hosted runner with GCS backend

I use a self-hosted Github Actions runner on a VM in GCP that is authorized to my GCS storage backend by its service account. This allows me to run terraform on the VM without providing credentials to access the bucket.

I would like to use the setup-terraform step in Github Actions to set up terraform and the wrapper (so the plan can be commented in the PR). I just use:

steps:
  - uses: hashicorp/setup-terraform@v1

This results in an error:

Error: (s || "").replace is not a function

I think this is solved when providing specific environment variables with credentials, but I don't want to provide credentials (they should not be needed).

Error: Error building ARM Config: Azure CLI Authorization Profile was not found. Please ensure the Azure CLI is installed and then log-in with `az login`.

Unable to authenticate properly to Azure within Github Actions when using an azurerm remote backend in Azure Storage Account. Secrets are configured correctly in Github Secrets. This config works properly when using local environment variables, but not on Actions runner.

Actions Output:

 Terraform Init

##[error]Process completed with exit code 1.
Run terraform init
/home/runner/work/_temp/6746c11e-1ad2-49cb-857f-24a8f9ce662e/terraform-bin init
Initializing modules...
- front_end_test in modules/front-end

Initializing the backend...
2020/07/30 20:11:57 [DEBUG] New state was assigned lineage "fd118fcc-47c8-e2c0-d946-8303a0d88c23"
2020/07/30 20:11:57 [DEBUG] Loading Environment "public"
2020/07/30 20:11:57 Testing if Service Principal / Client Certificate is applicable for Authentication..
2020/07/30 20:11:57 Testing if Multi Tenant Service Principal / Client Secret is applicable for Authentication..
2020/07/30 20:11:57 Testing if Service Principal / Client Secret is applicable for Authentication..
2020/07/30 20:11:57 Testing if Managed Service Identity is applicable for Authentication..
2020/07/30 20:11:57 Testing if Obtaining a token from the Azure CLI is applicable for Authentication..
2020/07/30 20:11:57 Using Obtaining a token from the Azure CLI for Authentication

Error: Error building ARM Config: Azure CLI Authorization Profile was not found. Please ensure the Azure CLI is installed and then log-in with `az login`.


##[error]Terraform exited with code 1.
##[error]Process completed with exit code 1.

Workflow:

name: Infrastructure CI

on:
  pull_request:
    branches:
    - master

env:
  ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
  ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
  ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
  ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}

jobs:
  terraform:
    name: 'Terraform'
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./infrastructure
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v1

      - name: Terraform Init
        run: terraform init
        
      - name: Terraform Plan
        run: terraform plan

TF backend config and provider config:

terraform {
  backend "azurerm" {
    resource_group_name  = "*****"
    storage_account_name = "*****"
    container_name       = "*****"
    key                  = "*****"
  }
}

provider "azurerm" {
    features {}
}

Missing documentation on how to pass variables to terraform

There is currently no documentation on how to pass variables to terraform.

Additionally, it seems like setting environment variables TF_VAR have no effect:

name: Production CI

env:
  TF_VAR_image_tag: ${{ github.sha }}

on:
  push:
    branches: [ master ]

jobs:
  provision:
    runs-on: ubuntu-latest

    steps:
    - name: Clone the repository code
      uses: actions/checkout@v2

    - name: Setup the Terraform CLI
      uses: hashicorp/setup-terraform@v1
      with:
        cli_config_credentials_token: ${{ secrets.TF_CREDENTIALS }}
      env:
        TF_VAR_image_tag: ${{ github.sha }}

    - name: Initialize the Terraform working directory
      working-directory: ./terraform
      id: init
      run: terraform init
      env:
        TF_VAR_image_tag: ${{ github.sha }}

    - name: Apply the Terraform execution plan
      working-directory: ./terraform
      id: plan
      run: terraform apply -auto-approve -no-color
      env:
        TF_VAR_image_tag: ${{ github.sha }}

Plan too long to be passed between steps

This example in the documentation often breaks down in real life. If the output from terraform plan is too big, it can't fit in an environment variable (which is how the documentation shows it being accessed).

The workaround we have found is to save the plan as a file, pass the filename, and then use terraform show -json $filename > plan.json to get the plan value in the second step. The problem we are having with this workaround is that the wrapper script breaks STDOUT.

Looks like the latest release (15 mins ago) has some issues?

Run hashicorp/setup-terraform@v1
internal/modules/cjs/loader.js:800
    throw err;
    ^

Error: Cannot find module 'asn1.js'
Require stack:
- /home/runner/work/_actions/hashicorp/setup-terraform/v1/dist/index.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:797:15)
    at Function.Module._load (internal/modules/cjs/loader.js:690:27)
    at Module.require (internal/modules/cjs/loader.js:852:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at o (/home/runner/work/_actions/hashicorp/setup-terraform/v1/dist/index.js:6804:200)
    at /home/runner/work/_actions/hashicorp/setup-terraform/v1/dist/index.js:6804:391
    at Object.<anonymous> (/home/runner/work/_actions/hashicorp/setup-terraform/v1/dist/index.js:37880:27)
    at Object.108.../../config (/home/runner/work/_actions/hashicorp/setup-terraform/v1/dist/index.js:38446:4)
    at o (/home/runner/work/_actions/hashicorp/setup-terraform/v1/dist/index.js:6804:340)
    at /home/runner/work/_actions/hashicorp/setup-terraform/v1/dist/index.js:6804:391 {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/home/runner/work/_actions/hashicorp/setup-terraform/v1/dist/index.js'
  ]
}

on side note how can i pin this to an older release?

sensitive values exposed

If an output marked as sensitive is specifically output, then the sensitive value is exposed in the workflow log.

For example, if I have the following outputs:

output "access_key_id" {
  value       = aws_iam_access_key.user.id
  description = "Access key id for test user"
  sensitive   = true
}

output "secret_access_key" {
  value       = aws_iam_access_key.user.secret
  description = "Secret access key for test user"
  sensitive   = true
}

I see the following output from terraform apply:

Outputs:

access_key_id = <sensitive>
secret_access_key = <sensitive>

However, if I try the following:

  - id: show-secret
    run: terraform output secret_access_key
  - run: |
      echo "::add-mask::${{ steps.show-secret.outputs.stdout }}"
      echo "${{ steps.show-secret.outputs.stdout }}"

I see the following output in the Actions log:

echo "::add-mask::<actual value>
  "
echo "<actual value>
  "

Consumers of this action are not able to mask the values themselves due to Github Actions' streaming output. According to this comment, this action would need to call set-mask before calling set-output.

Error: Error building AzureRM Client: Azure CLI Authorization Profile was not found

I tried to use this action to deploy the azure resources, but unfortunately i got the error information as below:


`Terraform v0.13.5
Configuring remote state backend...
Initializing Terraform configuration...
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

Error: Error building AzureRM Client: Azure CLI Authorization Profile was not found. Please ensure the Azure CLI is installed and then log-in with az login.

on provider.tf line 12, in provider "azurerm":
12: provider "azurerm"{

Error: Terraform exited with code 1.
Error: Process completed with exit code 1.`


i configure the environment variables in the github action yaml like this:


`jobs:
terraform:
name: 'Terraform'
runs-on: ubuntu-latest
defaults:
run:
shell: bash

env:
  ARM_CLIENT_ID: 'xxxxxxxxxxxxxxxxxxxxxxxx'
  ARM_CLIENT_SECRET: ${{ secrets.TF_ARM_CLIENT_SECRET }}
  ARM_SUBSCRIPTION_ID: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
  ARM_TENANT_ID: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'`

it seems like that the terraform plan command cannot get the environment variables i configured. but if i specify the azure config directly in the provider like below:


`provider "azurerm" {
version = "=2.4.0"
subscription_id = "00000000-0000-0000-0000-000000000000"
client_id = "00000000-0000-0000-0000-000000000000"
client_secret = var.client_secret
tenant_id = "00000000-0000-0000-0000-000000000000"

features {}
}`


the action will work well.
the question is why the terraform command "terraform apply" cannot get the environment variables?
thanks.

terraform init - `remote` backend with the `prefix` argument

I am using the remote backend (terraform cloud) with the prefix argument.

Main.tf -
terraform {
backend "remote" {
hostname = "app.terraform.io"
organization = "XYZ"
workspaces {
prefix = "action-workflow-"
}
}
}

Case-1:
terraform.yml -
name: 'Terraform Init'
run: terraform init

Workflow - gettting "The operation was canceled" as I am using prefix for workspace and need to select one. See below -

Run terraform init
/home/runner/work/_temp/75476658-e44d-420f-8a05-66e146748486/terraform-bin init

Initializing the backend...

Successfully configured the backend "remote"! Terraform will automatically
use this backend unless the backend configuration changes.

The currently selected workspace (default) does not exist.
This is expected behavior when the selected workspace did not have an
existing non-empty state. Please enter a number to select a workspace:

  1. terraform-azure
  2. tf-az

##[error]The operation was canceled.

Case-2:

Trying to pass argument and enviornemnt.

  • name: 'Terraform Init'
    run: terraform init
    with:
    args: '-backend-config="token=${{ secrets.TF_API_TOKEN }}" -backend-config="organization=XYZ"'
    env:
    TF_WORKSPACE: tf-az # suffix after action-workflow-, complete workspace name is action-workflow-tf-az

Workflow -
image

setup-terraform throws [error](s || "").replace is not a function

I tried switching to this action given that it it recently succeed terraform-github-actions. Unfortunately, I get this error:

  Run hashicorp/setup-terraform@v11s
##[error](s || "").replace is not a function
Run hashicorp/setup-terraform@v1
  with:
    terraform_version: 0.11.13
    cli_config_credentials_hostname: app.terraform.io
    terraform_wrapper: true
##[error](s || "").replace is not a function

Relevant config:

    - uses: hashicorp/setup-terraform@v1
      with:
        terraform_version: 0.11.13

I am not supplying credentials because I don't use Cloud/Enterprise, my backend is in S3. Terraform is given permission to access it via a self-hosted IAM runner, which worked fine with terraform-github-actions.

Am I correct in assuming that it is expecting a password? Just to clarify, this action doesn't only work for Cloud/Enterprise, does it? Supporting only one backend would be a dramatic reduction in utility from the now-unsupported version...

null_resource is not getting executed always

resource "null_resource" "getcreds" {

triggers = {
build_id = timestamp()
}

provisioner "local-exec" {
command = "az login --service-principal -u ${var.client_id} -p ${var.client_secret} --tenant ${var.tenant_id} && az aks get-credentials --resource-group ${azurerm_resource_group.rg.name} --name ${azurerm_kubernetes_cluster.aks.name}"
}
}

Bug: null_resource is not getting executed always. This is getting executed first time and then second time it says refreshing state even though triggger is set to run by current timestamp. Seeing this issue only in github actions. It works in Jenkins.

v1 tag does not point to the latest v1.2.1 release

It is typical for GitHub Actions to modify the v1 tag to point to the latest release in the v1.x.y release line to allow pegging a workflow to a major version of an action. This pulls in updates while not pulling in breaking changes (as may happen if depending on the @master ref).

I include this action in a workflow like

      - name: "Setup Terraform"
        uses: hashicorp/setup-terraform@v1

This setup doesn't pull in the fix for #63 and CVE-2020-15228.

How would you recommend depending on the latest, non-breaking changes to this action that does not require an update to workflow YAML every time a new version is release?

Unable to init with private repo modules

I have a terraform project that uses private repo modules. All of the repositories are under my organization's control and we have a CI Github user that is scoped sufficiently to clone these repos. My terraform init step is failing with output like:

Could not download module "nginx-ingress" (ingress.tf:9) source code from
"git::https://github.com/goodwatercap/terraform-goodwater-nginx-ingress.git":
error downloading
'https://github.com/goodwatercap/terraform-goodwater-nginx-ingress.git':
/usr/bin/git exited with 128: Cloning into
'.terraform/modules/nginx-ingress'...
fatal: could not read Username for 'https://github.com': No such device or
address

I'm not sure why this would be. I've instructed the checkout step to persist credentials. Does the specific form of git URL we've got there subvert that somehow? The failing workflow:

name: "[prod] terraform plan"

on:
  pull_request:
    branches:
      - prod

jobs:
  Terraform:
    defaults:
      run:
        working-directory: "."
    name: Terraform Plan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.CI_BOT_TOKEN }}
          persist-credentials: true

      - uses: hashicorp/setup-terraform@v1
        with:
          terraform_version: 0.12.25

      - name: Terraform Init
        id: init
        run: terraform init

I don't see in the project's documentation how to set the credentials explicitly. Is there a better way to write the module source URLs or this workflow to accomplish an init under these circumstances?

`terraform apply` happens even though there is no changes needed

๐Ÿ‘‹ I saw there is terraform apply even though there is no changes needed.

image

here is my workflow config:

      - name: Run terraform plan
        run: |
          cd module
          terraform plan -input=false -refresh -no-color
      - name: Run terraform apply
        if: github.ref == 'refs/heads/master'
        run: |
          cd module
          terraform apply -no-color -auto-approve

action in container

I want to start discussion about dockerizing this action. Currently this is running on runner context and it is running fine on GitHub hosted runners, issues incoming when we want to use self hosted runners, then some strict dependencies like NodeJS and etc are causing issues.

I know that those dependencies are available under:
https://github.com/actions/virtual-environments/blob/master/images/linux/Ubuntu1804-README.md

but this is huge list of software which we really dont want to install on our self hosted runners.

As per me best pattern for lightweight actions should be putting them in self-contained container.

Good example of such dockerized actions is https://github.com/Dirrk/terraform-docs where all dependencies are contained in container so self runner require just a docker to handle it.

This is not really issue, but rather proposal of changing architecture of this action to make it more available and remove 3rd party dependencies on runners.

Allow action to pick up version from project metadata

It would be nice to have the terraform action to use the version requirement stated in the terraform {} block. Something like TFEnv where we could state min-version for the version to use and it would refer to that value for the installation.

Perhaps we can even use TFEnv behind the scene in this action to not reinvent the wheel.

Solution for Terraform Output Command

I'm trying to find some recommendations on how to most effectively leverage the use of terraform output in GitHub Actions.

Problem

Our Terraform workflow is pretty straight forward, init -> plan -> apply -> output. However, when trying to set an output in GitHub Actions, the wrapper's invocation is instead set as the output.

Example:

- name: Terraform Output
  id: terraform-output
  run: echo "::set-output name=ingress::$(terraform output ingress)"

The value of ${{ steps.terraform-output.outputs.ingress }} ends up being "[command]/home/runner/work/_temp/297e1789-de2f-4ed5-ba5a-137f1a32e2ee/terraform-bin output ingress" which is incorrect.

Workaround

The solution I've seen is to add the terraform_wrapper: false option to the hashicorp/setup-terraform action. This does fix the issue, but now the step that comments on my PR no longer works because I can no longer access the stdout output since the wrapper is gone.

Problem with Workaround

I'd like to keep the functionality of being able to post a comment to my PR of the plan's results but also would like for terraform output to work. Is there an example or a recommendation on being able to accomplish both the PR comment and setting outputs with terraform output?

Terraform enterprise API calls

Any chance we can get support for terraform enterprise API calls?

I can use a remote backend to launch speculative plans using GitHub actions but this will not let me do an apply as itโ€™s not supported from the cli.

##[error](s || "").replace is not a function

Hi, trying the new action for setting up terraform.
Yaml:

  -
      name: Extract terraform version
      run: |
        echo ::set-env name=terraform_version::"$(./.github/extract-version.sh .github/terraform/go.mod | jq -r .version | cut -d v -f 1)"
        echo "terraform version is ${{ env.terraform_version }}"
    - 
      name: Setup terraform ${{ env.terraform_version }}
      uses: hashicorp/setup-terraform@v1
      with:
        terraform_version: ${{ env.terraform_version }}

But this results in:

Run hashicorp/setup-terraform@v1
  with:
    terraform_version: 1.13.0
    cli_config_credentials_hostname: app.terraform.io
    terraform_wrapper: true
  env:
    terraform_version: 1.13.0
    k8s_version: 1.18.3
##[error](s || "").replace is not a function

Any ideas?

Bring back (modified) terraform-github-actions

Please read in full before dismissing suggestion based on the title alone.

terraform-github-actions was justifiably obsoleted because it suffered from a few issues:

  • it downloaded terraform over and over in every step that used it (thus causing workflows that used multiple different terraform steps to take longer than necessary)
  • it was a Docker-based step, which added a slight penalty of requiring the image to be rebuild for every job.

However, the action also offered a number of benefits:

  • Proper usage of -detailed-exitcode and other flags, status code propagation, color removal, etc when handling command output
  • Built-in creation of GitHub PR comments

It made it really simple to build a PR review/approval workflow that is still challenging to build with setup-terraform alone (e.g. knowing when to set a step to continue-on-error: true, etc.).

Recent developments in the GH Actions world mean that the aforementioned issues can be addressed more elegantly today:

  • setup-terraform exists, which can be used to handle the installation of the binary (there are also alternatives out there, starting with the fact that terraform in preinstalled on the github hosted runners, or version management utilities like asdf exist).
  • GitHub introduced composite run steps, which makes it easy to implement a reusable step using bash without paying the Docker cost.

My proposal is thus to bring back terraform-github-actions with the following changes:

  • Remove the parts responsible for installing a particular version of terraform (including removing the tf_actions_version action argument)
  • Convert the action implementation to the "composite" type (instead of Docker-based), leaving the rest of the action input/output interface intact.

This way, we can chose to use the higher-level functionality of terraform-github-actions or invoke terraform directly via run steps.

Do not use deprecated set-env and add-path commands

Run hashicorp/[email protected]
/usr/bin/unzip /home/runner/work/_temp/2cc848c7-eab5-4ce6-9a15-8393203e756f
Archive:  /home/runner/work/_temp/2cc848c7-eab5-4ce6-9a15-8393203e756f
  inflating: terraform               
Error: Unable to process command '::set-env name=TERRAFORM_CLI_PATH::/home/runner/work/_temp/81d81b1c-0d05-40ce-95fb-41d0940c64c5' successfully.
Error: The `set-env` command is disabled. Please upgrade to using Environment Files or opt into unsecure command execution by setting the `ACTIONS_ALLOW_UNSECURE_COMMANDS` environment variable to `true`. For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/
Error: Unable to process command '::add-path::/home/runner/work/_temp/81d81b1c-0d05-40ce-95fb-41d0940c64c5' successfully.
Error: The `add-path` command is disabled. Please upgrade to using Environment Files or opt into unsecure command execution by setting the `ACTIONS_ALLOW_UNSECURE_COMMANDS` environment variable to `true`. For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/

Enabling Plugin Cache Directory

Description

We have a use case that requires running Terraform in a GitHub Action across multiple, separate configurations in the same repository. Since Terraform prefers to maintain its own plugin directory per directory, this leads to re-downloading (mostly the same) plugins for each separate directory. It would be great if there was the option to enable the plugin cache directory, which can be handled in the Terraform CLI configuration file via the plugin_cache_dir option, e.g. from the documentation:

plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"

Seems like it could be either a boolean where the GitHub Action maintains the directory location itself (enable_plugin_cache_dir: true) or allow configurations to provide it directly (plugin_cache_dir: /wherever/whenever), which might be useful for managed runners at the expense of being more complex. It seems like in either case, the GitHub Action would should try to create the directory, skipping errors for existing ones, as its prior existence is required.

Potential Workarounds

env:
  TF_PLUGIN_CACHE_DIR: ${{ github.workspace }}/.terraform.d/plugin-cache

jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
    # alternatively: run: mkdir -p $TF_PLUGIN_CACHE_DIR
    - uses: actions/cache@v1
      with:
        key: ${{ runner.os }}-terraform-plugin-cache
        path: ${{ env.TF_PLUGIN_CACHE_DIR }}
    - uses: actions/checkout@v2
    - uses: hashicorp/setup-terraform@v1
    - name: terraform
      run: |
        for DIR in $(find ./examples -type d); do
          pushd $DIR
          terraform init
          terraform fmt -check
          terraform validate
          popd
        done

References

tf plan fails - Error acquiring the state lock: resource not found

I set

      # Generates an execution plan for Terraform
      - name: Terraform Plan
        id: plan
        run: terraform plan
        env:
          TF_LOG: TRACE
action output
  Terraform Plan    1s

Run echo && cat /home/runner/.terraformrc && echo && terraform plan
  echo && cat /home/runner/.terraformrc && echo && terraform plan
  shell: /bin/bash --noprofile --norc -e -o pipefail {0}
  env:
    TERRAFORM_CLI_PATH: /home/runner/work/_temp/ee970212-8c4b-4fb5-9891-75dc348a3601
    TF_LOG: TRACE

credentials "app.terraform.io" {
  token = "***"
}

/home/runner/work/_temp/ee970212-8c4b-4fb5-9891-75dc348a3601/terraform-bin plan
2020/09/10 07:13:17 [INFO] Terraform version: 0.13.2  
2020/09/10 07:13:17 [INFO] Go runtime version: go1.14.7
2020/09/10 07:13:17 [INFO] CLI args: []string{"/home/runner/work/_temp/ee970212-8c4b-4fb5-9891-75dc348a3601/terraform-bin", "plan"}
2020/09/10 07:13:17 [DEBUG] Attempting to open CLI config file: /home/runner/.terraformrc
2020/09/10 07:13:17 Loading CLI configuration from /home/runner/.terraformrc
2020/09/10 07:13:17 [DEBUG] ignoring non-existing provider search directory terraform.d/plugins
2020/09/10 07:13:17 [DEBUG] ignoring non-existing provider search directory /home/runner/.terraform.d/plugins
2020/09/10 07:13:17 [DEBUG] ignoring non-existing provider search directory /home/runner/.local/share/terraform/plugins
2020/09/10 07:13:17 [DEBUG] ignoring non-existing provider search directory /usr/local/share/terraform/plugins
2020/09/10 07:13:17 [DEBUG] ignoring non-existing provider search directory /usr/share/terraform/plugins
2020/09/10 07:13:17 [INFO] CLI command args: []string{"plan"}
2020/09/10 07:13:17 [TRACE] Meta.Backend: built configuration for "remote" backend with hash value 3942427576
2020/09/10 07:13:17 [TRACE] Preserving existing state lineage "6ae12244-9f03-09ca-3e1e-7042f3a3fdc0"
2020/09/10 07:13:17 [TRACE] Preserving existing state lineage "6ae12244-9f03-09ca-3e1e-7042f3a3fdc0"
2020/09/10 07:13:17 [TRACE] Meta.Backend: working directory was previously initialized for "remote" backend
2020/09/10 07:13:17 [TRACE] Meta.Backend: using already-initialized, unchanged "remote" backend configuration
2020/09/10 07:13:17 [DEBUG] Service discovery for app.terraform.io at https://app.terraform.io/.well-known/terraform.json
2020/09/10 07:13:17 [TRACE] HTTP client GET request to https://app.terraform.io/.well-known/terraform.json
2020/09/10 07:13:17 [DEBUG] Retrieve version constraints for service tfe.v2.1 and product terraform
2020/09/10 07:13:17 [TRACE] HTTP client GET request to https://checkpoint-api.hashicorp.com/v1/versions/tfe.v2.1?product=terraform
2020/09/10 07:13:17 [TRACE] Meta.Backend: instantiated backend of type *remote.Remote
2020/09/10 07:13:17 [TRACE] providercache.fillMetaCache: scanning directory .terraform/plugins
2020/09/10 07:13:17 [TRACE] getproviders.SearchLocalDirectory: .terraform/plugins is a symlink to .terraform/plugins
2020/09/10 07:13:17 [TRACE] getproviders.SearchLocalDirectory: found registry.terraform.io/hashicorp/null v2.1.2 for linux_amd64 at .terraform/plugins/registry.terraform.io/hashicorp/null/2.1.2/linux_amd64
2020/09/10 07:13:17 [TRACE] getproviders.SearchLocalDirectory: found registry.terraform.io/hashicorp/tfe v0.21.0 for linux_amd64 at .terraform/plugins/registry.terraform.io/hashicorp/tfe/0.21.0/linux_amd64
2020/09/10 07:13:17 [TRACE] providercache.fillMetaCache: including .terraform/plugins/registry.terraform.io/hashicorp/null/2.1.2/linux_amd64 as a candidate package for registry.terraform.io/hashicorp/null 2.1.2
2020/09/10 07:13:17 [TRACE] providercache.fillMetaCache: including .terraform/plugins/registry.terraform.io/hashicorp/tfe/0.21.0/linux_amd64 as a candidate package for registry.terraform.io/hashicorp/tfe 0.21.0
2020/09/10 07:13:18 [TRACE] providercache.fillMetaCache: using cached result from previous scan of .terraform/plugins
2020/09/10 07:13:18 [DEBUG] checking for provisioner in "."
2020/09/10 07:13:18 [DEBUG] checking for provisioner in "/home/runner/work/_temp/ee970212-8c4b-4fb5-9891-75dc348a3601"
2020/09/10 07:13:18 [INFO] Failed to read plugin lock file .terraform/plugins/linux_amd64/lock.json: open .terraform/plugins/linux_amd64/lock.json: no such file or directory
2020/09/10 07:13:18 [TRACE] Meta.Backend: backend *remote.Remote supports operations
2020/09/10 07:13:18 [INFO] backend/local: starting Plan operation
2020/09/10 07:13:18 [TRACE] backend/local: requesting state manager for workspace "default"
2020/09/10 07:13:18 [TRACE] backend/local: requesting state lock for workspace "default"

Error: Error locking state: Error acquiring the state lock: resource not found

Terraform acquires a state lock to protect the state from being written
by multiple users at the same time. Please resolve the issue above and try
again. For most commands, you can disable locking with the "-lock=false"
flag, but this is not recommended.


##[error]Terraform exited with code 1.
##[error]Process completed with exit code 1.

Observations:

  • prior steps pass ok
  • API token look valid when i cat it (see auto-redacted log above)
  • I'm using the free tier of tf cloud right now
  • i'm able to plan/apply just fine from my local console using the same exact ~/.terraformrc file

Terraform setup uses 0.14.0 in github action

When running github actions with Setup terraform, hashicorp uses version 0.14.0 even though it is not released yet!
My cloud state bucket is now bricked!

# Install Terraform CLI
    - name: Setup Terraform
      uses: hashicorp/[email protected]

After running this github action I wanted to update the env. from dev machine. (as done before)

image

Version 0.14.0 is unavailable and not listed here:
https://www.terraform.io/downloads.html

0.14.0 Is stated as unreleased here:
https://github.com/hashicorp/terraform/releases

I know you can explicitly set version number for hashicorp/setup-terraform@v1. in github actions IE:

    - name: Setup Terraform
      uses: hashicorp/setup-terraform@v1
      with:
        terraform_version: 0.13.4

Regardless an unreleased and unavailable version should not be chosen as the default latest.

Deprecation warning for set-env

This action is now generating the following two deprecation notices:

Warning: The `set-env` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/
Warning: The `add-path` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/

Relevant portion of workflow yaml:

env:
  TERRAFORM_VERSION: 0.13.4

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: hashicorp/setup-terraform@v1
      with:
        terraform_version: ${{ env.TERRAFORM_VERSION }}

Unable to Use Custom Provider in Current Working Directory

I was unable to use a custom provider built in my current working directory. But, I was able to run it successfully on my local machine, and in GitHub Actions after installing Terraform manually. However, I'd really like to use this action instead! ๐Ÿ˜บ

Error

Using this workflow file I got the following error for the "Terraform Init" step:

Run terraform init
/home/runner/work/_temp/814bb1c2-7670-4133-aeae-b273f2121049/terraform-bin init

Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/port...

Error: Failed to install provider

Error while installing hashicorp/port: provider registry registry.terraform.io
does not have a provider named registry.terraform.io/hashicorp/port

##[error]Terraform exited with code 1.
##[error]Process completed with exit code 1.

๐Ÿค” Is there a trick for getting custom providers to work with this action, or a bug that's preventing Terraform from searching in my current working directory for providers?

Error refreshing state: state snapshot was created by Terraform v0.13.0, which is newer than current v0.12.28; upgrade to Terraform v0.13.0 or greater to work with this state

18 days ago I ran this plan and it initialized and deployed perfectly.

Today I couldn't access or make any changes on it. I am getting version mismatch error.

Somehow this script installed the BETA version 18 days ago, and initialized the plan using v13-beta and 18 days later you seem to have downgraded to v12. That looks like the reason.

I tried adding terraform_version: 0.13.0 to config, but it then started giving me (s || "").replace is not a function

I then installed the v13-beta3 locally to see if I can initialize that way.

This is the error I'm getting with v13-beta3

Error: Failed to decode current backend config

The backend configuration created by the most recent run of "terraform init"
could not be decoded: unsupported attribute "lock_table". The configuration
may have been initialized by an earlier version that used an incompatible
configuration structure. Run "terraform init -reconfigure" to force
re-initialization of the backend.

Finally I was able to init locally using v13-beta1.

How can I prevent this from happening in the future again?

Setup terraform Erro: ##[error](s || "").replace is not a function

Hi,
I hit the following error when running workflow in github. I am running it on self runner. Anyone can help?

 Run hashicorp/[email protected]
  with:
    cli_config_credentials_hostname: app.terraform.io
    terraform_version: latest
    terraform_wrapper: true
Latest version is 0.12.29
##[error](s || "").replace is not a function

My workflow file as below:

# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
#  push:
#    branches: [ master ]
#  pull_request:
#    branches: [ master ]
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: self-hosted

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
    # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
    - name: Checkout
      uses: actions/checkout@v2
    
    - name: HashiCorp - Setup Terraform
      uses: hashicorp/[email protected]

    - name: Terraform Init
      id: init
      run: terraform init

Migrating from terraform-github-actions with PR comment support is hard

I am trying to migrate from terraform-github-actions to take advantage of the speed increase of running Javascript-based actions and native commands over Docker-based actions. I am running into some trouble to replicate the functionality of automatic PR comments.

The Readme provides this as an equivalent example:

steps:
- uses: hashicorp/setup-terraform@v1

- run: terraform init

- id: plan
  run: terraform plan -no-color

- uses: actions/[email protected]
  if: github.event_name == 'pull_request'
  env:
    STDOUT: "```${{ steps.plan.outputs.stdout }}```"
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    script: |
      github.issues.createComment({
        issue_number: context.issue.number,
        owner: context.repo.owner,
        repo: context.repo.repo,
        body: process.env.STDOUT
      })

However this is not correct, as far as I can tell, due to a number of issues

  1. To be able to detect that a plan results in a change, you need to invoke run: terraform plan -no-color -detailed-exitcode.
  2. Then to ensure that a PR comment is emitted only if there's a change, you need to modify the condition to: if: github.event_name == 'pull_request' && steps.plan.outputs.exitcode == 2
  3. Of course, to be able to even run the PR comment step you need to make sure that the plan step doesn't return an error: run: terraform plan -no-color -detailed-exitcode || echo 0
  4. But you still want the job to fail if terraform plan returns code 1 in case there's a problem with the terraform files, maybe by adding if (${{ steps.plan.outputs.exitcode }} == 1) { core.setFailed("There's a problem with the plan"); } after the PR comment is created.

I can try to whip up a PR to try to at least improve the Readme, but I wanted to ask for some thoughts first on what the intended usage is.

unable to install google-beta provider

edit: I should add that I can run this provider locally with terraform just fine.

resource "google_container_cluster" "primary" {
  provider                 = google-beta
  project                  = var.project
  name                     = var.cluster_name
  location                 = "northamerica-northeast1-a"
  remove_default_node_pool = "true"
  network                  = var.network
  subnetwork               = var.subnetwork
  min_master_version       = var.min_master_version
  node_version             = var.node_version
  release_channel {
    channel = var.release_channel
  }
jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - uses: hashicorp/setup-terraform@v1

    - name: Terraform Init
      id: init
      run: terraform init
Initializing provider plugins...
- Finding latest version of hashicorp/google-beta...
- Finding latest version of hashicorp/google...
- Finding latest version of -/google...
- Finding latest version of -/google-beta...
- Installing hashicorp/google v3.26.0...
- Installed hashicorp/google v3.26.0 (signed by HashiCorp)
- Installing -/google v3.26.0...
- Installed -/google v3.26.0 (signed by HashiCorp)
- Installing -/google-beta v3.26.0...
- Installed -/google-beta v3.26.0 (signed by HashiCorp)

Error: Failed to install providers

Could not find required providers, but found possible alternatives:

  hashicorp/google-beta -> terraform-providers/google-beta

If these suggestions look correct, upgrade your configuration with the
following command:
    terraform 0.13upgrade .

##[error]Terraform exited with code 1.
##[error]Process completed with exit code 1.

Action fails behind the proxy

We are using self-hosted runners and trying to execute the action behind the corporate proxy

It fails with

Run hashicorp/setup-terraform@v1
##[error]Failed to fetch version metadata. FetchError: request to https://releases.hashicorp.com/terraform/index.json failed, reason: connect ETIMEDOUT 151.101.193.183:443
##[error](s || "").replace is not a function

I tried to declare standard http_proxy variables with

        env:
          http_proxy: http://<proxy_adress>:<port>
          https_proxy: http://<proxy_adress>:<port>

It didn't help apparently due to the node's fetch specifics which is used at

return fetch('https://releases.hashicorp.com/terraform/index.json')

Related upstream issue node-fetch/node-fetch#79

Reactions to ease of use with new actions workflow

From #7;

Migrating from terraform-github-actions with PR comment support is hard

yeah, this is hard alright.

My immediate reactions when working with this in order to get a good workflow:

  • I'm not sure it makes sense to split stdout and stderr into two different outputs. Errors reported from terraform fmt -check are printed to stdout, while terraform validate ends up in stderr. I would rather prefer everything ends up in a single output.

  • When we have to use continue-on-error in order to get the run results as a comment on the PR, an additional check is required to actually fail the actions run, which feels clunky

      - name: 'End results'
        shell: bash
        run: |
          echo fmt
          test ${{ steps.fmt.outputs.exitcode }} -eq 0
          echo init
          test ${{ steps.init.outputs.exitcode }} -eq 0
          echo validate
          test ${{ steps.validate.outputs.exitcode }} -eq 0
  • In our workflow, we want fmt, init and validate. For reference, this is what we end up with.
name: 'Terraform'

on:
  push:
    branches:
      - main
      - master
  pull_request:
    branches:
      - main
      - master

jobs:
  terraform:
    name: 'Terraform'
    runs-on: ubuntu-latest
    steps:
      - name: 'Checkout'
        uses: actions/checkout@v2

      - name: 'Setup'
        uses: hashicorp/setup-terraform@v1
        with:
          terraform_version: 0.13.4

      - name: 'Check formatting'
        id: fmt
        run: terraform fmt -check -recursive -list=true
        continue-on-error: true

      - name: 'Initialise'
        id: init
        run: terraform init -no-color
        continue-on-error: true

      - name: 'Validate'
        id: validate
        run: terraform validate -no-color
        continue-on-error: true

      - name: 'Post results as comment'
        uses: actions/github-script@v3
        if: github.event_name == 'pull_request'
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const CODE = '```';
            const output = `
            ### Terraform
            Format: **${{ steps.fmt.outcome }}**
            <details>
            <summary>Output</summary>

            ${CODE}
            # stdout
            ${{ steps.fmt.outputs.stdout }}
            ${CODE}

            </details>

            Init: **${{ steps.init.outcome }}**
            <details>
            <summary>Output</summary>

            ${CODE}
            # stderr
            ${{ steps.init.outputs.stderr }}
            ${CODE}

            </details>

            Validate: **${{ steps.validate.outcome }}**
            <details>
            <summary>Output</summary>

            ${CODE}
            # stderr
            ${{ steps.validate.outputs.stderr }}
            ${CODE}

            </details>`;

            github.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: output
            });

      - name: 'End results'
        shell: bash
        run: |
          echo fmt
          test ${{ steps.fmt.outputs.exitcode }} -eq 0
          echo init
          test ${{ steps.init.outputs.exitcode }} -eq 0
          echo validate
          test ${{ steps.validate.outputs.exitcode }} -eq 0

Which in turn posts a result like the below (when there are format and validation errors). As you can see, I have to add some placeholder content inside the code tags (#stdout) to prevent bad formatting in the rendered GitHub comment if there's no output at all.


Terraform

Format: failure

Output
# stdout
test.tf

Init: success

Output
# stderr

Validate: failure

Output
# stderr

Error: Unsupported attribute

  on siteshield/outputs.tf line 3, in output "cidr_list":
   3:   value       = data.external.cidr_list.resul

This object has no argument, nested block, or exported attribute named
"resul". Did you mean "result"?


Actions download latest-latest terraform

Current action downloads latest terraform binary regardless of it's stability- ie it downloads latest even it it's a beta release.
Which broke ~nearly-prod environment and required to destroy and reapply two major components in our infra and rotation of AWS IAM credentials for bot users used to apply the code.
Please fix it asap.

Terraform plan produces invalid out file

Hi,

I am trying to use the out file of terraform plan to convert to .json in order to apply some policy-as-code.

  • Terraform show -json out.file > out.file.json from the github action produces invalid JSON.
  • I am trying to use another tool called jfson that tells me the out file is not a valid plan file.

Anyone is able to produce a valid out file from this github action and convert to JSON?

TypeError: Cannot read property 'chmod' of undefined

We are using self-hosted runners and are unable to get this action to work. It seems to run the setup step, but fails with any terraform * action:

This could be related to #13, but I didn't see this specific error, so I'm not sure how we are to troubleshoot it.

Run terraform fmt .
  terraform fmt .
  shell: /bin/bash -e {0}
  env:
    TERRAFORM_CLI_PATH: /home/runner/_work/_temp/3a1a054c-4701-42f3-8dcd-5518d64d59b3
    GITHUB_TOKEN: ***
/home/runner/_work/_temp/3a1a054c-4701-42f3-8dcd-5518d64d59b3/terraform:1316
_a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
                                     ^

TypeError: Cannot read property 'chmod' of undefined
    at Object.672 (/home/runner/_work/_temp/3a1a054c-4701-42f3-8dcd-5518d64d59b3/terraform:1316:38)
    at __webpack_require__ (/home/runner/_work/_temp/3a1a054c-4701-42f3-8dcd-5518d64d59b3/terraform:23:30)
    at Object.1 (/home/runner/_work/_temp/3a1a054c-4701-42f3-8dcd-5518d64d59b3/terraform:65:16)
    at __webpack_require__ (/home/runner/_work/_temp/3a1a054c-4701-42f3-8dcd-5518d64d59b3/terraform:23:30)
    at Object.950 (/home/runner/_work/_temp/3a1a054c-4701-42f3-8dcd-5518d64d59b3/terraform:1552:12)
    at __webpack_require__ (/home/runner/_work/_temp/3a1a054c-4701-42f3-8dcd-5518d64d59b3/terraform:23:30)
    at startup (/home/runner/_work/_temp/3a1a054c-4701-42f3-8dcd-5518d64d59b3/terraform:38:19)
    at module.exports.1.P (/home/runner/_work/_temp/3a1a054c-4701-42f3-8dcd-5518d64d59b3/terraform:42:18)
    at Object.<anonymous> (/home/runner/_work/_temp/3a1a054c-4701-42f3-8dcd-5518d64d59b3/terraform:45:10)
    at Module._compile (module.js:652:30)
##[error]Process completed with exit code 1.

Support third party providers

Ok back to this one. With this new action, it's possible to now put third party providers in $HOME/.terraform.d/plugins.

Thanks

How do you export a generated ARN back to a github pipeline?

I'm working on a project using this library to set up my aws environment for a serverless-nextjs project. I would really love to be able to export some (or all) of the generated arns from the setup-terraform action to pass into my serverless command. This would automate my process much more and make it dynamic. Is this possible with this action?

If this is not possible with setup-terraform, does anyone know how I can through another github action/script to dynamically retrieve arns from my aws account?

If no-one wants to answer the second part I understand as it's unrelated to this repo so I can make a StackOverflow question for it. Just checking if any local experts know.

Thanks!
Matt Trachsel

Terraform Plan Pull Request Comment Incorrectly Formatted

Hi there,

I'm not sure if this is an issue with this action, however I wanted to point out that the example given in the docs of commenting on a PR from the output of the terraform plan step does not produce an output formatted correctly. More specifically, it appears the triple backticks are not working correctly to place the output in a code block (as seen below).
Screen Shot 2020-12-07 at 11 51 31 AM

This may be an issue with the github-script action this step uses, however I can't figure out the origin of the issue. For reference, here is my workflow file:

name: Dev

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

env:
  TF_WORKSPACE: dev

jobs:
  terraform:
    name: Terraform
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v1
        with:
          cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
          terraform_version: 0.13.2

      - name: Terraform format
        id: fmt
        run: terraform fmt -check

      - name: Terraform Init
        id: init
        run: terraform init

      - name: Terraform Validate
        id: validate
        run: terraform validate -no-color

      - name: Terraform Plan
        id: plan
        if: github.event_name == 'pull_request'
        run: terraform plan -no-color
        continue-on-error: true

      - name: Update Pull Request
        uses: actions/[email protected]
        if: github.event_name == 'pull_request'
        env:
          PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const output = `#### Terraform Format and Style ๐Ÿ–Œ\`${{ steps.fmt.outcome }}\`
            #### Terraform Initialization โš™๏ธ\`${{ steps.init.outcome }}\`
            #### Terraform Plan ๐Ÿ“–\`${{ steps.plan.outcome }}\`
            <details><summary>Show Plan</summary>
            ```${process.env.PLAN}```
            </details>
            *Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`;
              
            github.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: output
            })

      - name: Terraform Apply
        if: github.ref == 'refs/heads/master' && github.event_name == 'push'
        run: terraform apply -auto-approve

This is all pretty stock as far as I can tell. Any help here would be appreciated. Thanks!

Raw output when using wrapper with `$()` in bash

I was in the process of migrating our workflows to use this new action for setting up terraform when I ran into this... behavior? bug? I'm not sure what to call it.

When terraform_wrapper is set to true (the default behavior) in this action, it breaks what would be considered normal behavior in bash.

Take the following example from a step in a workflow:

- run: echo "credentials: $(terraform output my_arn)" > my_file.txt

The contents of the file created would be this:

credentials: [command]/home/runner/work/_temp/<some UUID>/terraform-bin output my_arn

Instead of the expected:

credentials: my_arn_value

The only way to fix this problem is to set terraform_wrapper to false. I'm not sure if this is something that can be fixed/changed? Otherwise, I think it would be a good idea to put this somewhere in the README.

/cc @petersin0422

Failed to instantiate provider "registry.terraform.io/hashicorp/google" to obtain schema: fork/exec

Unable to validate, this use to work.

    steps:
      - uses: actions/checkout@v2

      - uses: hashicorp/setup-terraform@v1

      - name: Terraform Init
        id: init
        run: terraform init

      - name: Terraform Validate
        id: validate
        run: terraform validate
Terraform Init
2s
commands will detect it and remind you to do so if necessary.
Run terraform init
/home/runner/work/_temp/2594f61b-3c27-488b-88c3-b3373e2b324c/terraform-bin init

Initializing the backend...

Initializing provider plugins...
- Using previously-installed hashicorp/google-beta v3.36.0
- Using previously-installed hashicorp/google v3.36.0

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, we recommend adding version constraints in a required_providers block
in your configuration, with the constraint strings suggested below.

* hashicorp/google: version = "~> 3.36.0"
* hashicorp/google-beta: version = "~> 3.36.0"

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.


Terraform Validate
1s
##[error]Process completed with exit code 1.

Error: Could not load plugin


Plugin reinitialization required. Please run "terraform init".

Plugins are external binaries that Terraform uses to access and manipulate
resources. The configuration provided requires plugins which can't be located,
don't satisfy the version constraints, or are otherwise incompatible.

Terraform automatically discovers provider requirements from your
configuration, including providers used in child modules. To see the
requirements and constraints, run "terraform providers".

2 problems:

- Failed to instantiate provider "registry.terraform.io/hashicorp/google" to
obtain schema: fork/exec
.terraform/plugins/registry.terraform.io/hashicorp/google/3.36.0/linux_amd64/terraform-provider-google_v3.36.0_x5:
permission denied
- Failed to instantiate provider "registry.terraform.io/hashicorp/google-beta"
to obtain schema: fork/exec
.terraform/plugins/registry.terraform.io/hashicorp/google-beta/3.36.0/linux_amd64/terraform-provider-google-beta_v3.36.0_x5:
permission denied


##[error]Terraform exited with code 1.
##[error]Process completed with exit code 1.

Unable to get recent versions with latest tag

When setting latest (or leaving it off), the action step is only pulling version 0.12.26:
Run hashicorp/setup-terraform@v1
Latest version is 0.12.26

Workflow pipeline yml:

  • name: "Terraform"
    uses: hashicorp/setup-terraform@v1
    with:
    terraform_version: latest

Run terraform init \ ...
Initializing modules...

  • vm in vm

Error: Unsupported Terraform Core version

This configuration does not support Terraform version 0.12.26. To proceed,
either choose another supported Terraform version or update the root module's
version constraint. Version constraints are normally set for good reason, so
updating the constraint may lead to other errors or unexpected behavior.

##[error]Terraform exited with code 1.
##[error]Process completed with exit code 1.

This was working yesterday without specifying a version. Wondering if the push last night affected this? Also tried to specify the version via the README instructions and get: (s || "").replace is not a function

@sudomateo

Plan comment on PR?

Since the old action is deprecated, how can I make the new action put a comment with output of terraform plan on my PR?

Bug: Wrapper does not forward the exit code correctly

In

// A non-zero exitCode is considered an error
if (exitCode !== 0) {
core.setFailed(`Terraform exited with code ${exitCode}.`);
}
a non-zero exit code is considered a failure. However, if you use terraform plan -detailed-exitcode you might be interested in exit code 2. But, since the wrapper just uses setFailed() the wrapper exits with 1.

Steps to reproduce

Have a terraform configuration where you have changes to the terraform state.

Add a github actions step with following configuration

shell: bash {0}
run: |
    terraform plan -detailed-exitcode
    echo $?

Expected result

Echo prints 2 to the log.

Actual result

Echo prints 1 to the log.

Workaround

Instead of using bash to read the exit code, create another step where you check ${{ steps.<step_id>.outputs.exitcode }}.

failed to pull google

anyone else experiencing this issue? it started earlier today. I have no issue pulling the provider locally

Error: Failed to query available provider packages

Could not retrieve the list of available versions for provider
hashicorp/google: no available releases match the given constraints ~> 3.45.0,
>= 3.43.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 3.43.*, <
4.0.*, >= 2.1.*, < 4.0.*, >= 3.8.*, < 4.0.*, >= 2.1.*, < 4.0.*, >= 2.1.*, <
4.0.*, >= 3.8.*, < 4.0.*, >= 2.1.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 3.50.*, <
4.0.*, >= 3.43.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 3.43.*,
< 4.0.*, >= 3.43.*, < 4.0.*, >= 2.1.*, < 4.0.*, >= 3.8.*, < 4.0.*, >= 2.1.*, <
4.0.*, >= 2.1.*, < 4.0.*, >= 3.8.*, < 4.0.*, >= 2.1.*, < 4.0.*, >= 2.1.*, <
4.0.*, >= 3.8.*, < 4.0.*, >= 2.1.*, < 4.0.*, ~> 3.5, ~> 3.5, >= 2.1.*, <
4.0.*, >= 3.8.*, < 4.0.*, >= 2.1.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 3.50.*, <
4.0.*, >= 3.43.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 2.1.*, <
4.0.*, >= 3.8.*, < 4.0.*, >= 2.1.*, < 4.0.*, >= 2.1.*, < 4.0.*, >= 3.8.*, <
4.0.*, >= 2.1.*, < 4.0.*, ~> 3.5, ~> 3.5, >= 3.43.*, < 4.0.*, >= 3.50.*, <
4.0.*, >= 3.43.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 2.1.*, <
4.0.*, >= 3.8.*, < 4.0.*, >= 2.1.*, < 4.0.*, >= 2.1.*, < 4.0.*, >= 3.8.*, <
4.0.*, >= 2.1.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 3.50.*, <
4.0.*, >= 3.43.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 3.50.*, < 4.0.*, >= 3.43.*,
< 4.0.*, >= 3.43.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 3.50.*, < 4.0.*, >=
3.43.*, < 4.0.*, >= 3.43.*, < 4.0.*, >= 2.1.*, < 4.0.*, >= 3.8.*, < 4.0.*, >=
2.1.*, < 4.0.*, ~> 3.38, >= 2.1.*, < 4.0.*, >= 3.8.*, < 4.0.*, >= 2.1.*, <
4.0.*

Error: Terraform exited with code 1.
Error: Process completed with exit code 1.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.