Skip to content

Latest commit

 

History

History
304 lines (231 loc) · 10.3 KB

CONTRIBUTING.md

File metadata and controls

304 lines (231 loc) · 10.3 KB

Contributing

This document provides guidelines for contributing to samples.

Before you begin

Sign our Contributor License Agreement

Contributions to this project must be accompanied by a Contributor License Agreement (CLA). You (or your employer) retain the copyright to your contribution; this simply gives us permission to use and redistribute your contributions as part of the project.

If you or your current employer have already signed the Google CLA (even if it was for a different project), you probably don't need to do it again.

Visit https://cla.developers.google.com/ to see your current agreements or to sign a new one.

Review our Community Guidelines

This project follows Google's Open Source Community Guidelines.

Review Terraform sample requirements, best practices, and code style

If you are submitting or reviewing a pull request, make sure that the sample follows the rules for quality and consistency.

Code style

For samples that you add to the terraform-docs-samples GitHub repository, make sure that they follow the style guidelines for Terraform described in the Effective samples style guide.

Other requirements and best practices

  • (Required) Samples maintained in terraform-docs-samples must include only resource and data blocks. Don't include module blocks in your samples.

    Note: If you want to use a sample that contains module blocks, you can use the Cloud Foundation Toolkit modules.

  • (Required) Don't create a README file for your sample.

  • (Recommended) If a sample needs an API enabled, add the service to the Test setup file.

  • (Recommened) If a sample adds a new directory, add code owners to the CODEOWNERS file.

  • (Recommended) In each resource that has a name argument, include the name argument first in the resource block.

  • (Recommended) For maintainability, don't include other-vendor resources. Multi-cloud isn't recommended in terraform-docs-samples. Only Google provider resources are recommended. For example, terraform-docs-samples samples shouldn't have Azure or AWS resources. For multi-cloud samples, create a blueprint instead.

  • (Recommended) For simplicity and consistency, use default as the Terraform resource name when possible. The only time it isn't possible is if a single sample has multiple resources of the same type. They can't all have the same resource name. In this case, use what makes sense for your sample.

  • (Recommended) If your sample enables an API, add disable_on_destroy = false to prevent the API from being disabled when deleting the resources.

Dependencies for testing

The following dependencies must be installed on the development system:

Cloud Shell is recommended for development because these tools are pre-installed.

Linting and Formatting

Files in the repository are linted or formatted to maintain a standard of quality and statically validated. You can run this check locally:

cd terraform-docs-samples
make docker_test_lint

Integration Testing

Integration tests are used to verify that the samples are actuatable by Terraform. Tests are dynamically discovered based on directories in repo root and executed using the blueprint-test framework.

Set up the Test Environment

The easiest way to test the samples are in isolated test projects. The setup for projects are defined in test/setup directory.

To use this setup, you need to authenticate gcloud with an identity that has Project Creator access on a folder and the Billing Account User role on a billing account.

  1. Get you project's organization ID and folder ID:

    gcloud projects get-ancestors <YOUR_PROJECT_ID>
    
  2. Get your project's billing ID by opening https://console.cloud.google.com/billing.

  3. Set the following environment variables.

    export TF_VAR_org_id="your_org_id"
    
    export TF_VAR_folder_id="your_folder_id"
    
    export TF_VAR_billing_account="your_billing_account_id"
    
  4. Ensure that you are locally authenticated using gcloud:

    gcloud auth application-default login
    
  5. With these settings in place, you can prepare a test project using Docker:

    cd terraform-docs-samples
    
    make docker_test_prepare
    

Sample Output:

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

project_ids = [
  "ci-tf-samples-0-c5ab",
  "ci-tf-samples-1-f344",
  "ci-tf-samples-2-b5a7",
  "ci-tf-samples-3-6eda",
]
...

Noninteractive Execution

Run make -s docker_test_sample SAMPLE=${SAMPLE_NAME} to test a sample noninteractively. This will initialize, apply, verify and destroy the specified sample.

SAMPLE_NAME is the name of the lowest most containing folder. For example, to test the sample in /storage/new_bucket/main.tf, use SAMPLE=new_bucket. (See TestSample for implementation, logic discussion).

Example:

make -s docker_test_sample SAMPLE=new_bucket

Sample output:

 make -s docker_test_sample SAMPLE=new_bucket
