instruction: How do you create a custom composite action in GitHub Actions?
output: GitHub - hashicorp/setup-terraform: Sets up Terraform CLI in your GitHub Actions workflow. Skip to content Navigation Menu Toggle navigation Sign in Appearance settings Product GitHub Copilot Write better code with AI GitHub Spark New Build and deploy intelligent apps GitHub Models New Manage and compare prompts GitHub Advanced Security Find and fix vulnerabilities Actions Automate any workflow Codespaces Instant dev environments Issues Plan and track work Code Review Manage code changes Discussions Collaborate outside of code Code Search Find more, search less Explore Why GitHub All features Documentation GitHub Skills Blog Solutions By company size Enterprises Small and medium teams Startups Nonprofits By use case DevSecOps DevOps CI/CD View all use cases By industry Healthcare Financial services Manufacturing Government View all industries View all solutions Resources Topics AI DevOps Security Software Development View all Explore Learning Pathways Events &amp; Webinars Ebooks &amp; Whitepapers Customer Stories Partners Executive Insights Open Source GitHub Sponsors Fund open source developers The ReadME Project GitHub community articles Repositories Topics Trending Collections Enterprise Enterprise platform AI-powered developer platform Available add-ons GitHub Advanced Security Enterprise-grade security features Copilot for business Enterprise-grade AI features Premium Support Enterprise-grade 24/7 support Pricing Search or jump to... Search code, repositories, users, issues, pull requests... --> Search Clear Search syntax tips Provide feedback --> We read every piece of feedback, and take your input very seriously. Include my email address so I can be contacted Cancel Submit feedback Saved searches Use saved searches to filter your results more quickly --> Name Query To see all available qualifiers, see our documentation . Cancel Create saved search Sign in Sign up Appearance settings Resetting focus You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session. Dismiss alert {{ message }} hashicorp / setup-terraform Public Notifications You must be signed in to change notification settings Fork 258 Star 1.5k Sets up Terraform CLI in your GitHub Actions workflow. developer.hashicorp.com/terraform/tutorials/automation/github-actions License MPL-2.0 license 1.5k stars 258 forks Branches Tags Activity Star Notifications You must be signed in to change notification settings Code Issues 45 Pull requests 14 Actions Security Uh oh! There was an error while loading. Please reload this page . Insights Additional navigation options Code Issues Pull requests Actions Security Insights hashicorp/setup-terraform Use this GitHub action with your project Add this Action to an existing workflow or create a new one View on Marketplace main Branches Tags Go to file Code Open more actions menu Folders and files Name Name Last commit message Last commit date Latest commit History 294 Commits .changes .changes .github .github META.d META.d dist dist lib lib test test wrapper wrapper .changie.yaml .changie.yaml .copywrite.hcl .copywrite.hcl .gitignore .gitignore CHANGELOG.md CHANGELOG.md CODE_OF_CONDUCT.md CODE_OF_CONDUCT.md LICENSE LICENSE README.md README.md action.yml action.yml index.js index.js package-lock.json package-lock.json package.json package.json View all files Repository files navigation README Code of conduct MPL-2.0 license Security 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 -input=false - name : Terraform Validate id : validate run : terraform validate -no-color - name : Terraform Plan id : plan run : terraform plan -no-color -input=false 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 }}\` &lt;details&gt;&lt;summary&gt;Validation Output&lt;/summary&gt; \`\`\`\n ${{ steps.validate.outputs.stdout }} \`\`\` &lt;/details&gt; #### Terraform Plan 📖\`${{ steps.plan.outcome }}\` &lt;details&gt;&lt;summary&gt;Show Plan&lt;/summary&gt; \`\`\`\n ${process.env.PLAN} \`\`\` &lt;/details&gt; *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 -input=false - name : Terraform Validate id : validate run : terraform validate -no-color - name : Terraform Plan id : plan run : terraform plan -no-color -input=false 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 =&gt; { return comment.user.type === 'Bot' &amp;&amp; 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 }}\` &lt;details&gt;&lt;summary&gt;Validation Output&lt;/summary&gt; \`\`\`\n ${{ steps.validate.outputs.stdout }} \`\`\` &lt;/details&gt; #### Terraform Plan 📖\`${{ steps.plan.outcome }}\` &lt;details&gt;&lt;summary&gt;Show Plan&lt;/summary&gt; \`\`\`\n ${process.env.PLAN} \`\`\` &lt;/details&gt; *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: "&lt;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. About Sets up Terraform CLI in your GitHub Actions workflow. developer.hashicorp.com/terraform/tutorials/automation/github-actions Resources Readme License MPL-2.0 license Code of conduct Code of conduct Security policy Security policy Uh oh! There was an error while loading. Please reload this page . Activity Custom properties Stars 1.5k stars Watchers 20 watching Forks 258 forks Report repository Releases 17 v3.1.2 Latest Aug 19, 2024 + 16 releases Packages 0 No packages published Uh oh! There was an error while loading. Please reload this page . Contributors 44 + 30 contributors Languages JavaScript 97.5% HCL 2.5% Footer &copy; 2025 GitHub,&nbsp;Inc. Footer navigation Terms Privacy Security Status Docs Contact Manage cookies Do not share my personal information You can’t perform that action at this time.