Giter VIP home page Giter VIP logo

terraform-examples's Introduction

terraform-examples

A reference repository of Terraform with canonical and as-simple-as-possible demonstrations of Terraform functionality and features.

See here for a searchable front-end: https://containersolutions.github.io/terraform-examples/

Why?

At Container Solutions we find we regularly need chunks of Terraform to demonstrate something specific, such as:

  • A simple EC2 instance

  • A bespoke VPC

  • A Windows EC2 instance with an EBS volume

This might be to do a basic test of something, find an example to tinker with, or send to someone to get them going.

Usage

To help get started with these examples, there are scripts available in bin and in local folders.

Here's an example run:

$ git clone https://github.com/ContainerSolutions/terraform-examples
$ cd terraform-examples
$ cd aws/aws_vpc
$ ./run.sh
Input AWS_ACCESS_KEY_ID
KEY
Input AWS_SECRET_ACCESS_KEY
<secret>
...

If you want to skip the manual key/id inputs, then export them.

See bin/README.md for more information.

Where is...?

If you want to look for a specific example, try the index.

Sections

The code is generally divided up by provider, then resource, then whatever the example illustrates, eg local/null_resource/for_each, or aws/aws_instance/remote-exec/inline.

Other basic language features may be illustrated in their own folders, eg outputs/local_file/module.

Principles

The examples seek to be:

  • As simple as possible to illustrate the functionality

  • Self-contained (ie limited to one .tf file)

  • Clear (eg resource names are verbose and unambiguous)

Conventions

  • Naming examples:

    • simple - for minimal functionality demonstration
    • <functionality> - when demonstrating something more than minimal
    • directory structure: <provider>/<resource_type>/<example_name>
  • Where it makes sense, items that can be changed are prefaced with changeme_

  • In general, underscores are used in Terraform names over dashes

  • Naming Terraform resources, data, and variables:

    • use only lower case letters, numbers, and underscore
    • names should be unique between all examples (but across resources items only if a resource; data items only if data, etc)
    • prefixed with: changeme_<example_name>_
  • name = attribute within the resource:

    • use only lower case letters, numbers, and dash
    • same as resource name, but with: s/_/-/g
  • For help with automated testing

    • where possible, add some way to enable 'left-over' resources to be cleaned up, eg provider default_tags of cs_terraform_examples in AWS provider blocks
  • Add inline documentation for each Terraform code block

    • # Summary: – 1-line summary of what this example does
    • # Documentation: – add link to documentation before each block (terraform, provider, variable, resource, etc.)
    • # Explanation: – add only where some extra explanation is needed

Contributing

Contributions to terraform-examples project are welcome. You can find detailed information about contributing here.

GitHub Actions Workflow

On every commit/push, the following tests run on all branches:

  • A tflint on all files ending with tf

  • A terraform validate on all

  • A series of checks to test the code against standards

Using slash command /test, a maintainer can run Cloud Testing jobs. This includes:

  • All AWS provider examples are run against an AWS account

  • All GCP provider examples are run against a GCP account

  • All Linode provider examples are run against a Linode account

  • All DigitalOcean provider examples are run against a DigitalOcean account

  • All 'local' provider examples are run locally on the GitHub Actions runner

Cloud Environment tests are long and/or cost money and they won't work without the necessary auth information being set up correctly.

The auth information for the provider accounts are stored in secrets in the repository, accessible to the admin.

Slash commands can be used to approve/merge the PR, '/approve' or '/merge'.

The Flow:

  • PR is opened

  • Contributor commits/pushes on-demand and triggers the Statis Tests

  • Once ready, and maintainer runs the Full-CI, which includes Cloud Tests '/test'

  • If everything goes well, the maintainer uses the command '/approve' to mark as reviewed/approve

  • The last step, after everything is checked, '/merge' to perform the merge to the main branch

Note: All the slash commands are performed by Github Actions BOT with GITHUB_TOKEN

Forcing tests

