This repository has been archived by the owner on Jun 19, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* feat: adds initial cut at cloudposse/tutorials Docker image * chore: updates gitignore to ignore terraform.lock.hcl files * chore: adds backend.tf.json to gitignore * feat: adds initial cut at code for tutorial #3 * chore: updates to rootfs/ pattern for motd file * feat: updates tutorial #3 stacks to correct catalog/ conventions * feat: updates stacks to include TODOs for names + adds bin/uniquify.sh * chore: adds vendir to tutorials image * chore: adds --name arg to `make run` * feat: updates our tfstate-backend component to latest * chore: updates tfstate-backend to be in us-east-2 * chore: applies suggestions from Erik's code review Co-authored-by: Erik Osterman (CEO @ Cloud Posse) <[email protected]> * chore: applies suggestions from Erik's code review Co-authored-by: Erik Osterman (CEO @ Cloud Posse) <[email protected]> * feat: updates to use golang-petname > random string * fix: issue with dynamo lock attributes being out of order * chore: updates tutorial #3 README to link to docs Co-authored-by: Erik Osterman (CEO @ Cloud Posse) <[email protected]>
- Loading branch information
Showing
25 changed files
with
833 additions
and
4 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
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,3 @@ | ||
# Tutorial #3: You first AWS Environment with Atmos | ||
|
||
The code in this directory is an accompaniment to the [Your first environment on AWS](https://docs.cloudposse.com/tutorials/first-aws-environment/) tutorial in our SweetOps documentation. |
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,33 @@ | ||
#!/usr/bin/env bash | ||
# | ||
# Since we're creating an S3 bucket as part of this tutorial, we need the names of those | ||
# buckets to be unique, otherwise we'll run into issues with AWS S3 API errors blocking | ||
# our terraform applies. This scripts generates random pet names to append to attributes | ||
# which ensures all bucket names in the project are unique. | ||
|
||
# Build random value | ||
# We install golang-petname as part of our tutorials toolbox. | ||
RANDOM_PET=$(golang-petname) | ||
|
||
# Updates our tfstate-backend's attributes to be unique | ||
yq eval --inplace \ | ||
".components.terraform.tfstate-backend.vars.attributes.[0] = \"$RANDOM_PET\"" \ | ||
stacks/ue2-root.yaml | ||
|
||
# Updates our static backend config with unique names | ||
yq eval --inplace \ | ||
".terraform.backend.s3.bucket = \"acme-uw2-tfstate-$RANDOM_PET\"" \ | ||
stacks/catalog/globals.yaml | ||
|
||
yq eval --inplace \ | ||
".terraform.backend.s3.dynamodb_table = \"acme-uw2-tfstate-lock-$RANDOM_PET\"" \ | ||
stacks/catalog/globals.yaml | ||
|
||
# Updates our dev + prod static-site component vars to ensure we're creating unique names | ||
yq eval --inplace \ | ||
".components.terraform.static-site.vars.attributes.[0] = \"$RANDOM_PET\"" \ | ||
stacks/uw2-dev.yaml | ||
|
||
yq eval --inplace \ | ||
".components.terraform.static-site.vars.attributes.[0] = \"$RANDOM_PET\"" \ | ||
stacks/uw2-prod.yaml |
202 changes: 202 additions & 0 deletions
202
03-first-aws-environment/components/terraform/static-site/context.tf
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,202 @@ | ||
# | ||
# ONLY EDIT THIS FILE IN github.com/cloudposse/terraform-null-label | ||
# All other instances of this file should be a copy of that one | ||
# | ||
# | ||
# Copy this file from https://github.com/cloudposse/terraform-null-label/blob/master/exports/context.tf | ||
# and then place it in your Terraform module to automatically get | ||
# Cloud Posse's standard configuration inputs suitable for passing | ||
# to Cloud Posse modules. | ||
# | ||
# Modules should access the whole context as `module.this.context` | ||
# to get the input variables with nulls for defaults, | ||
# for example `context = module.this.context`, | ||
# and access individual variables as `module.this.<var>`, | ||
# with final values filled in. | ||
# | ||
# For example, when using defaults, `module.this.context.delimiter` | ||
# will be null, and `module.this.delimiter` will be `-` (hyphen). | ||
# | ||
|
||
module "this" { | ||
source = "cloudposse/label/null" | ||
version = "0.24.1" # requires Terraform >= 0.13.0 | ||
|
||
enabled = var.enabled | ||
namespace = var.namespace | ||
environment = var.environment | ||
stage = var.stage | ||
name = var.name | ||
delimiter = var.delimiter | ||
attributes = var.attributes | ||
tags = var.tags | ||
additional_tag_map = var.additional_tag_map | ||
label_order = var.label_order | ||
regex_replace_chars = var.regex_replace_chars | ||
id_length_limit = var.id_length_limit | ||
label_key_case = var.label_key_case | ||
label_value_case = var.label_value_case | ||
|
||
context = var.context | ||
} | ||
|
||
# Copy contents of cloudposse/terraform-null-label/variables.tf here | ||
|
||
variable "context" { | ||
type = any | ||
default = { | ||
enabled = true | ||
namespace = null | ||
environment = null | ||
stage = null | ||
name = null | ||
delimiter = null | ||
attributes = [] | ||
tags = {} | ||
additional_tag_map = {} | ||
regex_replace_chars = null | ||
label_order = [] | ||
id_length_limit = null | ||
label_key_case = null | ||
label_value_case = null | ||
} | ||
description = <<-EOT | ||
Single object for setting entire context at once. | ||
See description of individual variables for details. | ||
Leave string and numeric variables as `null` to use default value. | ||
Individual variable settings (non-null) override settings in context object, | ||
except for attributes, tags, and additional_tag_map, which are merged. | ||
EOT | ||
|
||
validation { | ||
condition = lookup(var.context, "label_key_case", null) == null ? true : contains(["lower", "title", "upper"], var.context["label_key_case"]) | ||
error_message = "Allowed values: `lower`, `title`, `upper`." | ||
} | ||
|
||
validation { | ||
condition = lookup(var.context, "label_value_case", null) == null ? true : contains(["lower", "title", "upper", "none"], var.context["label_value_case"]) | ||
error_message = "Allowed values: `lower`, `title`, `upper`, `none`." | ||
} | ||
} | ||
|
||
variable "enabled" { | ||
type = bool | ||
default = null | ||
description = "Set to false to prevent the module from creating any resources" | ||
} | ||
|
||
variable "namespace" { | ||
type = string | ||
default = null | ||
description = "Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp'" | ||
} | ||
|
||
variable "environment" { | ||
type = string | ||
default = null | ||
description = "Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT'" | ||
} | ||
|
||
variable "stage" { | ||
type = string | ||
default = null | ||
description = "Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release'" | ||
} | ||
|
||
variable "name" { | ||
type = string | ||
default = null | ||
description = "Solution name, e.g. 'app' or 'jenkins'" | ||
} | ||
|
||
variable "delimiter" { | ||
type = string | ||
default = null | ||
description = <<-EOT | ||
Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`. | ||
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | ||
EOT | ||
} | ||
|
||
variable "attributes" { | ||
type = list(string) | ||
default = [] | ||
description = "Additional attributes (e.g. `1`)" | ||
} | ||
|
||
variable "tags" { | ||
type = map(string) | ||
default = {} | ||
description = "Additional tags (e.g. `map('BusinessUnit','XYZ')`" | ||
} | ||
|
||
variable "additional_tag_map" { | ||
type = map(string) | ||
default = {} | ||
description = "Additional tags for appending to tags_as_list_of_maps. Not added to `tags`." | ||
} | ||
|
||
variable "label_order" { | ||
type = list(string) | ||
default = null | ||
description = <<-EOT | ||
The naming order of the id output and Name tag. | ||
Defaults to ["namespace", "environment", "stage", "name", "attributes"]. | ||
You can omit any of the 5 elements, but at least one must be present. | ||
EOT | ||
} | ||
|
||
variable "regex_replace_chars" { | ||
type = string | ||
default = null | ||
description = <<-EOT | ||
Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`. | ||
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | ||
EOT | ||
} | ||
|
||
variable "id_length_limit" { | ||
type = number | ||
default = null | ||
description = <<-EOT | ||
Limit `id` to this many characters (minimum 6). | ||
Set to `0` for unlimited length. | ||
Set to `null` for default, which is `0`. | ||
Does not affect `id_full`. | ||
EOT | ||
validation { | ||
condition = var.id_length_limit == null ? true : var.id_length_limit >= 6 || var.id_length_limit == 0 | ||
error_message = "The id_length_limit must be >= 6 if supplied (not null), or 0 for unlimited length." | ||
} | ||
} | ||
|
||
variable "label_key_case" { | ||
type = string | ||
default = null | ||
description = <<-EOT | ||
The letter case of label keys (`tag` names) (i.e. `name`, `namespace`, `environment`, `stage`, `attributes`) to use in `tags`. | ||
Possible values: `lower`, `title`, `upper`. | ||
Default value: `title`. | ||
EOT | ||
|
||
validation { | ||
condition = var.label_key_case == null ? true : contains(["lower", "title", "upper"], var.label_key_case) | ||
error_message = "Allowed values: `lower`, `title`, `upper`." | ||
} | ||
} | ||
|
||
variable "label_value_case" { | ||
type = string | ||
default = null | ||
description = <<-EOT | ||
The letter case of output label values (also used in `tags` and `id`). | ||
Possible values: `lower`, `title`, `upper` and `none` (no transformation). | ||
Default value: `lower`. | ||
EOT | ||
|
||
validation { | ||
condition = var.label_value_case == null ? true : contains(["lower", "title", "upper", "none"], var.label_value_case) | ||
error_message = "Allowed values: `lower`, `title`, `upper`, `none`." | ||
} | ||
} | ||
#### End of copy of cloudposse/terraform-null-label/variables.tf |
20 changes: 20 additions & 0 deletions
20
03-first-aws-environment/components/terraform/static-site/main.tf
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,20 @@ | ||
module "cdn" { | ||
source = "cloudposse/cloudfront-s3-cdn/aws" | ||
version = "0.59.0" | ||
|
||
name = "static-site" | ||
website_enabled = true | ||
|
||
context = module.this.context | ||
} | ||
|
||
resource "aws_s3_bucket_object" "site_index" { | ||
bucket = module.cdn.s3_bucket | ||
key = "index.html" | ||
content_type = "text/html" | ||
|
||
content = <<-EOT | ||
<h1>Hello World!</h1> | ||
<p>This is ${var.stage}!</p> | ||
EOT | ||
} |
9 changes: 9 additions & 0 deletions
9
03-first-aws-environment/components/terraform/static-site/outputs.tf
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,9 @@ | ||
output "domain_name" { | ||
value = module.cdn.cf_domain_name | ||
description = "The FQDN of the created static site." | ||
} | ||
|
||
output "s3_bucket_name" { | ||
value = module.cdn.s3_bucket | ||
description = "The FQDN of the created static site." | ||
} |
3 changes: 3 additions & 0 deletions
3
03-first-aws-environment/components/terraform/static-site/providers.tf
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,3 @@ | ||
provider "aws" { | ||
region = var.region | ||
} |
4 changes: 4 additions & 0 deletions
4
03-first-aws-environment/components/terraform/static-site/variables.tf
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,4 @@ | ||
variable "region" { | ||
type = string | ||
description = "AWS Region" | ||
} |
94 changes: 94 additions & 0 deletions
94
03-first-aws-environment/components/terraform/tfstate-backend/README.md
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,94 @@ | ||
# Component: `tfstate-backend` | ||
|
||
This component is responsible for provisioning an S3 Bucket and DynamoDB table that follow security best practices for usage as a Terraform backend. | ||
|
||
## Usage | ||
|
||
**Stack Level**: Regional | ||
|
||
Here's an example snippet for how to use this component. | ||
|
||
```yaml | ||
components: | ||
terraform: | ||
tfstate-backend: | ||
vars: | ||
name: tfstate | ||
force_destroy: false | ||
prevent_unencrypted_uploads: true | ||
enable_server_side_encryption: true | ||
``` | ||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --> | ||
## Requirements | ||
| Name | Version | | ||
|------|---------| | ||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | ~> 0.14.0 | | ||
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 3.32 | | ||
| <a name="requirement_local"></a> [local](#requirement\_local) | ~> 2.1 | | ||
| <a name="requirement_template"></a> [template](#requirement\_template) | ~> 2.2 | | ||
## Providers | ||
No providers. | ||
## Modules | ||
| Name | Source | Version | | ||
|------|--------|---------| | ||
| <a name="module_tfstate_backend"></a> [tfstate\_backend](#module\_tfstate\_backend) | cloudposse/tfstate-backend/aws | 0.32.0 | | ||
| <a name="module_this"></a> [this](#module\_this) | cloudposse/label/null | 0.24.1 | | ||
## Resources | ||
No resources. | ||
## Inputs | ||
| Name | Description | Type | Default | Required | | ||
|------|-------------|------|---------|:--------:| | ||
| <a name="input_additional_tag_map"></a> [additional\_tag\_map](#input\_additional\_tag\_map) | Additional tags for appending to tags\_as\_list\_of\_maps. Not added to `tags`. | `map(string)` | `{}` | no | | ||
| <a name="input_attributes"></a> [attributes](#input\_attributes) | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no | | ||
| <a name="input_context"></a> [context](#input\_context) | Single object for setting entire context at once.<br>See description of individual variables for details.<br>Leave string and numeric variables as `null` to use default value.<br>Individual variable settings (non-null) override settings in context object,<br>except for attributes, tags, and additional\_tag\_map, which are merged. | <pre>object({<br> enabled = bool<br> namespace = string<br> environment = string<br> stage = string<br> name = string<br> delimiter = string<br> attributes = list(string)<br> tags = map(string)<br> additional_tag_map = map(string)<br> regex_replace_chars = string<br> label_order = list(string)<br> id_length_limit = number<br> })</pre> | <pre>{<br> "additional_tag_map": {},<br> "attributes": [],<br> "delimiter": null,<br> "enabled": true,<br> "environment": null,<br> "id_length_limit": null,<br> "label_order": [],<br> "name": null,<br> "namespace": null,<br> "regex_replace_chars": null,<br> "stage": null,<br> "tags": {}<br>}</pre> | no | | ||
| <a name="input_delimiter"></a> [delimiter](#input\_delimiter) | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`.<br>Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | | ||
| <a name="input_enable_server_side_encryption"></a> [enable\_server\_side\_encryption](#input\_enable\_server\_side\_encryption) | Enable DynamoDB and S3 server-side encryption | `bool` | `true` | no | | ||
| <a name="input_enabled"></a> [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | | ||
| <a name="input_environment"></a> [environment](#input\_environment) | Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | | ||
| <a name="input_force_destroy"></a> [force\_destroy](#input\_force\_destroy) | A boolean that indicates the terraform state S3 bucket can be destroyed even if it contains objects. These objects are not recoverable. | `bool` | `false` | no | | ||
| <a name="input_id_length_limit"></a> [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters.<br>Set to `0` for unlimited length.<br>Set to `null` for default, which is `0`.<br>Does not affect `id_full`. | `number` | `null` | no | | ||
| <a name="input_label_order"></a> [label\_order](#input\_label\_order) | The naming order of the id output and Name tag.<br>Defaults to ["namespace", "environment", "stage", "name", "attributes"].<br>You can omit any of the 5 elements, but at least one must be present. | `list(string)` | `null` | no | | ||
| <a name="input_name"></a> [name](#input\_name) | Solution name, e.g. 'app' or 'jenkins' | `string` | `null` | no | | ||
| <a name="input_namespace"></a> [namespace](#input\_namespace) | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | `string` | `null` | no | | ||
| <a name="input_prevent_unencrypted_uploads"></a> [prevent\_unencrypted\_uploads](#input\_prevent\_unencrypted\_uploads) | Prevent uploads of unencrypted objects to S3 | `bool` | `false` | no | | ||
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no | | ||
| <a name="input_region"></a> [region](#input\_region) | AWS Region | `string` | n/a | yes | | ||
| <a name="input_stage"></a> [stage](#input\_stage) | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | | ||
| <a name="input_tags"></a> [tags](#input\_tags) | Additional tags (e.g. `map('BusinessUnit','XYZ')` | `map(string)` | `{}` | no | | ||
| <a name="input_tfstate_account_id"></a> [tfstate\_account\_id](#input\_tfstate\_account\_id) | The ID of the account where the Terraform remote state backend is provisioned | `string` | `""` | no | | ||
| <a name="input_tfstate_assume_role"></a> [tfstate\_assume\_role](#input\_tfstate\_assume\_role) | Set to false to use the caller's role to access the Terraform remote state | `bool` | `true` | no | | ||
| <a name="input_tfstate_bucket_environment_name"></a> [tfstate\_bucket\_environment\_name](#input\_tfstate\_bucket\_environment\_name) | The name of the environment for Terraform state bucket | `string` | `""` | no | | ||
| <a name="input_tfstate_bucket_stage_name"></a> [tfstate\_bucket\_stage\_name](#input\_tfstate\_bucket\_stage\_name) | The name of the stage for Terraform state bucket | `string` | `"root"` | no | | ||
| <a name="input_tfstate_existing_role_arn"></a> [tfstate\_existing\_role\_arn](#input\_tfstate\_existing\_role\_arn) | The ARN of the existing IAM Role to access the Terraform remote state. If not provided and `remote_state_assume_role` is `true`, a role will be constructed from `remote_state_role_arn_template` | `string` | `""` | no | | ||
| <a name="input_tfstate_role_arn_template"></a> [tfstate\_role\_arn\_template](#input\_tfstate\_role\_arn\_template) | IAM Role ARN template for accessing the Terraform remote state | `string` | `"arn:aws:iam::%s:role/%s-%s-%s-%s"` | no | | ||
| <a name="input_tfstate_role_environment_name"></a> [tfstate\_role\_environment\_name](#input\_tfstate\_role\_environment\_name) | The name of the environment for Terraform state IAM role | `string` | `"gbl"` | no | | ||
| <a name="input_tfstate_role_name"></a> [tfstate\_role\_name](#input\_tfstate\_role\_name) | IAM Role name for accessing the Terraform remote state | `string` | `"terraform"` | no | | ||
| <a name="input_tfstate_role_stage_name"></a> [tfstate\_role\_stage\_name](#input\_tfstate\_role\_stage\_name) | The name of the stage for Terraform state IAM role | `string` | `"root"` | no | | ||
|
||
## Outputs | ||
|
||
| Name | Description | | ||
|------|-------------| | ||
| <a name="output_tfstate_backend_dynamodb_table_arn"></a> [tfstate\_backend\_dynamodb\_table\_arn](#output\_tfstate\_backend\_dynamodb\_table\_arn) | Terraform state DynamoDB table ARN | | ||
| <a name="output_tfstate_backend_dynamodb_table_id"></a> [tfstate\_backend\_dynamodb\_table\_id](#output\_tfstate\_backend\_dynamodb\_table\_id) | Terraform state DynamoDB table ID | | ||
| <a name="output_tfstate_backend_dynamodb_table_name"></a> [tfstate\_backend\_dynamodb\_table\_name](#output\_tfstate\_backend\_dynamodb\_table\_name) | Terraform state DynamoDB table name | | ||
| <a name="output_tfstate_backend_s3_bucket_arn"></a> [tfstate\_backend\_s3\_bucket\_arn](#output\_tfstate\_backend\_s3\_bucket\_arn) | Terraform state S3 bucket ARN | | ||
| <a name="output_tfstate_backend_s3_bucket_domain_name"></a> [tfstate\_backend\_s3\_bucket\_domain\_name](#output\_tfstate\_backend\_s3\_bucket\_domain\_name) | Terraform state S3 bucket domain name | | ||
| <a name="output_tfstate_backend_s3_bucket_id"></a> [tfstate\_backend\_s3\_bucket\_id](#output\_tfstate\_backend\_s3\_bucket\_id) | Terraform state S3 bucket ID | | ||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK --> | ||
|
||
## References | ||
|
||
- [cloudposse/terraform-aws-components](https://github.com/cloudposse/terraform-aws-components/tree/master/modules/tfstate-backend) - Cloud Posse's upstream component | ||
|
||
[<img src="https://cloudposse.com/logo-300x69.svg" height="32" align="right"/>](https://cpco.io/component) |
Oops, something went wrong.