go: downloading github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test v0.3.0
...
=== RUN   TestSamples
TestSamples terraform.go:216: Loading env vars from setup ../setup
...
2022/10/28 02:30:16 Running stage init
TestSamples/1/new_bucket retry.go:91: terraform [init -upgrade=false]
...
2022/10/28 02:30:17 Running stage apply
TestSamples/1/new_bucket retry.go:91: terraform [apply -input=false -auto-approve -lock=false]
...
2022/10/28 02:30:21 Running stage verify
TestSamples/1/new_bucket cmd.go:103: Running terraform with args [plan -input=false -detailed-exitcode -lock=false]
...
2022/10/28 02:30:23 Running stage teardown
TestSamples/1/new_bucket retry.go:91: terraform [destroy -auto-approve -input=false -lock=false]
...
TestSamples/1/new_bucket command.go:185: Destroy complete! Resources: 3 destroyed.
TestSamples/1/new_bucket command.go:185:
--- PASS: TestSamples (17.12s)
    --- PASS: TestSamples/1/new_bucket (13.95s)
PASS
ok      github.com/terraform-google-modules/terraform-docs-samples/test/integration     17.203s

Interactive Execution

Interactive execution is useful if you want to iteratively test a sample without destroying resources automatically.

  1. Run make docker_run to start the testing Docker container in interactive mode and you should see the following prompt.

    Sample output:

    [root@... workspace]#
    
  2. Navigate to the test directory cd test/integration.

  3. Run RUN_STAGE=init go test -v -timeout 0 -run //${SAMPLE_NAME} to initialize the sample to be tested. (Note: To reduce log verbosity, you can skip the -v option)

    Sample output:

    RUN_STAGE=init go test -v -timeout 0 -run //new_bucket
    ...
    === RUN   TestSamples
    TestSamples 2022-10-28T02:24:48Z terraform.go:216: Loading env vars from setup ../setup
    ...
    TestSamples/1/new_bucket 2022-10-28T02:24:59Z command.go:185: Success! The configuration is valid.
    TestSamples/1/new_bucket 2022-10-28T02:24:59Z command.go:185:
    RUN_STAGE env var set to init
    Skipping stage apply
    RUN_STAGE env var set to init
    Skipping stage verify
    RUN_STAGE env var set to init
    Skipping stage teardown
    --- PASS: TestSamples (11.27s)
        --- PASS: TestSamples/1/new_bucket (3.80s)
    
  4. Run RUN_STAGE=apply go test -v -timeout 0 -run //${SAMPLE_NAME} to apply the sample to be tested.

    Sample output:

    RUN_STAGE=apply go test -v -timeout 0 -run //new_bucket
    === RUN   TestSamples
    ...
    TestSamples/1/new_bucket command.go:185: Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
    ...
    RUN_STAGE env var set to apply
    Skipping stage verify
    RUN_STAGE env var set to apply
    Skipping stage teardown
    --- PASS: TestSamples (8.70s)
        --- PASS: TestSamples/1/new_bucket (5.83s)
    PASS
    ok      github.com/terraform-google-modules/terraform-docs-samples/test/integration     8.784s
    
  5. Run RUN_STAGE=verify go test -v -timeout 0 -run //${SAMPLE_NAME} to verify the sample has been applied.

    Sample output:

    RUN_STAGE=verify go test -v -timeout 0 -run //new_bucket
    === RUN   TestSamples
    ...
    TestSamples/1/new_bucket  command.go:185: No changes. Your infrastructure matches the configuration.
    TestSamples/1/new_bucket  command.go:185:
    TestSamples/1/new_bucket  command.go:185: Terraform has compared your real infrastructure against your configuration
    TestSamples/1/new_bucket  command.go:185: and found no differences, so no changes are needed.
    2022/10/28 02:27:47 RUN_STAGE env var set to verify
    2022/10/28 02:27:47 Skipping stage teardown
    --- PASS: TestSamples (6.79s)
        --- PASS: TestSamples/1/new_bucket (3.93s)
    PASS
    ok      github.com/terraform-google-modules/terraform-docs-samples/test/integration     6.864s
    
  6. Run RUN_STAGE=teardown go test -v -timeout 0 -run //${SAMPLE_NAME} to destroy resources created by the sample.

    Sample output:

    RUN_STAGE=teardown go test -v -timeout 0 -run //new_bucket
    === RUN   TestSamples
    ...
    TestSamples/1/new_bucket command.go:185:
    TestSamples/1/new_bucket command.go:185: Destroy complete! Resources: 3 destroyed.
    TestSamples/1/new_bucket command.go:185:
    --- PASS: TestSamples (8.49s)
        --- PASS: TestSamples/1/new_bucket (5.65s)
    PASS
    ok      github.com/terraform-google-modules/terraform-docs-samples/test/integration     8.563s