You can force a test for a given provider (on main branch only) by adding a .forcetest file to the relevant folder.

For example, if you want to ensure that the aws tests run, then add an empty file in aws/.forcetest. On a successfully completed test run, these files are removed as part of the 'success commit' in the github action workflow.

## Maintainer Information

For information for maintainers of this repository at ContainerSolutions, see maintainers

Sources / Thanks To

Learn Terraform The Hard Way Slash Commands

Other Examples

Immutable Cluster Using Packer and Ansible on AWS

terraform-examples's People

Contributors

aymensegni avatar b4ld avatar choilmto avatar deeajayi avatar github-actions[bot] avatar ianmiell avatar ileriayo avatar knelasevero avatar melihc1 avatar mo-abdallaa avatar raha-fi avatar rodrigorras avatar sanyer avatar sebagomez avatar teszes avatar ttarczynski avatar vmhlotsh1 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

terraform-examples's Issues

DNS

This issue describes the list of sub-tasks needed to complete the DNS examples on AWS

  • Create a simple route53 zone and TXT record

For other use-cases add to this list

CI test 'ProvidersAzure' stopped working

After the recent change #56 our CI test ProvidersAzure stopped working.
See:

Results from ProvidersAzure test:

Run /home/runner/work/terraform-examples/terraform-examples/bin/run_azurerm_examples.sh
find: ‘azurerm’: No such file or directory

