From 6d60cb630fb81c8aab059b83126392e6d4013d89 Mon Sep 17 00:00:00 2001 From: Dan Meyers <20687081+danjbh@users.noreply.github.com> Date: Tue, 13 Oct 2020 14:14:20 -0700 Subject: [PATCH] Adding new module, documentation, and complete example (#1) * Initial commit * Updating README * Updating README * Updating documentation * Fixing small documentation thing * Renaming k8s_namespace * Updating a few things * Some minor formatting tweaks * A few more tweaks * Updating examples * Adding first draft of service acount * A couple small tweaks * Breaking out k8s resource values into TF vars * Updating vars * Renaming fixtures in complete example * Updating variable description * Fixing a formatting thing * Fixing formatting & added missing variable * Fixing a couple more things * Update README.yaml Co-authored-by: Erik Osterman * Update README.yaml Co-authored-by: Erik Osterman * Update README.yaml Co-authored-by: Erik Osterman * Update variables.tf Co-authored-by: Erik Osterman * Update variables.tf Co-authored-by: Erik Osterman * Update README.yaml Co-authored-by: Erik Osterman * Update main.tf Co-authored-by: Erik Osterman * Making a bunch of updates * Fixing a formatting thing * Update README.md Co-authored-by: Erik Osterman * Update README.md Co-authored-by: Erik Osterman * Update README.yaml Co-authored-by: Erik Osterman * Updating README * A few more updates * Adding support for agent CLI arguments * Cleaning up namespace/service_account stuff and adding outputs * Lots of updates * Updating README * Fixing namespace output * Fixing HEREDOC Co-authored-by: Erik Osterman * Fixing HEREDOC Co-authored-by: Erik Osterman * Fixing more HEREDOC * Renaming tfc_extra_envs var to agent_envs * Fixing a few things found during testing Co-authored-by: Dan Meyers Co-authored-by: Erik Osterman --- README.md | 133 +++++++++++------- README.yaml | 61 ++++---- docs/terraform.md | 30 +++- ...tures.us-east-2.tfvars => fixtures.tfvars} | 3 - examples/complete/main.tf | 14 +- examples/complete/outputs.tf | 17 +-- examples/complete/variables.tf | 4 +- examples/complete/versions.tf | 2 +- main.tf | 118 +++++++++++++++- outputs.tf | 17 +-- test/src/examples_complete_test.go | 2 +- variables.tf | 133 +++++++++++++++++- versions.tf | 3 +- 13 files changed, 411 insertions(+), 126 deletions(-) rename examples/complete/{fixtures.us-east-2.tfvars => fixtures.tfvars} (75%) diff --git a/README.md b/README.md index 40b4383..40e138a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# terraform-example-module [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-example-module.svg)](https://github.com/cloudposse/terraform-example-module/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com) [![Discourse Forum](https://img.shields.io/discourse/https/ask.sweetops.com/posts.svg)](https://ask.sweetops.com/) +# terraform-kubernetes-tfc-cloud-agent + + [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-kubernetes-tfc-cloud-agent.svg)](https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com) [![Discourse Forum](https://img.shields.io/discourse/https/ask.sweetops.com/posts.svg)](https://ask.sweetops.com/) [![README Header][readme_header_img]][readme_header_link] @@ -25,8 +27,9 @@ --> -This is `terraform-example-module` project provides all the scaffolding for a typical well-built Cloud Posse module. It's a template repository you can -use when creating new repositories. +This project installs the Terraform Cloud Agent on an existing Kubernetes cluster. You must provide your own Kubernetes provider configuration in your project! + +NOTE: Requires [Terraform Cloud Business or Terraform Enterprise](https://www.hashicorp.com/products/terraform/pricing) subscription. --- @@ -64,15 +67,29 @@ We literally have [*hundreds of terraform modules*][terraform_modules] that are **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. -Instead pin to the release tag (e.g. `?ref=tags/x.y.z`) of one of our [latest releases](https://github.com/cloudposse/terraform-example-module/releases). +Instead pin to the release tag (e.g. `?ref=tags/x.y.z`) of one of our [latest releases](https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent/releases). -Here's how to invoke this example module in your projects ```hcl -module "example" { - source = "https://github.com/cloudposse/terraform-example-module.git?ref=master" - example = "Hello world!" +provider "kubernetes" { + # Context to choose from the config file, if needed. + config_context = "example-context" + version = "~> 1.12" +} + +module "tfc_agent" { + source = "https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent.git?ref=master" + + # Your agent token generated in Terraform Cloud + token = var.tfc_agent_token + namespace = var.namespace + stage = var.stage + environment = var.environment + name = var.name + + # You can specify a namespace other than "default" + kubernetes_namespace = "tfc-agent" } ``` @@ -82,7 +99,7 @@ module "example" { ## Examples Here is an example of using this module: -- [`examples/complete`](https://github.com/cloudposse/terraform-example-module/) - complete example of using this module +- [`examples/complete`](https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent/) - complete example of using this module @@ -104,41 +121,57 @@ Available targets: | Name | Version | |------|---------| | terraform | >= 0.12.0, < 0.14.0 | -| local | ~> 1.2 | -| random | ~> 2.2 | +| kubernetes | >= 1.12.0 | ## Providers | Name | Version | |------|---------| -| random | ~> 2.2 | +| kubernetes | >= 1.12.0 | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | additional\_tag\_map | Additional tags for appending to tags\_as\_list\_of\_maps. Not added to `tags`. | `map(string)` | `{}` | no | +| agent\_cli\_args | Extra command line arguments to pass to tfc-agent | `list` | `[]` | no | +| agent\_image | Name and tag of Terraform Cloud Agent docker image | `string` | `"hashicorp/tfc-agent:latest"` | no | | attributes | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no | | context | 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. |
object({
enabled = bool
namespace = string
environment = string
stage = string
name = string
delimiter = string
attributes = list(string)
tags = map(string)
additional_tag_map = map(string)
regex_replace_chars = string
label_order = list(string)
id_length_limit = number
})
|
{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_order": [],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {}
}
| no | | delimiter | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | +| deployment\_annotations | Annotations to add to the Kubernetes deployment | `map` | `{}` | no | +| deployment\_name | Override the deployment name in Kubernetes | `string` | `null` | no | | enabled | Set to false to prevent the module from creating any resources | `bool` | `null` | no | | environment | Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | -| example | Example variable | `string` | `"hello world"` | no | | id\_length\_limit | Limit `id` to this many characters.
Set to `0` for unlimited length.
Set to `null` for default, which is `0`.
Does not affect `id_full`. | `number` | `null` | no | +| kubernetes\_namespace | Kubernetes namespace override | `string` | `null` | no | | label\_order | 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. | `list(string)` | `null` | no | | name | Solution name, e.g. 'app' or 'jenkins' | `string` | `null` | no | | namespace | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | `string` | `null` | no | +| namespace\_creation\_enabled | Enable this if the Kubernetes namespace does not already exist | `bool` | `false` | no | | regex\_replace\_chars | 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. | `string` | `null` | no | +| replicas | Number of replicas in the Kubernetes deployment | `number` | `1` | no | +| resource\_limits\_cpu | Kubernetes deployment resource hard CPU limit | `string` | `"1"` | no | +| resource\_limits\_memory | Kubernetes deployment resource hard memory limit | `string` | `"512Mi"` | no | +| resource\_requests\_cpu | Kubernetes deployment resource CPU requests | `string` | `"250m"` | no | +| resource\_requests\_memory | Kubernetes deployment resource memory requests | `string` | `"50Mi"` | no | +| service\_account\_annotations | Annotations to add to the Kubernetes service account | `map` | `{}` | no | | stage | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | | tags | Additional tags (e.g. `map('BusinessUnit','XYZ')` | `map(string)` | `{}` | no | +| tfc\_address | The HTTP or HTTPS address of the Terraform Cloud API. | `string` | `"https://app.terraform.io"` | no | +| tfc\_agent\_data\_dir | The path to a directory to store all agent-related data, including
Terraform configurations, cached Terraform release archives, etc. It is
important to ensure that the given directory is backed by plentiful
storage. | `string` | `"~/.tfc-agent"` | no | +| tfc\_agent\_disable\_update | Disable automatic core updates. | `bool` | `false` | no | +| tfc\_agent\_log\_level | The log verbosity expressed as a level string. Level options include
"trace", "debug", "info", "warn", and "error" | `string` | `"info"` | no | +| tfc\_agent\_single | Enable single mode. This causes the agent to handle at most one job and
immediately exit thereafter. Useful for running agents as ephemeral
containers, VMs, or other isolated contexts with a higher-level scheduler
or process supervisor. | `bool` | `false` | no | +| tfc\_agent\_token | The agent token to use when making requests to the Terraform Cloud API.
This token must be obtained from the API or UI. It is recommended to use
the environment variable whenever possible for configuring this setting due
to the sensitive nature of API tokens. | `string` | `""` | no | +| tfc\_extra\_envs | A map of any extra environment variables to pass to the TFC agent | `map` | `{}` | no | ## Outputs | Name | Description | |------|-------------| -| example | Example output | -| id | ID of the created example | -| random | Stable random number for this example | +| namespace | n/a | +| service\_account\_name | n/a | @@ -146,7 +179,7 @@ Available targets: ## Share the Love -Like this project? Please give it a ★ on [our GitHub](https://github.com/cloudposse/terraform-example-module)! (it helps us **a lot**) +Like this project? Please give it a ★ on [our GitHub](https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent)! (it helps us **a lot**) Are you using this project or any of our other projects? Consider [leaving a testimonial][testimonial]. =) @@ -166,15 +199,17 @@ For additional context, refer to some of these links. - [Terraform Standard Module Structure](https://www.terraform.io/docs/modules/index.html#standard-module-structure) - HashiCorp's standard module structure is a file and directory layout we recommend for reusable modules distributed in separate repositories. - [Terraform Module Requirements](https://www.terraform.io/docs/registry/modules/publish.html#requirements) - HashiCorp's guidance on all the requirements for publishing a module. Meeting the requirements for publishing a module is extremely easy. -- [Terraform `random_integer` Resource](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) - The resource random_integer generates random values from a given range, described by the min and max attributes of a given resource. - [Terraform Version Pinning](https://www.terraform.io/docs/configuration/terraform.html#specifying-a-required-terraform-version) - The required_version setting can be used to constrain which versions of the Terraform CLI can be used with your configuration +- [Terraform Cloud Agents](https://www.terraform.io/docs/cloud/workspaces/agent.html) - Terraform Cloud Agents are a solution to allow Terraform Cloud to communicate with isolated, private, or on-premises infrastructure. +- [Announcing HashiCorp Terraform Cloud Business Tier](https://www.hashicorp.com/blog/announcing-hashicorp-terraform-cloud-business) - This new tier includes enterprise features for advanced security, compliance and governance, the ability to execute multiple runs concurrently, and flexible support options. +- [Announcing Terraform Cloud Business Tier with Armon Dadgar](https://www.hashicorp.com/resources/announcing-terraform-cloud-business-tier-with-armon-dadgar) - Watch HashiCorp co-founder and CTO Armon Dadgar announce the latest addition to Terraform Cloud: the new Business tier. ## Help **Got a question?** We got answers. -File a GitHub [issue](https://github.com/cloudposse/terraform-example-module/issues), send us an [email][email] or join our [Slack Community][slack]. +File a GitHub [issue](https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent/issues), send us an [email][email] or join our [Slack Community][slack]. [![README Commercial Support][readme_commercial_support_img]][readme_commercial_support_link] @@ -222,7 +257,7 @@ Sign up for [our newsletter][newsletter] that covers everything on our technolog ### Bug Reports & Feature Requests -Please use the [issue tracker](https://github.com/cloudposse/terraform-example-module/issues) to report any bugs or file feature requests. +Please use the [issue tracker](https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent/issues) to report any bugs or file feature requests. ### Developing @@ -301,42 +336,42 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply ### Contributors -| [![Erik Osterman][osterman_avatar]][osterman_homepage]
[Erik Osterman][osterman_homepage] | +| [![Dan Meyers][danjbh_avatar]][danjbh_homepage]
[Dan Meyers][danjbh_homepage] | |---| - [osterman_homepage]: https://github.com/osterman - [osterman_avatar]: https://img.cloudposse.com/150x150/https://github.com/osterman.png + [danjbh_homepage]: https://github.com/danjbh + [danjbh_avatar]: https://img.cloudposse.com/150x150/https://github.com/danjbh.png [![README Footer][readme_footer_img]][readme_footer_link] [![Beacon][beacon]][website] [logo]: https://cloudposse.com/logo-300x69.svg - [docs]: https://cpco.io/docs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=docs - [website]: https://cpco.io/homepage?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=website - [github]: https://cpco.io/github?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=github - [jobs]: https://cpco.io/jobs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=jobs - [hire]: https://cpco.io/hire?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=hire - [slack]: https://cpco.io/slack?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=slack - [linkedin]: https://cpco.io/linkedin?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=linkedin - [twitter]: https://cpco.io/twitter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=twitter - [testimonial]: https://cpco.io/leave-testimonial?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=testimonial - [office_hours]: https://cloudposse.com/office-hours?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=office_hours - [newsletter]: https://cpco.io/newsletter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=newsletter - [discourse]: https://ask.sweetops.com/?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=discourse - [email]: https://cpco.io/email?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=email - [commercial_support]: https://cpco.io/commercial-support?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=commercial_support - [we_love_open_source]: https://cpco.io/we-love-open-source?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=we_love_open_source - [terraform_modules]: https://cpco.io/terraform-modules?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=terraform_modules + [docs]: https://cpco.io/docs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=docs + [website]: https://cpco.io/homepage?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=website + [github]: https://cpco.io/github?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=github + [jobs]: https://cpco.io/jobs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=jobs + [hire]: https://cpco.io/hire?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=hire + [slack]: https://cpco.io/slack?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=slack + [linkedin]: https://cpco.io/linkedin?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=linkedin + [twitter]: https://cpco.io/twitter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=twitter + [testimonial]: https://cpco.io/leave-testimonial?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=testimonial + [office_hours]: https://cloudposse.com/office-hours?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=office_hours + [newsletter]: https://cpco.io/newsletter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=newsletter + [discourse]: https://ask.sweetops.com/?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=discourse + [email]: https://cpco.io/email?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=email + [commercial_support]: https://cpco.io/commercial-support?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=commercial_support + [we_love_open_source]: https://cpco.io/we-love-open-source?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=we_love_open_source + [terraform_modules]: https://cpco.io/terraform-modules?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=terraform_modules [readme_header_img]: https://cloudposse.com/readme/header/img - [readme_header_link]: https://cloudposse.com/readme/header/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=readme_header_link + [readme_header_link]: https://cloudposse.com/readme/header/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=readme_header_link [readme_footer_img]: https://cloudposse.com/readme/footer/img - [readme_footer_link]: https://cloudposse.com/readme/footer/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=readme_footer_link + [readme_footer_link]: https://cloudposse.com/readme/footer/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=readme_footer_link [readme_commercial_support_img]: https://cloudposse.com/readme/commercial-support/img - [readme_commercial_support_link]: https://cloudposse.com/readme/commercial-support/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-example-module&utm_content=readme_commercial_support_link - [share_twitter]: https://twitter.com/intent/tweet/?text=terraform-example-module&url=https://github.com/cloudposse/terraform-example-module - [share_linkedin]: https://www.linkedin.com/shareArticle?mini=true&title=terraform-example-module&url=https://github.com/cloudposse/terraform-example-module - [share_reddit]: https://reddit.com/submit/?url=https://github.com/cloudposse/terraform-example-module - [share_facebook]: https://facebook.com/sharer/sharer.php?u=https://github.com/cloudposse/terraform-example-module - [share_googleplus]: https://plus.google.com/share?url=https://github.com/cloudposse/terraform-example-module - [share_email]: mailto:?subject=terraform-example-module&body=https://github.com/cloudposse/terraform-example-module - [beacon]: https://ga-beacon.cloudposse.com/UA-76589703-4/cloudposse/terraform-example-module?pixel&cs=github&cm=readme&an=terraform-example-module + [readme_commercial_support_link]: https://cloudposse.com/readme/commercial-support/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-kubernetes-tfc-cloud-agent&utm_content=readme_commercial_support_link + [share_twitter]: https://twitter.com/intent/tweet/?text=terraform-kubernetes-tfc-cloud-agent&url=https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent + [share_linkedin]: https://www.linkedin.com/shareArticle?mini=true&title=terraform-kubernetes-tfc-cloud-agent&url=https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent + [share_reddit]: https://reddit.com/submit/?url=https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent + [share_facebook]: https://facebook.com/sharer/sharer.php?u=https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent + [share_googleplus]: https://plus.google.com/share?url=https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent + [share_email]: mailto:?subject=terraform-kubernetes-tfc-cloud-agent&body=https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent + [beacon]: https://ga-beacon.cloudposse.com/UA-76589703-4/cloudposse/terraform-kubernetes-tfc-cloud-agent?pixel&cs=github&cm=readme&an=terraform-kubernetes-tfc-cloud-agent diff --git a/README.yaml b/README.yaml index dfc9acb..daa3c15 100644 --- a/README.yaml +++ b/README.yaml @@ -5,7 +5,7 @@ # # Name of this project -name: terraform-example-module +name: terraform-kubernetes-tfc-cloud-agent # Logo for this project #logo: docs/logo.png @@ -20,13 +20,13 @@ copyrights: year: "2020" # Canonical GitHub repo -github_repo: cloudposse/terraform-example-module +github_repo: cloudposse/terraform-kubernetes-tfc-cloud-agent # Badges to display badges: - name: "Latest Release" - image: "https://img.shields.io/github/release/cloudposse/terraform-example-module.svg" - url: "https://github.com/cloudposse/terraform-example-module/releases/latest" + image: "https://img.shields.io/github/release/cloudposse/terraform-kubernetes-tfc-cloud-agent.svg" + url: "https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent/releases/latest" - name: "Slack Community" image: "https://slack.cloudposse.com/badge.svg" url: "https://slack.cloudposse.com" @@ -48,41 +48,54 @@ references: - name: "Terraform Module Requirements" description: "HashiCorp's guidance on all the requirements for publishing a module. Meeting the requirements for publishing a module is extremely easy." url: "https://www.terraform.io/docs/registry/modules/publish.html#requirements" - - name: "Terraform `random_integer` Resource" - description: "The resource random_integer generates random values from a given range, described by the min and max attributes of a given resource." - url: "https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer" - name: "Terraform Version Pinning" description: "The required_version setting can be used to constrain which versions of the Terraform CLI can be used with your configuration" url: "https://www.terraform.io/docs/configuration/terraform.html#specifying-a-required-terraform-version" + - name: "Terraform Cloud Agents" + description: "Terraform Cloud Agents are a solution to allow Terraform Cloud to communicate with isolated, private, or on-premises infrastructure." + url: "https://www.terraform.io/docs/cloud/workspaces/agent.html" + - name: "Announcing HashiCorp Terraform Cloud Business Tier" + description: "This new tier includes enterprise features for advanced security, compliance and governance, the ability to execute multiple runs concurrently, and flexible support options." + url: "https://www.hashicorp.com/blog/announcing-hashicorp-terraform-cloud-business" + - name: "Announcing Terraform Cloud Business Tier with Armon Dadgar" + description: "Watch HashiCorp co-founder and CTO Armon Dadgar announce the latest addition to Terraform Cloud: the new Business tier." + url: "https://www.hashicorp.com/resources/announcing-terraform-cloud-business-tier-with-armon-dadgar" # Short description of this project description: |- - This is `terraform-example-module` project provides all the scaffolding for a typical well-built Cloud Posse module. It's a template repository you can - use when creating new repositories. - -# Introduction to the project -#introduction: |- -# This is an introduction. + This project installs the Terraform Cloud Agent on an existing Kubernetes cluster. You must provide your own Kubernetes provider configuration in your project! + + NOTE: Requires [Terraform Cloud Business or Terraform Enterprise](https://www.hashicorp.com/products/terraform/pricing) subscription. # How to use this module. Should be an easy example to copy and paste. usage: |- - Here's how to invoke this example module in your projects ```hcl - module "example" { - source = "https://github.com/cloudposse/terraform-example-module.git?ref=master" - example = "Hello world!" + provider "kubernetes" { + # Context to choose from the config file, if needed. + config_context = "example-context" + version = "~> 1.12" + } + + module "tfc_agent" { + source = "https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent.git?ref=master" + + # Your agent token generated in Terraform Cloud + token = var.tfc_agent_token + namespace = var.namespace + stage = var.stage + environment = var.environment + name = var.name + + # You can specify a namespace other than "default" + kubernetes_namespace = "tfc-agent" } ``` # Example usage examples: |- Here is an example of using this module: - - [`examples/complete`](https://github.com/cloudposse/terraform-example-module/) - complete example of using this module - -# How to get started quickly -#quickstart: |- -# Here's how to get started... + - [`examples/complete`](https://github.com/cloudposse/terraform-kubernetes-tfc-cloud-agent/) - complete example of using this module # Other files to include in this README from the project folder include: @@ -91,5 +104,5 @@ include: # Contributors to this project contributors: - - name: "Erik Osterman" - github: "osterman" + - name: "Dan Meyers" + github: "danjbh" diff --git a/docs/terraform.md b/docs/terraform.md index 7fdf496..084d947 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -4,40 +4,56 @@ | Name | Version | |------|---------| | terraform | >= 0.12.0, < 0.14.0 | -| local | ~> 1.2 | -| random | ~> 2.2 | +| kubernetes | >= 1.12.0 | ## Providers | Name | Version | |------|---------| -| random | ~> 2.2 | +| kubernetes | >= 1.12.0 | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | additional\_tag\_map | Additional tags for appending to tags\_as\_list\_of\_maps. Not added to `tags`. | `map(string)` | `{}` | no | +| agent\_cli\_args | Extra command line arguments to pass to tfc-agent | `list` | `[]` | no | +| agent\_image | Name and tag of Terraform Cloud Agent docker image | `string` | `"hashicorp/tfc-agent:latest"` | no | | attributes | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no | | context | 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. |
object({
enabled = bool
namespace = string
environment = string
stage = string
name = string
delimiter = string
attributes = list(string)
tags = map(string)
additional_tag_map = map(string)
regex_replace_chars = string
label_order = list(string)
id_length_limit = number
})
|
{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_order": [],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {}
}
| no | | delimiter | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | +| deployment\_annotations | Annotations to add to the Kubernetes deployment | `map` | `{}` | no | +| deployment\_name | Override the deployment name in Kubernetes | `string` | `null` | no | | enabled | Set to false to prevent the module from creating any resources | `bool` | `null` | no | | environment | Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | -| example | Example variable | `string` | `"hello world"` | no | | id\_length\_limit | Limit `id` to this many characters.
Set to `0` for unlimited length.
Set to `null` for default, which is `0`.
Does not affect `id_full`. | `number` | `null` | no | +| kubernetes\_namespace | Kubernetes namespace override | `string` | `null` | no | | label\_order | 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. | `list(string)` | `null` | no | | name | Solution name, e.g. 'app' or 'jenkins' | `string` | `null` | no | | namespace | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | `string` | `null` | no | +| namespace\_creation\_enabled | Enable this if the Kubernetes namespace does not already exist | `bool` | `false` | no | | regex\_replace\_chars | 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. | `string` | `null` | no | +| replicas | Number of replicas in the Kubernetes deployment | `number` | `1` | no | +| resource\_limits\_cpu | Kubernetes deployment resource hard CPU limit | `string` | `"1"` | no | +| resource\_limits\_memory | Kubernetes deployment resource hard memory limit | `string` | `"512Mi"` | no | +| resource\_requests\_cpu | Kubernetes deployment resource CPU requests | `string` | `"250m"` | no | +| resource\_requests\_memory | Kubernetes deployment resource memory requests | `string` | `"50Mi"` | no | +| service\_account\_annotations | Annotations to add to the Kubernetes service account | `map` | `{}` | no | | stage | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | | tags | Additional tags (e.g. `map('BusinessUnit','XYZ')` | `map(string)` | `{}` | no | +| tfc\_address | The HTTP or HTTPS address of the Terraform Cloud API. | `string` | `"https://app.terraform.io"` | no | +| tfc\_agent\_data\_dir | The path to a directory to store all agent-related data, including
Terraform configurations, cached Terraform release archives, etc. It is
important to ensure that the given directory is backed by plentiful
storage. | `string` | `"~/.tfc-agent"` | no | +| tfc\_agent\_disable\_update | Disable automatic core updates. | `bool` | `false` | no | +| tfc\_agent\_log\_level | The log verbosity expressed as a level string. Level options include
"trace", "debug", "info", "warn", and "error" | `string` | `"info"` | no | +| tfc\_agent\_single | Enable single mode. This causes the agent to handle at most one job and
immediately exit thereafter. Useful for running agents as ephemeral
containers, VMs, or other isolated contexts with a higher-level scheduler
or process supervisor. | `bool` | `false` | no | +| tfc\_agent\_token | The agent token to use when making requests to the Terraform Cloud API.
This token must be obtained from the API or UI. It is recommended to use
the environment variable whenever possible for configuring this setting due
to the sensitive nature of API tokens. | `string` | `""` | no | +| tfc\_extra\_envs | A map of any extra environment variables to pass to the TFC agent | `map` | `{}` | no | ## Outputs | Name | Description | |------|-------------| -| example | Example output | -| id | ID of the created example | -| random | Stable random number for this example | +| namespace | n/a | +| service\_account\_name | n/a | diff --git a/examples/complete/fixtures.us-east-2.tfvars b/examples/complete/fixtures.tfvars similarity index 75% rename from examples/complete/fixtures.us-east-2.tfvars rename to examples/complete/fixtures.tfvars index 1e0ce68..4fa9294 100644 --- a/examples/complete/fixtures.us-east-2.tfvars +++ b/examples/complete/fixtures.tfvars @@ -1,5 +1,3 @@ -region = "us-east-2" - namespace = "eg" environment = "ue2" @@ -7,4 +5,3 @@ environment = "ue2" stage = "test" name = "example" - diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 38880b7..136f805 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -1,7 +1,13 @@ -module "example" { - source = "../.." - - example = var.example +provider "kubernetes" { + version = "~> 1.12" +} +module "tfc_agent" { + source = "../.." context = module.this.context + + tfc_agent_token = var.tfc_agent_token + + namespace_creation_enabled = true + kubernetes_namespace = "foo" } diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 20aa3e3..744c3ca 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -1,14 +1,7 @@ -output "id" { - description = "ID of the created example" - value = module.example.id +output "service_account_name" { + value = module.tfc_agent.service_account_name } -output "example" { - description = "Output \"example\" from example module" - value = module.example.example -} - -output "random" { - description = "Output \"random\" from example module" - value = module.example.random -} +output "namespace" { + value = module.tfc_agent.namespace +} \ No newline at end of file diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf index 9a04f21..c9aa9df 100644 --- a/examples/complete/variables.tf +++ b/examples/complete/variables.tf @@ -1,4 +1,4 @@ -variable "example" { +variable "tfc_agent_token" { type = string - description = "The value which will be passed to the example module" + description = "The preconfigured Terraform Cloud Agent token" } diff --git a/examples/complete/versions.tf b/examples/complete/versions.tf index 572ee1f..4a34796 100644 --- a/examples/complete/versions.tf +++ b/examples/complete/versions.tf @@ -2,6 +2,6 @@ terraform { required_version = ">= 0.12.0, < 0.14" required_providers { - local = "~> 1.2" + kubernetes = "~> 1.12" } } diff --git a/main.tf b/main.tf index 8e1225e..dd4b4a7 100644 --- a/main.tf +++ b/main.tf @@ -1,13 +1,117 @@ -resource "random_integer" "example" { +locals { + service_account_name = coalesce(var.deployment_name, module.this.id, "tfc-agent") + deployment_name = coalesce(var.deployment_name, module.this.id, "tfc-agent") + + namespace = coalesce(var.kubernetes_namespace, "default") +} + +resource "kubernetes_namespace" "namespace" { + count = var.namespace_creation_enabled ? 1 : 0 + metadata { + name = local.namespace + } +} + +resource "kubernetes_service_account" "service_account" { count = module.this.enabled ? 1 : 0 - min = 1 - max = 50000 - keepers = { - example = var.example + metadata { + name = local.service_account_name + namespace = local.namespace + annotations = var.service_account_annotations } } -locals { - example = format("%v %v", var.example, join("", random_integer.example[*].result)) +resource "kubernetes_secret" "secret" { + metadata { + name = local.deployment_name + namespace = local.namespace + } + + data = { + token = var.tfc_agent_token + } +} + +resource "kubernetes_deployment" "tfc_cloud_agent" { + count = module.this.enabled ? 1 : 0 + + metadata { + name = local.deployment_name + namespace = local.namespace + labels = module.this.tags + } + spec { + selector { + match_labels = module.this.tags + } + replicas = var.replicas + + template { + metadata { + namespace = local.namespace + labels = module.this.tags + annotations = var.deployment_annotations + } + spec { + service_account_name = local.service_account_name + automount_service_account_token = true + container { + image = var.agent_image + name = "tfc-agent" + args = var.agent_cli_args + env { + name = "TFC_AGENT_TOKEN" + value_from { + secret_key_ref { + key = "token" + name = local.deployment_name + } + } + } + env { + name = "TFC_AGENT_NAME" + value = coalesce(module.this.id, "tfc-agent") + } + env { + name = "TFC_AGENT_LOG_LEVEL" + value = var.tfc_agent_log_level + } + env { + name = "TFC_AGENT_DATA_DIR" + value = var.tfc_agent_data_dir + } + env { + name = "TFC_AGENT_SINGLE" + value = var.tfc_agent_single + } + env { + name = "TFC_AGENT_DISABLE_UPDATE" + value = var.tfc_agent_disable_update + } + env { + name = "TFC_ADDRESS" + value = var.tfc_address + } + dynamic "env" { + for_each = var.agent_envs + content { + name = env.key + value = env.value + } + } + resources { + limits { + cpu = var.resource_limits_cpu + memory = var.resource_limits_memory + } + requests { + cpu = var.resource_requests_cpu + memory = var.resource_requests_memory + } + } + } + } + } + } } diff --git a/outputs.tf b/outputs.tf index 23e08b2..9eac91f 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,14 +1,9 @@ -output "id" { - description = "ID of the created example" - value = module.this.enabled ? module.this.id : null +output "service_account_name" { + value = local.service_account_name + description = "Name of the Kubernetes service account" } -output "example" { - description = "Example output" - value = module.this.enabled ? local.example : null -} - -output "random" { - description = "Stable random number for this example" - value = module.this.enabled ? join("", random_integer.example[*].result) : null +output "namespace" { + value = local.namespace + description = "Name of the Kubernetes namespace" } diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go index d14510d..7805e88 100644 --- a/test/src/examples_complete_test.go +++ b/test/src/examples_complete_test.go @@ -23,7 +23,7 @@ func TestExamplesComplete(t *testing.T) { TerraformDir: "../../examples/complete", Upgrade: true, // Variables to pass to our Terraform code using -var-file options - VarFiles: []string{"fixtures.us-east-2.tfvars"}, + VarFiles: []string{"fixtures.tfvars"}, // We always include a random attribute so that parallel tests // and AWS resources do not interfere with each other Vars: map[string]interface{}{ diff --git a/variables.tf b/variables.tf index ff9b03b..0912b49 100644 --- a/variables.tf +++ b/variables.tf @@ -1,4 +1,131 @@ -variable "example" { - description = "Example variable" - default = "hello world" +variable "deployment_name" { + type = string + default = null + description = "Override the deployment name in Kubernetes" +} + +variable "kubernetes_namespace" { + type = string + default = null + description = "Kubernetes namespace override" +} + +variable "namespace_creation_enabled" { + type = bool + default = false + description = "Enable this if the Kubernetes namespace does not already exist" +} + +variable "replicas" { + type = number + default = 1 + description = "Number of replicas in the Kubernetes deployment" +} + +variable "deployment_annotations" { + type = map + default = {} + description = "Annotations to add to the Kubernetes deployment" +} + +variable "service_account_annotations" { + type = map + default = {} + description = "Annotations to add to the Kubernetes service account" +} + +variable "agent_image" { + type = string + default = "hashicorp/tfc-agent:latest" + description = "Name and tag of Terraform Cloud Agent docker image" +} + +variable "agent_cli_args" { + type = list + default = [] + description = "Extra command line arguments to pass to tfc-agent" +} + +variable "agent_envs" { + type = map + default = {} + description = "A map of any extra environment variables to pass to the TFC agent" +} + +variable "tfc_agent_token" { + type = string + default = "" + description = <<-EOF + The agent token to use when making requests to the Terraform Cloud API. + This token must be obtained from the API or UI. It is recommended to use + the environment variable whenever possible for configuring this setting due + to the sensitive nature of API tokens. + EOF +} + +variable "tfc_agent_log_level" { + type = string + default = "info" + description = <<-EOF + The log verbosity expressed as a level string. Level options include + "trace", "debug", "info", "warn", and "error" + EOF +} + +variable "tfc_agent_data_dir" { + type = string + default = "~/.tfc-agent" + description = <<-EOF + The path to a directory to store all agent-related data, including + Terraform configurations, cached Terraform release archives, etc. It is + important to ensure that the given directory is backed by plentiful + storage. + EOF +} + +variable "tfc_agent_single" { + type = bool + default = false + description = <<-EOF + Enable single mode. This causes the agent to handle at most one job and + immediately exit thereafter. Useful for running agents as ephemeral + containers, VMs, or other isolated contexts with a higher-level scheduler + or process supervisor. + EOF +} + +variable "tfc_agent_disable_update" { + type = bool + default = false + description = "Disable automatic core updates." +} + +variable "tfc_address" { + type = string + default = "https://app.terraform.io" + description = "The HTTP or HTTPS address of the Terraform Cloud API." +} + +variable "resource_limits_cpu" { + type = string + default = "1" + description = "Kubernetes deployment resource hard CPU limit" +} + +variable "resource_limits_memory" { + type = string + default = "512Mi" + description = "Kubernetes deployment resource hard memory limit" +} + +variable "resource_requests_cpu" { + type = string + default = "250m" + description = "Kubernetes deployment resource CPU requests" +} + +variable "resource_requests_memory" { + type = string + default = "50Mi" + description = "Kubernetes deployment resource memory requests" } diff --git a/versions.tf b/versions.tf index b108528..ba071b4 100644 --- a/versions.tf +++ b/versions.tf @@ -2,7 +2,6 @@ terraform { required_version = ">= 0.12.0, < 0.14.0" required_providers { - local = "~> 1.2" - random = "~> 2.2" + kubernetes = ">= 1.12.0" } }