Skip to content

Commit e2ff068

Browse files
authored
Convert to TF 0.12. Add Tests. Add Codefresh test pipeline. Pin providers (#26)
* Convert to TF 0.12. Add Tests. Add Codefresh test pipeline * Update README * Update README * Pin providers
1 parent 6e679bd commit e2ff068

22 files changed

+646
-176
lines changed

.travis.yml

Lines changed: 0 additions & 16 deletions
This file was deleted.

README.md

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
[![Cloud Posse][logo]](https://cpco.io/homepage)
55

6-
# terraform-aws-tfstate-backend [![Build Status](https://travis-ci.org/cloudposse/terraform-aws-tfstate-backend.svg?branch=master)](https://travis-ci.org/cloudposse/terraform-aws-tfstate-backend) [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-aws-tfstate-backend.svg)](https://github.com/cloudposse/terraform-aws-tfstate-backend/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com)
6+
# terraform-aws-tfstate-backend [![Codefresh Build Status](https://g.codefresh.io/api/badges/pipeline/cloudposse/terraform-modules%2Fterraform-aws-tfstate-backend?type=cf-1)](https://g.codefresh.io/public/accounts/cloudposse/pipelines/5d0d3d11c841e6807afe8d2a) [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-aws-tfstate-backend.svg)](https://github.com/cloudposse/terraform-aws-tfstate-backend/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com)
77

88

99
Terraform module to provision an S3 bucket to store `terraform.tfstate` file and a DynamoDB table to lock the state file
@@ -57,20 +57,21 @@ We literally have [*hundreds of terraform modules*][terraform_modules] that are
5757

5858
## Usage
5959

60+
61+
**IMPORTANT:** The `master` branch is used in `source` just as an example. In your code, do not pin to `master` because there may be breaking changes between releases.
62+
Instead pin to the release tag (e.g. `?ref=tags/x.y.z`) of one of our [latest releases](https://github.com/cloudposse/terraform-aws-tfstate-backend/releases).
63+
64+
6065
1. Define the module in your `.tf` file using local state:
6166
```hcl
62-
terraform {
63-
required_version = ">= 0.11.3"
64-
}
65-
66-
module "terraform_state_backend" {
67-
source = "git::https://github.com/cloudposse/terraform-aws-tfstate-backend.git?ref=master"
68-
namespace = "cp"
69-
stage = "prod"
70-
name = "terraform"
71-
attributes = ["state"]
72-
region = "us-east-1"
73-
}
67+
module "terraform_state_backend" {
68+
source = "git::https://github.com/cloudposse/terraform-aws-tfstate-backend.git?ref=master"
69+
namespace = "eg"
70+
stage = "test"
71+
name = "terraform"
72+
attributes = ["state"]
73+
region = "us-east-1"
74+
}
7475
```
7576

7677
1. `terraform init`
@@ -79,9 +80,6 @@ We literally have [*hundreds of terraform modules*][terraform_modules] that are
7980

8081
1. Then add a `backend` that uses the new bucket and table:
8182
```hcl
82-
terraform {
83-
required_version = ">= 0.11.3"
84-
8583
backend "s3" {
8684
region = "us-east-1"
8785
bucket = "< the name of the S3 bucket >"
@@ -122,33 +120,33 @@ Available targets:
122120
| Name | Description | Type | Default | Required |
123121
|------|-------------|:----:|:-----:|:-----:|
124122
| acl | The canned ACL to apply to the S3 bucket | string | `private` | no |
125-
| additional_tag_map | Additional tags for appending to each tag map | map | `<map>` | no |
126-
| attributes | Additional attributes (e.g. `state`) | list | `<list>` | no |
127-
| block_public_acls | Whether Amazon S3 should block public ACLs for this bucket. | string | `false` | no |
128-
| block_public_policy | Whether Amazon S3 should block public bucket policies for this bucket. | string | `false` | no |
129-
| context | Default context to use for passing state between label invocations | map | `<map>` | no |
123+
| additional_tag_map | Additional tags for appending to each tag map | map(string) | `<map>` | no |
124+
| attributes | Additional attributes (e.g. `state`) | list(string) | `<list>` | no |
125+
| block_public_acls | Whether Amazon S3 should block public ACLs for this bucket | bool | `true` | no |
126+
| block_public_policy | Whether Amazon S3 should block public bucket policies for this bucket | string | `true` | no |
127+
| context | Default context to use for passing state between label invocations | object | `<map>` | no |
130128
| delimiter | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes` | string | `-` | no |
131-
| enable_server_side_encryption | Enable DynamoDB server-side encryption | string | `true` | no |
129+
| enable_server_side_encryption | Enable DynamoDB server-side encryption | bool | `true` | no |
132130
| environment | Environment, e.g. 'prod', 'staging', 'dev', 'pre-prod', 'UAT' | string | `` | no |
133-
| force_destroy | A boolean that indicates the S3 bucket can be destroyed even if it contains objects. These objects are not recoverable | string | `false` | no |
134-
| ignore_public_acls | Whether Amazon S3 should ignore public ACLs for this bucket. | string | `false` | no |
135-
| label_order | The naming order of the id output and Name tag | list | `<list>` | no |
136-
| mfa_delete | A boolean that indicates that versions of S3 objects can only be deleted with MFA. ( Terraform cannot apply changes of this value; https://github.com/terraform-providers/terraform-provider-aws/issues/629 ) | string | `false` | no |
131+
| force_destroy | A boolean that indicates the S3 bucket can be destroyed even if it contains objects. These objects are not recoverable | bool | `false` | no |
132+
| ignore_public_acls | Whether Amazon S3 should ignore public ACLs for this bucket | bool | `true` | no |
133+
| label_order | The naming order of the id output and Name tag | list(string) | `<list>` | no |
134+
| mfa_delete | A boolean that indicates that versions of S3 objects can only be deleted with MFA. ( Terraform cannot apply changes of this value; https://github.com/terraform-providers/terraform-provider-aws/issues/629 ) | bool | `false` | no |
137135
| name | Solution name, e.g. 'app' or 'jenkins' | string | `terraform` | no |
138136
| namespace | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | string | `` | no |
139-
| prevent_unencrypted_uploads | Prevent uploads of unencrypted objects to S3 | string | `true` | no |
137+
| prevent_unencrypted_uploads | Prevent uploads of unencrypted objects to S3 | bool | `true` | no |
140138
| profile | AWS profile name as set in the shared credentials file | string | `` | no |
141139
| read_capacity | DynamoDB read capacity units | string | `5` | no |
142140
| regex_replace_chars | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`. By default only hyphens, letters and digits are allowed, all other chars are removed | string | `/[^a-zA-Z0-9-]/` | no |
143141
| region | AWS Region the S3 bucket should reside in | string | - | yes |
144-
| restrict_public_buckets | Whether Amazon S3 should restrict public bucket policies for this bucket. | string | `false` | no |
142+
| restrict_public_buckets | Whether Amazon S3 should restrict public bucket policies for this bucket | bool | `true` | no |
145143
| role_arn | The role to be assumed | string | `` | no |
146144
| stage | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | string | `` | no |
147-
| tags | Additional tags (e.g. `map('BusinessUnit','XYZ')` | map | `<map>` | no |
145+
| tags | Additional tags (e.g. `map('BusinessUnit','XYZ')` | map(string) | `<map>` | no |
148146
| terraform_backend_config_file_name | Name of terraform backend config file | string | `terraform.tf` | no |
149147
| terraform_backend_config_file_path | The path to terrafrom project directory | string | `` | no |
150148
| terraform_state_file | The path to the state file inside the bucket | string | `terraform.tfstate` | no |
151-
| terraform_version | The minimum required terraform version | string | `0.11.3` | no |
149+
| terraform_version | The minimum required terraform version | string | `0.12.2` | no |
152150
| write_capacity | DynamoDB write capacity units | string | `5` | no |
153151

154152
## Outputs

README.yaml

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ license: "APACHE2"
1616
# Canonical GitHub repo
1717
github_repo: cloudposse/terraform-aws-tfstate-backend
1818

19+
1920
# Badges to display
2021
badges:
21-
- name: "Build Status"
22-
image: "https://travis-ci.org/cloudposse/terraform-aws-tfstate-backend.svg?branch=master"
23-
url: "https://travis-ci.org/cloudposse/terraform-aws-tfstate-backend"
22+
- name: "Codefresh Build Status"
23+
image: "https://g.codefresh.io/api/badges/pipeline/cloudposse/terraform-modules%2Fterraform-aws-tfstate-backend?type=cf-1"
24+
url: "https://g.codefresh.io/public/accounts/cloudposse/pipelines/5d0d3d11c841e6807afe8d2a"
2425
- name: "Latest Release"
2526
image: "https://img.shields.io/github/release/cloudposse/terraform-aws-tfstate-backend.svg"
2627
url: "https://github.com/cloudposse/terraform-aws-tfstate-backend/releases/latest"
@@ -59,18 +60,14 @@ description: |-
5960
usage: |-
6061
1. Define the module in your `.tf` file using local state:
6162
```hcl
62-
terraform {
63-
required_version = ">= 0.11.3"
64-
}
65-
66-
module "terraform_state_backend" {
67-
source = "git::https://github.com/cloudposse/terraform-aws-tfstate-backend.git?ref=master"
68-
namespace = "cp"
69-
stage = "prod"
70-
name = "terraform"
71-
attributes = ["state"]
72-
region = "us-east-1"
73-
}
63+
module "terraform_state_backend" {
64+
source = "git::https://github.com/cloudposse/terraform-aws-tfstate-backend.git?ref=master"
65+
namespace = "eg"
66+
stage = "test"
67+
name = "terraform"
68+
attributes = ["state"]
69+
region = "us-east-1"
70+
}
7471
```
7572
7673
1. `terraform init`
@@ -79,9 +76,6 @@ usage: |-
7976
8077
1. Then add a `backend` that uses the new bucket and table:
8178
```hcl
82-
terraform {
83-
required_version = ">= 0.11.3"
84-
8579
backend "s3" {
8680
region = "us-east-1"
8781
bucket = "< the name of the S3 bucket >"

codefresh/test.yml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
version: '1.0'
2+
3+
stages:
4+
- Prepare
5+
- Test
6+
7+
steps:
8+
wait:
9+
title: Wait
10+
stage: Prepare
11+
image: codefresh/cli:latest
12+
commands:
13+
- codefresh get builds --pipeline=${{CF_REPO_NAME}} --status running --limit 1000 -o json | jq --arg id ${{CF_BUILD_ID}} -ser 'flatten|.[-1].id==$id'
14+
retry:
15+
maxAttempts: 10
16+
delay: 20
17+
exponentialFactor: 1.1
18+
19+
main_clone:
20+
title: "Clone repository"
21+
type: git-clone
22+
stage: Prepare
23+
description: "Initialize"
24+
repo: ${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}
25+
git: CF-default
26+
revision: ${{CF_REVISION}}
27+
28+
clean_init:
29+
title: Prepare build-harness and test-harness
30+
image: ${{TEST_IMAGE}}
31+
stage: Prepare
32+
commands:
33+
- cf_export PATH="/usr/local/terraform/0.12/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
34+
- make init
35+
- git -C build-harness checkout master
36+
- make -C test/ clean init TEST_HARNESS_BRANCH=master
37+
- make -C test/src clean init
38+
- find . -type d -name '.terraform' | xargs rm -rf
39+
- find . -type f -name 'terraform.tfstate*' -exec rm -f {} \;
40+
41+
test:
42+
type: "parallel"
43+
title: "Run tests"
44+
description: "Run all tests in parallel"
45+
stage: Test
46+
steps:
47+
test_readme_lint:
48+
title: "Test README.md updated"
49+
stage: "Test"
50+
image: ${{TEST_IMAGE}}
51+
description: Test "readme/lint"
52+
commands:
53+
- make readme/lint
54+
55+
test_module:
56+
title: Test module with bats
57+
image: ${{TEST_IMAGE}}
58+
stage: Test
59+
commands:
60+
- make -C test/ module
61+
62+
test_examples_complete:
63+
title: Test "examples/complete" with bats
64+
image: ${{TEST_IMAGE}}
65+
stage: Test
66+
commands:
67+
- make -C test/ examples/complete
68+
69+
test_examples_complete_terratest:
70+
title: Test "examples/complete" with terratest
71+
image: ${{TEST_IMAGE}}
72+
stage: Test
73+
commands:
74+
- make -C test/src

docs/terraform.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,33 @@
33
| Name | Description | Type | Default | Required |
44
|------|-------------|:----:|:-----:|:-----:|
55
| acl | The canned ACL to apply to the S3 bucket | string | `private` | no |
6-
| additional_tag_map | Additional tags for appending to each tag map | map | `<map>` | no |
7-
| attributes | Additional attributes (e.g. `state`) | list | `<list>` | no |
8-
| block_public_acls | Whether Amazon S3 should block public ACLs for this bucket. | string | `false` | no |
9-
| block_public_policy | Whether Amazon S3 should block public bucket policies for this bucket. | string | `false` | no |
10-
| context | Default context to use for passing state between label invocations | map | `<map>` | no |
6+
| additional_tag_map | Additional tags for appending to each tag map | map(string) | `<map>` | no |
7+
| attributes | Additional attributes (e.g. `state`) | list(string) | `<list>` | no |
8+
| block_public_acls | Whether Amazon S3 should block public ACLs for this bucket | bool | `true` | no |
9+
| block_public_policy | Whether Amazon S3 should block public bucket policies for this bucket | string | `true` | no |
10+
| context | Default context to use for passing state between label invocations | object | `<map>` | no |
1111
| delimiter | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes` | string | `-` | no |
12-
| enable_server_side_encryption | Enable DynamoDB server-side encryption | string | `true` | no |
12+
| enable_server_side_encryption | Enable DynamoDB server-side encryption | bool | `true` | no |
1313
| environment | Environment, e.g. 'prod', 'staging', 'dev', 'pre-prod', 'UAT' | string | `` | no |
14-
| force_destroy | A boolean that indicates the S3 bucket can be destroyed even if it contains objects. These objects are not recoverable | string | `false` | no |
15-
| ignore_public_acls | Whether Amazon S3 should ignore public ACLs for this bucket. | string | `false` | no |
16-
| label_order | The naming order of the id output and Name tag | list | `<list>` | no |
17-
| mfa_delete | A boolean that indicates that versions of S3 objects can only be deleted with MFA. ( Terraform cannot apply changes of this value; https://github.com/terraform-providers/terraform-provider-aws/issues/629 ) | string | `false` | no |
14+
| force_destroy | A boolean that indicates the S3 bucket can be destroyed even if it contains objects. These objects are not recoverable | bool | `false` | no |
15+
| ignore_public_acls | Whether Amazon S3 should ignore public ACLs for this bucket | bool | `true` | no |
16+
| label_order | The naming order of the id output and Name tag | list(string) | `<list>` | no |
17+
| mfa_delete | A boolean that indicates that versions of S3 objects can only be deleted with MFA. ( Terraform cannot apply changes of this value; https://github.com/terraform-providers/terraform-provider-aws/issues/629 ) | bool | `false` | no |
1818
| name | Solution name, e.g. 'app' or 'jenkins' | string | `terraform` | no |
1919
| namespace | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | string | `` | no |
20-
| prevent_unencrypted_uploads | Prevent uploads of unencrypted objects to S3 | string | `true` | no |
20+
| prevent_unencrypted_uploads | Prevent uploads of unencrypted objects to S3 | bool | `true` | no |
2121
| profile | AWS profile name as set in the shared credentials file | string | `` | no |
2222
| read_capacity | DynamoDB read capacity units | string | `5` | no |
2323
| regex_replace_chars | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`. By default only hyphens, letters and digits are allowed, all other chars are removed | string | `/[^a-zA-Z0-9-]/` | no |
2424
| region | AWS Region the S3 bucket should reside in | string | - | yes |
25-
| restrict_public_buckets | Whether Amazon S3 should restrict public bucket policies for this bucket. | string | `false` | no |
25+
| restrict_public_buckets | Whether Amazon S3 should restrict public bucket policies for this bucket | bool | `true` | no |
2626
| role_arn | The role to be assumed | string | `` | no |
2727
| stage | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | string | `` | no |
28-
| tags | Additional tags (e.g. `map('BusinessUnit','XYZ')` | map | `<map>` | no |
28+
| tags | Additional tags (e.g. `map('BusinessUnit','XYZ')` | map(string) | `<map>` | no |
2929
| terraform_backend_config_file_name | Name of terraform backend config file | string | `terraform.tf` | no |
3030
| terraform_backend_config_file_path | The path to terrafrom project directory | string | `` | no |
3131
| terraform_state_file | The path to the state file inside the bucket | string | `terraform.tfstate` | no |
32-
| terraform_version | The minimum required terraform version | string | `0.11.3` | no |
32+
| terraform_version | The minimum required terraform version | string | `0.12.2` | no |
3333
| write_capacity | DynamoDB write capacity units | string | `5` | no |
3434

3535
## Outputs
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
region = "us-west-1"
2+
3+
namespace = "eg"
4+
5+
stage = "test"
6+
7+
name = "terraform"

examples/complete/main.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module "tfstate_backend" {
2+
source = "../../"
3+
4+
providers = {
5+
aws = "aws"
6+
null = "null"
7+
local = "local"
8+
template = "template"
9+
}
10+
11+
region = var.region
12+
namespace = var.namespace
13+
stage = var.stage
14+
name = var.name
15+
16+
force_destroy = true
17+
}

examples/complete/outputs.tf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
output "s3_bucket_id" {
2+
value = module.tfstate_backend.s3_bucket_id
3+
description = "S3 bucket ID"
4+
}
5+
6+
output "dynamodb_table_name" {
7+
value = module.tfstate_backend.dynamodb_table_name
8+
description = "DynamoDB table name"
9+
}
10+
11+
output "dynamodb_table_id" {
12+
value = module.tfstate_backend.dynamodb_table_id
13+
description = "DynamoDB table ID"
14+
}

examples/complete/variables.tf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
variable "region" {
2+
type = string
3+
}
4+
5+
variable "namespace" {
6+
type = string
7+
}
8+
9+
variable "name" {
10+
type = string
11+
}
12+
13+
variable "stage" {
14+
type = string
15+
}

examples/complete/versions.tf

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
terraform {
2+
required_version = "~> 0.12.0"
3+
}
4+
5+
# Pin the `aws` provider
6+
# https://www.terraform.io/docs/configuration/providers.html
7+
# Any non-beta version >= 2.0.0 and < 3.0.0, e.g. 2.X.Y
8+
provider "aws" {
9+
version = "~> 2.0"
10+
region = var.region
11+
}
12+
13+
provider "null" {
14+
version = "~> 2.0"
15+
}
16+
17+
provider "local" {
18+
version = "~> 1.2"
19+
}
20+
21+
provider "template" {
22+
version = "~> 2.0"
23+
}

0 commit comments

Comments
 (0)