The problem is caused by renaming azurerm to azure without the needed changes in CI and bin/*.sh scripts:

# egrep -r azurerm bin
bin/run_azurerm_examples.sh:source bin/get_azurerm_folders.sh
bin/apply.sh:SUPPORTED_PROVIDERS="aws|azurerm|digitalocean|google|kubernetes|linode"
bin/get_azurerm_folders.sh:AZURERM_FOLDERS="$(find azurerm | grep tf$ | xargs -n1 dirname | sed 's/^.\///')"
bin/destroy.sh:SUPPORTED_PROVIDERS="aws|azurerm|digitalocean|google|kubernetes|linode"
# egrep -r azurerm .github/workflows
.github/workflows/main.yml:        run: ${{github.workspace}}/bin/run_azurerm_examples.sh

Error parsing /home/runner/.terraformrc: At 3:16: illegal char

There's an error repeated in every terraform run (init / plan / apply / validate). It doesn't break the tests but it pollutes the logs.

There are some problems with the CLI configuration:
╷
│ Error: Error parsing /home/runner/.terraformrc: At 3:16: illegal char
│
╵

As a result of the above problems, Terraform may not behave as intended.

Create template for new issues

For new issues, template should be created so that description would cover some basic questions like:
Bug or Feature Request/New Example Request
Bug: Which examples are affected?
Feature Request/New Example Request: Name of the provider and resource example is asked for

Load Balancer

This issue describes the list of sub-tasks needed to complete the load balancer examples on AWS

  • Create an application load balancer
  • Create a network load balancer

For other use-cases add to this list

Project conventions: documentation

One of our conventions is not yet documented and not enforced with bin/check* scripts.
It is:

The comments that we want to have in all examples:

  • # Summary: – 1-line summary of what this example does
  • # Documentation: – add link to documentation before each block (terraform, provider, variable, resource, etc.)
  • # Explanation: – add only where some extra explanation is needed

TODO:

  • add this convention to README
  • #183

Main broken

Tomasz Tarczynski I’ve spotted one issue after your last change with renaming variables (529f675)
The variable names are now unique. But it breaks one functionality here:
after that last commit variable project_id (for google examples) changed to changeme_<example_name>_project_id
find google -name main.tf | xargs egrep 'variable.+project_id'
google/google_compute_instance/simple/main.tf:variable "changeme_google_compute_instance_simple_project_id" {
google/google_container_cluster/separate_node_pool/main.tf:variable "changeme_google_container_cluster_separate_node_pool_project_id" {
google/google_container_cluster/simple/main.tf:variable "changeme_google_container_cluster_simple_project_id" {
google/google_container_cluster/cluster_and_deployment/main.tf:variable "changeme_google_container_cluster_cluster_and_deployment_project_id" {
google/google_container_cluster/vpc_native_cluster/main.tf:variable "changeme_google_container_cluster_vpc_native_cluster_project_id" {
google/google_compute_network/simple/main.tf:variable "changeme_google_compute_network_simple_project_id" {
google/google_compute_attached_disk/count/main.tf:variable "changeme_google_compute_attached_disk_count_project_id" {
google/google_compute_attached_disk/simple/main.tf:variable "changeme_google_compute_attached_disk_simple_project_id" {
google/google_compute_disk/simple/main.tf:variable "changeme_google_compute_disk_simple_project_id" {
google/google_storage_bucket/simple/main.tf:variable "changeme_google_storage_bucket_simple_project_id" {
but we want to set this one with an environment variable, see here: https://github.com/ContainerSolutions/terraform-examples/blob/main/bin/shared_google.sh#L15-L21
if [ -z "$TF_VAR_project_id" ]
then
echo "If you want to suppress this input, run 'export TF_VAR_project_id=<YOUR_GCP_PROJECT_ID>'"
echo "To find your current Project ID, run 'gcloud config get-value project'"
echo 'Input TF_VAR_project_id'
read -r TF_VAR_project_id
fi
So I think we cannot make the project_id variable name unique and still have this working.
Should we maybe say that this one is an exception (and add some conditional to the check_non_unique_variable.sh script?

AWS version?

'I noticed you are rocking the default_tags goodness in the aws provider; it's so great! FYI you should be using version = "~> 3.38" for aws since that is the first public version that supports the feature'

Add simple Examples for Rancher Provider

Create the basic structure for the Rancher Provider:

  • CI scripts
  • some Test environment
    • check what "sandbox" options are available for testing
  • configure credentials/secrets etc.

Add one simplest example for official Terraform Rancher Provider. Could be one of:

  • Cloud Credential
  • Cluster
  • Node Template

Remove index CI check

Remove check to improve velocity, long term replace with automatically generated stuff.

Automate Terraform-examples website updates

We have a Web GUI for terraform-examples at: https://containersolutions.github.io/terraform-examples/
This website was last updated in May, so it's far behind the main branch of the repository.

TODO

  • learn how to update it (CONTRIBUTING.md / Updating Web UI)
  • make the update using the current process
  • plan how to get fully automated updates done by the CI
  • Implement the fully automated website update process

Some hints on what's used for generating the website:

  1. https://github.com/ContainerSolutions/terraform-examples/tree/terraform-examples-UI
  2. https://github.com/ContainerSolutions/terraform-examples/blob/terraform-examples-UI/README.md
  3. https://github.com/ContainerSolutions/terraform-examples/blob/main/RELEASE.md
  4. https://github.com/ContainerSolutions/terraform-examples/blob/terraform-examples-UI/release.sh

Fix action errors with commentFeedback steps

commentFeedback was added previously but later due to errors on actions they were removed in this commit: fed5aa3

It would be nice to see them working and have feedback on full-ci action result on PR. It can be either an emoji on the slash command or a comment with result of the action.

AWS VM Instance Examples

This issue describes the list of sub-tasks needed to complete the VM Instance examples on AWS

  • Simple VM Instance
  • Simple VM Instance with ssh access (Unmanaged SSH Key)
  • Simple VM Instance with remote exec
  • Multiple VM Instances with count
  • Multiple VM Instances with for_each

For other use-cases add to this list

Add a PR template with a checklist

It should list what is required for the PR.
Something like:

General contribution criteria

Please have a look at our contribution guidelines: ...
Particularly the sections about the:

  • contribution workflow
  • Principles
  • Conventions
  • add CHANGELOG.md entry
  • ...

The following short checklist should be used to make sure your PR is of good
quality, and can be merged easily:

  • does it follow project Conventions?
  • does it follow project Principles?
  • do all the checks pass?
  • if it resolves an issue;
    is a reference (i.e. #1) to this issue included?

CI action 'RecordActionSuccess' fails on 'main' branch

See the last CI run: https://github.com/ContainerSolutions/terraform-examples/runs/3074918753?check_suite_focus=true
It's because the main branch is protected now:

To https://github.com/ContainerSolutions/terraform-examples
 ! [remote rejected] main -> main (protected branch hook declined)
error: failed to push some refs to 'https://github.com/ContainerSolutions/terraform-examples'
Error: Invalid status code: 1
    at ChildProcess.<anonymous> (/home/runner/work/_actions/stefanzweifel/git-auto-commit-action/v4/index.js:17:19)
    at ChildProcess.emit (events.js:210:5)
    at maybeClose (internal/child_process.js:1021:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5) {
  code: 1
}
Error: Invalid status code: 1
    at ChildProcess.<anonymous> (/home/runner/work/_actions/stefanzweifel/git-auto-commit-action/v4/index.js:17:19)
    at ChildProcess.emit (events.js:210:5)
    at maybeClose (internal/child_process.js:1021:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5)

Improve scripts

  • find were we have code duplication in the bash scripts and generalize where appropriate
    • generic bin/run_*.sh and bin/destroy.sh scripts – #53
    • #182
    • generic bin/get_*_examples.sh scripts
    • generic bin/shared_*_examples.sh scripts
  • use symlinks instead of 2-line scripts (if possible): destroy.sh, run.sh
  • #181

Creating multiple users in AWS IAM

'I am currently looking at creating different list of users in a locals.tf and using them in different IAM resources to reduce the toil. That would be awesome'

Cover all basic resources for GCP

  • VM instance
  • Serverless / FaaS
  • Kubernetes cluster
  • Block storage / persistent disk
  • Object storage
  • SQL database
  • NoSQL database
  • VPC / virtual network
  • Load Balancer
  • DNS:
  • IAM

Cover all basic resources for Azure

  • VM instance
  • Serverless / FaaS
  • Kubernetes cluster
  • Block storage / persistent disk
  • Object storage
  • SQL database
  • NoSQL database
  • VPC / virtual network
  • Load Balancer
  • DNS
  • IAM
  • KeyVault

Naming convention

I would like to reopen the discussion on the naming conventions that we have.

As I understand, the current convention is the following:

  • names of "resource" and "data" blocks should start with "changeme_"
  • names of string type variables (or basically all unvalidated variables) should start with "changeme_"

I think this has two issues:

  • it's quite redundant, as you know you can change all variable names and values
  • even if you don't, the inconsistency of it - since it implies you can't change validated values, like a CIDR block - is misleading

Consider the same situation, if the language in question was not Terraform, but Python:

import os

for number in range(15):
    if not os.path.isdir("changeme_test" + f"{number}"):
        os.makedirs("changeme_test" + f"{number}")
        print("created folder : ", "changeme_test" + f"{number}")
    else:
        print("changeme_test" + f"{number}", "folder already exists.")

You could say that there are a few issues with this snippet:

  • if you actually want to change the string value, you actually have to change it in 4 places individually
  • it implies you can't change the number value from 15, as it's not valued "changeme_15"

Compare this with a TF snippet from out repo:

# Documentation: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance
resource "aws_instance" "changeme_aws_resource_simple" {
  instance_type = "t2.nano"
  ami           = "ami-0ddbdea833a8d2f0d"
}

This also implies that the thing to change here is the resource name. However, the machine size and the AMI are arguably more important in this context. There is also little documentation to learn what the value of an AMI could be.

To refactor the Python example before, this would be IMO a correct approach:

import os

# Number of directories to be created
DIR_COUNT = 15

# Common directory name prefix
DIR_PREFIX = "test"

for number in range(DIR_COUNT):
    if not os.path.isdir(DIR_PREFIX + f"{number}"):
        os.makedirs(DIR_PREFIX + f"{number}")
        print("created folder : ", DIR_PREFIX + f"{number}")
    else:
        print(DIR_PREFIX + f"{number}", "folder already exists.")

As it explains every variable that can be changed, and also indicates the intention around using them. It also resolves a "magic numbers" code smell.

Conversely, the TF snippet could be changed in the following way:

# Documentation: <link explaining VM sizes>
variable "aws_instance_type" {
  description = "The chosen machine size from the available machine sizes defined by AWS"
}

# Documentation: <link explaining AMIs>
variable "amazon_machine_image_id" {
  description = "The ID of the chosen Amazon Machine Image"
}

# Documentation: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance
resource "aws_instance" "aws_instance_simple" {
  instance_type = var.aws_instance_type
  ami           = var.amazon_machine_image_id
}

This way we could extend documentation to variables as well, and also display all variables that can be changed.

Add contributor's guide

We need a guide that will help new contributors when working on their first pull request.
Such guide should:

Some information are already in README.md, but we need to make it easier for first-time contributors.

AWS Kubernetes Cluster Examples

This issue describes the list of tasks needed to complete the AWS Kubernetes cluster examples

  • Simple Spot instances and Fargate aws_eks_cluster

For other use-cases, please add to this list.

AWS Object Storage Examples

This issue describes the list of tasks needed to complete the AWS object storage examples

  • Simple aws_s3_bucket

For other use-cases, please add to this list.

Try import if run.sh doesn't work?

If run.sh doesn't work, it might be because of 'left-overs' from previous failed destroys. Maybe try import, then destroy, then run.sh again?

AWS Serverless / FaaS examples

This issue describes the list of tasks needed to complete the AWS Serverless / FaaS examples

  • Simple aws_lambda_function

For other use-cases, please add to this list.

Create integration

Create integration branch, to run final tests before going to main.

Need to add 'integration' or similar to the branches that run the cloud code tests.

release.sh in terraform-examples-UI branch

Release.sh currently has some issues:

  • When its executed, it gives a warning about usage of depth argument of find. Script output lists directories when that argument is changed to maxdepth and placed before type argument.
  • After the change mentioned above, it shows warning about different directories. According to RELEASE.md in main branch, comment for release.sh is To get advice on whether an examples folder needs to be added, and add if necessary. So we should expect it to list provider folders inside examples folder which doesn't have related md files.

This script should be fixed and its usage should be documented.

AWS IAM Examples

This issue describes the list of tasks needed to complete the AWS IAM examples

  • Simple aws_iam_user + aws_iam_access_key #121
  • Simple aws_iam_group
  • aws_iam_group_policy + aws_iam_group_policy_attachment
  • aws_iam_user + aws_iam_group + aws_iam_group_policy + aws_iam_group_policy_attachment

For other use-cases, please add to this list.

INDEX.md improvements

Right now, INDEX.md causes a lot of work as it needs to be touched by every PR that adds something, and it creates a lot of merge conflicts. It also is something between a glossary and a table of contents, not really conforming to either idea.

Goals we want to achieve:

  • have an automated solution to generate INDEX.md
  • avoid making any changes to INDEX.md when contributing new examples

In more detail:

  • It could be in a form of a script
  • That script can be automatically executed after every new commit to the main branch (GitHub Actions CI job)

AWS Block Storage / Persistent Disk Examples

This issue describes the list of tasks needed to complete the AWS Block storage / persistent disk examples

  • Simple aws_ebs_volume

For other use-cases, please add to this list.

Publishing on Terraform Registry

The Terraform Registry is basically the Docker Hub of Terraform Modules.

Publishing each example as a self-contained module would enable us to use them by just referencing them with a module block. It would also generate more exposure for the company.

What we would need to do this is basically create a repo from each example. We could do that by pushing from a GitHub action to each created repo. We could either house these under the current org, but we might consider housing them in a separate one, so that we don't pollute our namespace with lots of examples.

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.