-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Manage Gandi DNS with Terraform - sandbox only
Signed-off-by: Benoit Donneaux <[email protected]>
- Loading branch information
Showing
12 changed files
with
507 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
# Re-usable workflow to continuously integrate and deploy Terraform plan | ||
|
||
on: | ||
workflow_call: | ||
inputs: | ||
tf_version: | ||
description: 'Version of Terraform runtime to use' | ||
required: false | ||
type: string | ||
default: '1.7.4' | ||
tf_dir: | ||
description: 'Version of Terraform runtime to use' | ||
required: false | ||
type: string | ||
default: './' | ||
gh_runner_version: | ||
description: 'Version of the GitHub runner to use' | ||
required: false | ||
type: string | ||
default: 'ubuntu-24.04' | ||
auto_comment: | ||
description: 'Enable automatic comment on GitHub pull request' | ||
required: false | ||
type: boolean | ||
default: true | ||
apply_on_branch: | ||
description: 'Automaticaly apply plan when on a specific branch' | ||
required: false | ||
type: string | ||
default: '' | ||
gandi_url: | ||
description: 'Gandi API URL' | ||
required: false | ||
type: string | ||
default: 'https://api.gandi.net' | ||
secrets: | ||
gandi_token: | ||
description: 'API token for Gandi' | ||
required: false | ||
hcloud_token: | ||
description: 'API token for Hetzner Cloud' | ||
required: false | ||
|
||
jobs: | ||
terraform: | ||
name: Terraform | ||
runs-on: ${{ inputs.gh_runner_version }} | ||
defaults: | ||
run: | ||
working-directory: ${{ inputs.tf_dir }} | ||
env: | ||
TF_VAR_gandi_token: ${{ secrets.gandi_token }} | ||
TF_VAR_hcloud_token: ${{ secrets.hcloud_token }} | ||
permissions: | ||
pull-requests: write | ||
contents: read | ||
|
||
steps: | ||
- name: Checkout | ||
id: checkout | ||
uses: actions/checkout@v4 | ||
|
||
- name: Setup | ||
id: setup | ||
uses: hashicorp/setup-terraform@v3 | ||
with: | ||
terraform_version: ${{ inputs.tf_version }} | ||
|
||
- name: Format | ||
id: fmt | ||
run: terraform fmt -no-color -check -diff | ||
|
||
- name: Init | ||
id: init | ||
run: terraform init -no-color -input=false | ||
|
||
- name: Validate | ||
id: validate | ||
run: terraform validate -no-color | ||
|
||
- name: Plan | ||
id: plan | ||
run: terraform plan -no-color -input=false -compact-warnings -out terraform_plan.out | ||
|
||
- name: Post Setup | ||
id: post_setup | ||
# Only to avoid wrapper to mess up outputs in later steps | ||
uses: hashicorp/setup-terraform@v3 | ||
with: | ||
terraform_version: ${{ inputs.tf_version }} | ||
terraform_wrapper: false | ||
|
||
- name: Verify | ||
id: verify | ||
run: | | ||
# Process the plan to verify the presence of some data | ||
# which can be used later to make additional checks | ||
terraform show -no-color terraform_plan.out > terraform_plan.log 2> >(tee terraform_plan.err >&2) && ret=0 || ret=$? | ||
# Export the plan in json too | ||
terraform show -json terraform_plan.out > terraform_plan.json | ||
# Extract current state from the plan for later comparison | ||
unzip terraform_plan.out tfstate | ||
# Extract data from temp files and export them as outputs for next steps | ||
# - changes made, if any | ||
echo "changes<<terraform_verify_changes" >> $GITHUB_OUTPUT | ||
awk '/the following actions/,0' terraform_plan.log >> $GITHUB_OUTPUT | ||
echo "terraform_verify_changes" >> $GITHUB_OUTPUT | ||
# - summary of the change, if any | ||
echo "summary<<terraform_verify_summary" >> $GITHUB_OUTPUT | ||
awk '/(Plan: |No changes. )/,1' terraform_plan.log | sed -e 's/Plan: /change(s): /' >> $GITHUB_OUTPUT | ||
echo "terraform_verify_summary" >> $GITHUB_OUTPUT | ||
# - stderr describing errors, if any | ||
echo "stderr<<terraform_verify_stderr" >> $GITHUB_OUTPUT | ||
cat terraform_plan.err >> $GITHUB_OUTPUT | ||
echo "terraform_verify_stderr" >> $GITHUB_OUTPUT | ||
# Exit with failure if any | ||
exit $ret | ||
- name: Comment | ||
id: update | ||
if: ${{ always() && github.event_name == 'pull_request' && inputs.auto_comment }} | ||
uses: actions/github-script@v7 | ||
with: | ||
github-token: ${{ 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('pr-auto-comment-${{ inputs.tf_dir }}') | ||
}) | ||
// 2. Prepare format of the comment, using toJSON to escape any special char | ||
const changes = [ | ||
${{ toJSON(steps.verify.outputs.changes) }}, | ||
] | ||
const errors = [ | ||
${{ toJSON(steps.fmt.outputs.stdout) }}, | ||
${{ toJSON(steps.init.outputs.stderr) }}, | ||
${{ toJSON(steps.validate.outputs.stderr) }}, | ||
${{ toJSON(steps.plan.outputs.stderr) }}, | ||
${{ toJSON(steps.verify.outputs.stderr) }}, | ||
] | ||
const output = ` | ||
<!-- pr-auto-comment-${{ inputs.tf_dir }} --> | ||
### ${{ github.workflow }} | ||
| Step | Outcome | | ||
| ---- | ------- | | ||
| :pencil2: **Format** | \`${{ steps.fmt.outcome }}\` | | ||
| :wrench: **Init** ️| \`${{ steps.init.outcome }}\` | | ||
| :mag: **Validate** | \`${{ steps.validate.outcome }}\` | | ||
| :page_facing_up: **Plan** | \`${{ steps.plan.outcome }}\` | | ||
| :passport_control: **Verify** | \`${{ steps.verify.outcome }}\` | | ||
| :point_right: **Result** | ${{ ( steps.plan.outcome == 'success' && steps.verify.outcome == 'success' && steps.verify.outputs.summary ) || 'with error(s) - see below' }} | | ||
<details><summary>show change(s)</summary> | ||
\`\`\` | ||
${ changes.filter(function(entry) { return /\S/.test(entry); }).join('\n') } | ||
\`\`\` | ||
</details> | ||
<details><summary>show error(s)</summary> | ||
\`\`\` | ||
${ errors.filter(function(entry) { return /\S/.test(entry); }).join('\n') } | ||
\`\`\` | ||
</details> | ||
*Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`* | ||
*Workflow: \`${{ github.workflow_ref }}\`*`; | ||
// 3. If we have a comment, update it, otherwise create a new one | ||
const comment_data = { | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
body: output | ||
} | ||
if (botComment) { | ||
comment_data.comment_id = botComment.id | ||
github.rest.issues.updateComment(comment_data) | ||
} else { | ||
comment_data.issue_number = context.issue.number | ||
github.rest.issues.createComment(comment_data) | ||
} | ||
- name: Apply | ||
id: apply | ||
if: ${{ inputs.apply_on_branch != '' && github.ref == format('refs/heads/{0}', inputs.apply_on_branch) }} | ||
run: terraform apply -no-color -input=false -auto-approve terraform_plan.out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Workflow to continuously integrate Terraform plan for Tahoe-LAFS | ||
# The deployment is not covered (yet), as it will require to auto commit | ||
# both the `terraform.state` and `.terraform/terraform.state` files when | ||
# apply_on_branch is enabled. | ||
|
||
name: Terraform Core | ||
concurrency: terraform_core_state | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
paths: | ||
- '.github/workflows/_terraform.yml' | ||
- '.github/workflows/terraform_core.yml' | ||
- 'terraform/core/**' | ||
pull_request: | ||
paths: | ||
- '.github/workflows/_terraform.yml' | ||
- '.github/workflows/terraform_core.yml' | ||
- 'terraform/core/**' | ||
workflow_dispatch: | ||
|
||
jobs: | ||
call-workflow-passing-data: | ||
# Call the re-usable Terraform workflow | ||
uses: ./.github/workflows/_terraform.yml | ||
with: | ||
tf_dir: terraform/core | ||
gandi_url: 'https://api.sandbox.gandi.net' | ||
secrets: | ||
gandi_token: ${{ secrets.GANDI_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
############################## | ||
# General level requirements # | ||
############################## | ||
|
||
# Pull base image from official repo | ||
FROM hashicorp/terraform:1.7.5@sha256:386b7bff108f9fd3b79a2e0110190c162b5e4aebf26afe3eef028fd89532c17e | ||
|
||
################################## | ||
# Application level requirements # | ||
################################## | ||
|
||
########################### | ||
# User level requirements # | ||
########################### | ||
|
||
# Parameters for default user:group | ||
ARG uid=1000 | ||
ARG user=appuser | ||
ARG gid=1000 | ||
ARG group=appgroup | ||
|
||
# Add user and group for build and runtime | ||
RUN id "${user}" > /dev/null 2>&1 || \ | ||
{ addgroup -g "${gid}" "${group}" && adduser -D -h "/home/${user}" -s /bin/bash -G "${group}" -u "${uid}" "${user}"; } | ||
|
||
# Switch to user | ||
USER ${user} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*/.terraform/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
terraform.tfstate.* | ||
!.terraform/terraform.tfstate |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"version": 3, | ||
"serial": 1, | ||
"lineage": "c2d32f6d-460b-75d4-0354-c71f999902f7", | ||
"backend": { | ||
"type": "local", | ||
"config": { | ||
"path": "./terraform.tfstate", | ||
"workspace_dir": null | ||
}, | ||
"hash": 3396623677 | ||
}, | ||
"modules": [ | ||
{ | ||
"path": [ | ||
"root" | ||
], | ||
"outputs": {}, | ||
"resources": {}, | ||
"depends_on": [] | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
resource "gandi_domain" "tl-org" { | ||
name = "tahoe-lafs.org" | ||
owner { | ||
city = "Gotham" | ||
country = "US" | ||
data_obfuscated = true | ||
email = "[email protected]" | ||
extra_parameters = { | ||
birth_city = "" | ||
birth_country = "" | ||
birth_date = "" | ||
birth_department = "" | ||
} | ||
organisation = "Tahoe-LAFS" | ||
family_name = "LAFS" | ||
given_name = "Terlog" | ||
mail_obfuscated = true | ||
phone = "+31.234567890" | ||
street_addr = "The place to be, 1" | ||
type = "association" | ||
zip = "12345" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# There is no state backend for the resources defined in this project | ||
# It is only used to define the basic requirements used by the other | ||
# ones in the parent folder. | ||
|
||
# TODO: Assess if we could/should use Terraform Cloud only for this project, | ||
# instead of committing the tfstate file. | ||
|
||
# Lets make the local state explicit | ||
terraform { | ||
backend "local" { | ||
path = "./terraform.tfstate" | ||
} | ||
} |
Oops, something went wrong.