Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 19 additions & 52 deletions .github/workflows/terraform-apply.yml
Original file line number Diff line number Diff line change
@@ -1,73 +1,40 @@
name: 'Terraform Plan'
name: 'Terraform Apply'
on:
pull_request:
push:
branches:
- main

env:
TF_CLOUD_ORGANIZATION: "florenciacomuzzi-org"
TF_CLOUD_ORGANIZATION: "florenciacomuzzi-org" # template field
TF_API_TOKEN: "${{ secrets.TF_API_TOKEN }}"
TF_WORKSPACE: "production"
TF_WORKSPACE: "production" # template field
CONFIG_DIRECTORY: "./"
jobs:
terraform:
if: github.repository != 'hashicorp-education/learn-terraform-github-actions'
name: "Terraform Plan"
name: "Terraform Apply"
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Upload Configuration
uses: hashicorp/tfc-workflows-github/actions/upload-configuration@v1.0.0
id: plan-upload
id: apply-upload
with:
workspace: ${{ env.TF_WORKSPACE }}
directory: ${{ env.CONFIG_DIRECTORY }}
speculative: true
- name: Create Plan Run
- name: Create Apply Run
uses: hashicorp/tfc-workflows-github/actions/create-run@v1.0.0
id: plan-run
id: apply-run
with:
workspace: ${{ env.TF_WORKSPACE }}
configuration_version: ${{ steps.plan-upload.outputs.configuration_version_id }}
plan_only: true
- name: Get Plan Output
uses: hashicorp/tfc-workflows-github/actions/plan-output@v1.0.0
id: plan-output
configuration_version: ${{ steps.apply-upload.outputs.configuration_version_id }}
- name: Apply
uses: hashicorp/tfc-workflows-github/actions/apply-run@v1.0.0
if: fromJSON(steps.apply-run.outputs.payload).data.attributes.actions.IsConfirmable
id: apply
with:
plan: ${{ fromJSON(steps.plan-run.outputs.payload).data.relationships.plan.data.id }}
- name: Update PR
uses: actions/github-script@v6
id: plan-comment
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('HCP Terraform Plan Output')
});
const output = `#### HCP Terraform Plan Output
\`\`\`
Plan: ${{ steps.plan-output.outputs.add }} to add, ${{ steps.plan-output.outputs.change }} to change, ${{ steps.plan-output.outputs.destroy }} to destroy.
\`\`\`
[HCP Terraform Plan](${{ steps.plan-run.outputs.run_link }})
`;
// 3. Delete previous comment so PR timeline makes sense
if (botComment) {
github.rest.issues.deleteComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
});
}
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: output
});
run: ${{ steps.apply-run.outputs.run_id }}
comment: "Apply Run from GitHub Actions CI ${{ github.sha }}"
106 changes: 106 additions & 0 deletions .github/workflows/terraform-plan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: 'Terraform Plan'
on:
pull_request:
env:
TF_CLOUD_ORGANIZATION: "florenciacomuzzi-org" # template field
TF_API_TOKEN: "${{ secrets.TF_API_TOKEN }}"
TF_WORKSPACE: "production" # template field
CONFIG_DIRECTORY: "./"
jobs:
tflint:
name: "TFLint"
runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]

steps:
- uses: actions/checkout@v4
name: Checkout source code

- uses: actions/cache@v4
name: Cache plugin dir
with:
path: ~/.tflint.d/plugins
key: ${{ matrix.os }}-tflint-${{ hashFiles('.tflint.hcl') }}

- uses: terraform-linters/setup-tflint@v4
name: Setup TFLint
with:
tflint_version: v0.52.0
- name: Show version
run: tflint --version

- name: Init TFLint
run: tflint --init
env:
# https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/plugins.md#avoiding-rate-limiting
GITHUB_TOKEN: ${{ github.token }}

- name: Run TFLint
run: tflint -f compact
terraform:
if: github.repository != 'hashicorp-education/learn-terraform-github-actions'
name: "Terraform Plan"
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Upload Configuration
uses: hashicorp/tfc-workflows-github/actions/upload-configuration@v1.0.0
id: plan-upload
with:
workspace: ${{ env.TF_WORKSPACE }}
directory: ${{ env.CONFIG_DIRECTORY }}
speculative: true
- name: Create Plan Run
uses: hashicorp/tfc-workflows-github/actions/create-run@v1.0.0
id: plan-run
with:
workspace: ${{ env.TF_WORKSPACE }}
configuration_version: ${{ steps.plan-upload.outputs.configuration_version_id }}
plan_only: true
- name: Get Plan Output
uses: hashicorp/tfc-workflows-github/actions/plan-output@v1.0.0
id: plan-output
with:
plan: ${{ fromJSON(steps.plan-run.outputs.payload).data.relationships.plan.data.id }}
- name: Update PR
uses: actions/github-script@v6
id: plan-comment
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('HCP Terraform Plan Output')
});
const output = `#### HCP Terraform Plan Output
\`\`\`
Plan: ${{ steps.plan-output.outputs.add }} to add, ${{ steps.plan-output.outputs.change }} to change, ${{ steps.plan-output.outputs.destroy }} to destroy.
\`\`\`
[HCP Terraform Plan](${{ steps.plan-run.outputs.run_link }})
`;
// 3. Delete previous comment so PR timeline makes sense
if (botComment) {
github.rest.issues.deleteComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
});
}
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: output
});
33 changes: 33 additions & 0 deletions SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# florenciacomuzzi-site-terraform
This repository contains Terraform code to create a Linode instance and deploy a website to it.
The infrastructure is managed using Hashicorp Terraform Cloud.
Deployments are triggered from GitHub Actions workflows.

## Setting up your own project
* Login to Linode account.
* Create a personal access token. This secret is the value of "token" input variable of the Terraform module.


* Login to Terraform Cloud.
* Create an organization like "mysite-org".
* Create a Team Token scoped to owners. This secret is the value of TF_API_TOKEN used by GitHub Actions to authenticate to Hashicorp Terraform Cloud.
* Create a variable set called "MYSITE__PRODUCTION".
* Add the following variables to the set:
* khj
* Create a project like "mysite-site".
* Create a workspace like "production".
* In the workspace, create a workspace variable called "token" with the value of the Linode Personal Access Token.
* Go back to the organization-level variable set you created previously and apply to the workspace specifically.


* Clone this repository. Name it like "mysite-site-terraform".
* Create a TF_API_TOKEN repository secret by going to Settings > Secrets and variables > Actions. This secret is used by GitHub Actions to authenticate to Hashicorp Terraform Cloud during runs.
* Change the values of TF_CLOUD_ORGANIZATION and TF_WORKSPACE in .github/workflows/terraform-apply.yml and .github/workflows/terraform-plan.yml.


You should now be able to run the terraform-apply and terraform-plan workflows via CICD. terraform-plan runs on pull request events, and terraform-apply runs on push events to the main branch.

## Making changes to your infrastructure
1. To make changes to the Linode instance, check out a feature branch based on main like "feature/my-changes", make the changes and push them to the feature branch, then create a pull request.
Terraform Cloud will run terraform-plan on the pull request.
2. Once you are satisfied with the terraform plan to make changes to the Linode instance, merge the pull request, and Terraform Cloud will run terraform-apply.
5 changes: 3 additions & 2 deletions providers.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
terraform {
required_version = ">= 1.3.0"
required_providers {
linode = {
source = "linode/linode"
# version = "..."
source = "linode/linode"
version = "2.34.1"
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
variable "token" {
sensitive = true
type = string
sensitive = true
type = string
description = "Linode API Token"
}