From 29cd34921177153e9c37f18fcf00c043fcf250b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20W=C3=BCrbach?= Date: Fri, 6 Oct 2023 12:28:08 +0200 Subject: [PATCH] initial commit Co-Authored-By: Tobias Babin <140624220+TobiasBabin@users.noreply.github.com> Co-Authored-By: William Overton Co-Authored-By: nickhumanitec <121984975+nickhumanitec@users.noreply.github.com> --- .github/workflows/ci.yaml | 41 ++++ .gitignore | 10 + LICENSE | 201 ++++++++++++++++++ Makefile | 29 +++ README.md | 156 ++++++++++++++ docs/.terraform-docs-example.yaml | 9 + docs/.terraform-docs.yaml | 15 ++ .../AWS-reference-architecture-Humanitec.png | Bin 0 -> 130721 bytes examples/with-backstage/README.md | 140 ++++++++++++ examples/with-backstage/aws-github.tf | 51 +++++ examples/with-backstage/backstage-aws.tf | 14 ++ examples/with-backstage/backstage-github.tf | 62 ++++++ .../with-backstage/backstage-humanitec.tf | 191 +++++++++++++++++ .../with-backstage/create-gh-app/index.js | 153 +++++++++++++ examples/with-backstage/main.tf | 33 +++ examples/with-backstage/provider.tf | 30 +++ .../with-backstage/terraform.tfvars.example | 18 ++ examples/with-backstage/variables.tf | 31 +++ main.tf | 56 +++++ modules/base/.terraform-docs.yaml | 11 + modules/base/README.md | 83 ++++++++ modules/base/humanitec.tf | 63 ++++++ modules/base/main.tf | 158 ++++++++++++++ modules/base/meta.tf | 7 + modules/base/outputs.tf | 58 +++++ modules/base/providers.tf | 19 ++ modules/base/variables.tf | 91 ++++++++ terraform.tfvars.example | 9 + variables.tf | 15 ++ 29 files changed, 1754 insertions(+) create mode 100644 .github/workflows/ci.yaml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 docs/.terraform-docs-example.yaml create mode 100644 docs/.terraform-docs.yaml create mode 100644 docs/images/AWS-reference-architecture-Humanitec.png create mode 100644 examples/with-backstage/README.md create mode 100644 examples/with-backstage/aws-github.tf create mode 100644 examples/with-backstage/backstage-aws.tf create mode 100644 examples/with-backstage/backstage-github.tf create mode 100644 examples/with-backstage/backstage-humanitec.tf create mode 100644 examples/with-backstage/create-gh-app/index.js create mode 100644 examples/with-backstage/main.tf create mode 100644 examples/with-backstage/provider.tf create mode 100644 examples/with-backstage/terraform.tfvars.example create mode 100644 examples/with-backstage/variables.tf create mode 100644 main.tf create mode 100644 modules/base/.terraform-docs.yaml create mode 100644 modules/base/README.md create mode 100644 modules/base/humanitec.tf create mode 100644 modules/base/main.tf create mode 100644 modules/base/meta.tf create mode 100644 modules/base/outputs.tf create mode 100644 modules/base/providers.tf create mode 100644 modules/base/variables.tf create mode 100644 terraform.tfvars.example create mode 100644 variables.tf diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..10a0032 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,41 @@ +name: CI +on: + push: + branches: [main] + pull_request: + branches: [main] +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: hashicorp/setup-terraform@v2 + with: + terraform_version: ~1.5 + + - name: Terraform Version + run: terraform -version + + - name: Install terraform-docs + run: | + WORK_DIR=$(mktemp -d) + curl -Lo ${WORK_DIR}/terraform-docs.tar.gz https://github.com/terraform-docs/terraform-docs/releases/download/v0.16.0/terraform-docs-v0.16.0-$(uname)-amd64.tar.gz + cd ${WORK_DIR} + tar -xzf terraform-docs.tar.gz + chmod +x terraform-docs + mv terraform-docs /usr/local/bin/terraform-docs + - name: Generate docs + run: make docs + + - name: Check git diff is clean (all files generated should be committed) + run: git diff --exit-code + + - name: Terraform Format Check + run: make fmt-check + + - name: Stub Github App credentials (required for validation) + run: cd ./examples/with-backstage && STUB_FILE=1 node create-gh-app/index.js + + - name: Terraform Validate + run: make validate diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e9686a8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +.idea +.terraform +.terraform.lock.hcl +*.tfstate +*.tfstate.* +*.tfplan +*.terraformrc +*.tfvars +terraform.rc +github-app-credentials.json diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ccca688 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +TF_DIRS = $(patsubst %/main.tf, %, $(shell find . -type d -name .terraform -prune -o -name 'main.tf' -print)) +VALIDATE_TF_DIRS = $(addprefix validate-,$(TF_DIRS)) + +# Generate docs +.PHONY: docs +docs: + terraform-docs --lockfile=false ./modules/base + terraform-docs --config docs/.terraform-docs.yaml . + terraform-docs --config docs/.terraform-docs-example.yaml . + terraform-docs --config docs/.terraform-docs.yaml ./examples/with-backstage + terraform-docs --config docs/.terraform-docs-example.yaml ./examples/with-backstage + +# Format all terraform files +fmt: + terraform fmt -recursive + +# Check if all terraform files are formatted +fmt-check: + terraform fmt -recursive -check + +# Validate a terraform directories +$(VALIDATE_TF_DIRS): validate-%: + @echo "Validate $*" + terraform -chdir="$*" init -upgrade + terraform -chdir="$*" validate + +# Validate all terraform directories +validate: $(VALIDATE_TF_DIRS) + @echo "All validated" diff --git a/README.md b/README.md new file mode 100644 index 0000000..7139df6 --- /dev/null +++ b/README.md @@ -0,0 +1,156 @@ +# Humanitec AWS Reference Architecture + +This repo contains an implementation of part of the Humanitec Reference Architecture for an Internal Developer Platform. + +To install an implementation containing add-ons, follow the separate README. We currently feature these add-ons: + +* [Base layer plus Backstage](examples/with-backstage/) + +![AWS reference architecture Humanitec](docs/images/AWS-reference-architecture-Humanitec.png) + +This repo covers the base layer of the implementation for AWS. + +By default, the following will be provisioned: + +- VPC +- EKS Cluster +- IAM User to access the cluster +- Ingress NGINX in the cluster +- Resource Definitions in Humanitec for: + - Kubernetes Cluster + - Logging + +## Prerequisites + +* A Humanitec account with the `Administrator` role in an Organization. Get a [free trial](https://humanitec.com/free-trial?utm_source=github&utm_medium=referral&utm_campaign=aws_refarch_repo) if you are just starting. +* An AWS account +* [AWS CLI](https://aws.amazon.com/cli/) installed locally +* [terraform](https://www.terraform.io/) installed locally + +## Usage + +**Note: Using this Reference Architecture Implementation will incur costs for your AWS project.** + +It is recommended that you fully review the code before you run it to ensure you understand the impact of provisioning this infrastructure. +Humanitec does not take responsibility for any costs incurred or damage caused when using the Reference Architecture Implementation. + +This reference architecture implementation uses Terraform. You will need to do the following: + +1. [Fork this GitHub repo](https://github.com/humanitec-architecture/reference-architecture-aws/fork), clone it to your local machine and navigate to the root of the repository. + +2. Set the required input variables. (see [Required input variables](#required-input-variables)) + +3. Ensure you are logged in with `aws`. (Follow the [quickstart](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-quickstart.html) if you aren't) + +4. Set the `HUMANITEC_TOKEN` environment variable to an appropriate Humanitec API token with the `Administrator` role on the Humanitec Organization. + + For example: + + ``` + export HUMANITEC_TOKEN="my-humanitec-api-token" + ``` + +5. Run terraform: + + ``` + terraform init + terraform plan + terraform apply + ``` + + `terraform plan` and `apply` might output this message: + ``` + │ Warning: Argument is deprecated + │ + │ with module.base.module.aws_eks.aws_eks_addon.this["aws-ebs-csi-driver"], + │ [...] + ``` + This is due to an upstream issue with the Terraform AWS modules, and can be ignored. + +### Required input variables + +Terraform reads variables by default from a file called `terraform.tfvars`. You can create your own file by renaming the `terraform.tfvars.example` file in the root of the repo and then filling in the missing values. + +You can see find a details about each of those variables and additional supported variables under [Inputs](#inputs). + + +## Verify your result + +Check for the existence of key elements of the reference architecture. This is a subset of all elements only. For a complete list of what was installed, review the Terraform code. + +1. Set the `HUMANITEC_ORG` environment variable to the ID of your Humanitec Organization (must be all lowercase): + + ``` + export HUMANITEC_ORG="my-humanitec-org" + ``` + +2. Verify the existence of the Resource Definition for the EKS cluster in your Humanitec Organization: + + ``` + curl -s https://api.humanitec.io/orgs/${HUMANITEC_ORG}/resources/defs/ref-arch \ + --header "Authorization: Bearer ${HUMANITEC_TOKEN}" \ + | jq .id,.type + ``` + + This should output: + ``` + "ref-arch" + "k8s-cluster" + ``` + +3. Verify the existence of the newly created EKS cluster: + + ``` + aws eks list-clusters --region + ``` + + This should output: + + ``` + { + "clusters": [ + "ref-arch", + "[more previously existing clusters here]" + ] + } + ``` + +## Cleaning up + +Once you are finished with the reference architecture, you can remove all provisioned infrastrcuture and the resource definitions created in Humanitec with the following: + +1. Ensure you are (still) logged in with `aws`. + +2. Ensure you still have the `HUMANITEC_TOKEN` environment variable set to an appropriate Humanitec API token with the `Administrator` role on the Humanitec Organization. + +3. Run terraform: + + ``` + terraform destroy + ``` + +## Terraform docs + + +### Requirements + +| Name | Version | +|------|---------| +| terraform | >= 1.3.0 | +| aws | ~> 5.17 | +| humanitec | ~> 0.13 | + +### Modules + +| Name | Source | Version | +|------|--------|---------| +| base | ./modules/base | n/a | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| aws\_account\_id | AWS Account (ID) to use | `string` | n/a | yes | +| aws\_region | AWS Region to deploy into | `string` | n/a | yes | +| humanitec\_org\_id | Humanitec Organization ID | `string` | n/a | yes | + diff --git a/docs/.terraform-docs-example.yaml b/docs/.terraform-docs-example.yaml new file mode 100644 index 0000000..4bf5908 --- /dev/null +++ b/docs/.terraform-docs-example.yaml @@ -0,0 +1,9 @@ +formatter: "tfvars hcl" + +output: + file: "./terraform.tfvars.example" + mode: replace + template: "{{ .Content }}" + +settings: + description: true diff --git a/docs/.terraform-docs.yaml b/docs/.terraform-docs.yaml new file mode 100644 index 0000000..f1f7132 --- /dev/null +++ b/docs/.terraform-docs.yaml @@ -0,0 +1,15 @@ +formatter: "markdown table" + +output: + file: "./README.md" + +sort: + enabled: true + by: required + + +settings: + anchor: false + indent: 3 + hide-empty: true + lockfile: false diff --git a/docs/images/AWS-reference-architecture-Humanitec.png b/docs/images/AWS-reference-architecture-Humanitec.png new file mode 100644 index 0000000000000000000000000000000000000000..7cfbd4bf37fcea5abfe09dc0e31d2eb28ba32e46 GIT binary patch literal 130721 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%0DwD^pE+R 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 uo;k;IykG-=M*jX+nJ Install + * “Okay, […] was installed on the […] account.” ~> You can close the window and server. + +## Usage + +Follow the same steps as for the [base layer](../../README.md#usage), applying these modifications: +* Execute `cd ./examples/with-backstage` after cloning the repo. Execute all subsequent commands in this directory. +* In particular, use the `./examples/with-backstage/terraform.tfvars.example` file as the basis for your `terraform.tfvars` file. It defines additional variables needed to setup and configure Backstage. + +## Verify your result + +Check for the existence of key elements of the backstage module. This is a subset of all elements only. For a complete list of what was installed, review the Terraform code. + +1. Perform the [verification steps of the base installation](../../README.md) if you have not already done so. +2. Verify the existence of the Backstage Application in your Humanitec Organization: + ``` + curl -s https://api.humanitec.io/orgs/${HUMANITEC_ORG}/apps/backstage \ + --header "Authorization: Bearer ${HUMANITEC_TOKEN}" + ``` + This should output a JSON formatted representation of the Application like so: + ``` + {"id":"backstage","name":"backstage","created_at":"2023-10-02T13:44:27Z","created_by":"s-d3e94a0e-8b53-29f9-b666-27548b7e06e0","envs":[{"id":"development","name":"Development","type":"development"}]} + ``` + You can also check for the Application in the [Humanitec Platform Orchestrator UI](https://app.humanitec.io). + +3. Connect to your EKS cluster via `kubectl`. See the [AWS documentation](https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html) or use this command: + ``` + aws eks update-kubeconfig --region --name ref-arch + ``` +4. Get the elements in the newly created Kubernetes namespace: + ``` + kubectl get all -n backstage-development + ``` + You should see + - a `deployment`, `replicaset`, running `pod`, and `service` for Backstage + - a `statefulset`, running `pod`, and `service` for PostgreSQL database used by Backstage. + + Note: it may take up to ten minutes after the `terraform apply` completed until you actually see those resources. The Backstage application needs to built and deployed via a GitHub action out of the newly created repository in your GitHub organization. + + +## Cleaning up + +Once you are finished with the reference architecture, you can remove all provisioned infrastrcuture and the resource definitions created in Humanitec with the following: + +1. Delete all Humanitec applications scaffolded using Backstage, but not the `backstage` app itself. + +2. Follow the [base reference architecture cleanup instructions](../../README.md#cleaning-up). + +## Terraform docs + + +### Requirements + +| Name | Version | +|------|---------| +| terraform | >= 1.3.0 | +| aws | ~> 5.17 | +| github | ~> 5.38 | +| humanitec | ~> 0.13 | + +### Providers + +| Name | Version | +|------|---------| +| aws | ~> 5.17 | +| github | ~> 5.38 | +| humanitec | ~> 0.13 | + +### Modules + +| Name | Source | Version | +|------|--------|---------| +| backstage\_ecr | terraform-aws-modules/ecr/aws | ~> 1.6 | +| backstage\_iam\_policy\_ecr\_create\_repository | git::https://github.com/humanitec-architecture/resource-packs-aws.git//humanitec-resource-defs/iam-policy/ecr-create-repository | n/a | +| backstage\_iam\_role\_service\_account | git::https://github.com/humanitec-architecture/resource-packs-aws.git//humanitec-resource-defs/iam-role/service-account | n/a | +| backstage\_k8s\_service\_account | git::https://github.com/humanitec-architecture/resource-packs-aws.git//humanitec-resource-defs/k8s/service-account | n/a | +| backstage\_mysql | git::https://github.com/humanitec-architecture/resource-packs-in-cluster.git//humanitec-resource-defs/mysql/basic | n/a | +| backstage\_postgres | git::https://github.com/humanitec-architecture/resource-packs-in-cluster.git//humanitec-resource-defs/postgres/basic | n/a | +| backstage\_workload | git::https://github.com/humanitec-architecture/resource-packs-aws.git//humanitec-resource-defs/workload/service-account | n/a | +| base | ../../modules/base | n/a | +| iam\_github\_oidc\_provider | terraform-aws-modules/iam/aws//modules/iam-github-oidc-provider | ~> 5.30 | +| iam\_github\_oidc\_role | terraform-aws-modules/iam/aws//modules/iam-github-oidc-role | ~> 5.30 | + +### Resources + +| Name | Type | +|------|------| +| [aws_iam_policy.ecr_push_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [github_actions_organization_secret.backstage_humanitec_token](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_secret) | resource | +| [github_actions_organization_variable.backstage_aws_region](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | +| [github_actions_organization_variable.backstage_aws_role_arn](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | +| [github_actions_organization_variable.backstage_humanitec_org_id](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | +| [github_repository.backstage](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) | resource | +| [humanitec_application.backstage](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/application) | resource | +| [humanitec_resource_definition_criteria.backstage_iam_policy_ecr_create_repository](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | +| [humanitec_resource_definition_criteria.backstage_iam_role_service_account](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | +| [humanitec_resource_definition_criteria.backstage_k8s_service_account](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | +| [humanitec_resource_definition_criteria.backstage_mysql](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | +| [humanitec_resource_definition_criteria.backstage_postgres](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | +| [humanitec_resource_definition_criteria.backstage_workload](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | +| [humanitec_value.aws_default_region](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | +| [humanitec_value.backstage_github_app_client_id](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | +| [humanitec_value.backstage_github_app_client_secret](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | +| [humanitec_value.backstage_github_app_id](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | +| [humanitec_value.backstage_github_app_private_key](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | +| [humanitec_value.backstage_github_app_webhook_secret](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | +| [humanitec_value.backstage_github_org_id](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | +| [humanitec_value.backstage_humanitec_org](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | +| [humanitec_value.backstage_humanitec_token](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| aws\_account\_id | AWS Account (ID) to use | `string` | n/a | yes | +| aws\_region | AWS region | `string` | n/a | yes | +| github\_org\_id | GitHub org id | `string` | n/a | yes | +| humanitec\_ci\_service\_user\_token | Humanitec CI Service User Token | `string` | n/a | yes | +| humanitec\_org\_id | Humanitec Organization ID | `string` | n/a | yes | +| resource\_packs\_aws\_rev | Revision of the resource-packs-aws repository to use | `string` | `"refs/heads/main"` | no | + diff --git a/examples/with-backstage/aws-github.tf b/examples/with-backstage/aws-github.tf new file mode 100644 index 0000000..bf6f6f1 --- /dev/null +++ b/examples/with-backstage/aws-github.tf @@ -0,0 +1,51 @@ +locals { + name = "gha-ecr-push" +} + +# Create a role for GitHub Actions to push to ECR using OpenID Connect (OIDC) so we don't need to store AWS credentials in GitHub +# Reference https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services + +# Source https://github.com/terraform-aws-modules/terraform-aws-iam +module "iam_github_oidc_provider" { + source = "terraform-aws-modules/iam/aws//modules/iam-github-oidc-provider" + version = "~> 5.30" +} + +module "iam_github_oidc_role" { + source = "terraform-aws-modules/iam/aws//modules/iam-github-oidc-role" + version = "~> 5.30" + + name = local.name + + subjects = [ + "${var.github_org_id}/*", + ] + + policies = { + ecr_push_policy = aws_iam_policy.ecr_push_policy.arn + } +} + +# Reference https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-push.html#image-push-iam +resource "aws_iam_policy" "ecr_push_policy" { + name = local.name + description = "GitHub Actions ECR Push Policy" + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = [ + "ecr:CompleteLayerUpload", + "ecr:GetAuthorizationToken", + "ecr:UploadLayerPart", + "ecr:InitiateLayerUpload", + "ecr:BatchCheckLayerAvailability", + "ecr:PutImage" + ] + Effect = "Allow" + Resource = "*" + }, + ] + }) +} diff --git a/examples/with-backstage/backstage-aws.tf b/examples/with-backstage/backstage-aws.tf new file mode 100644 index 0000000..c0b157c --- /dev/null +++ b/examples/with-backstage/backstage-aws.tf @@ -0,0 +1,14 @@ + +# Create ECR repository for the backstage image +# Source https://github.com/terraform-aws-modules/terraform-aws-ecr +module "backstage_ecr" { + source = "terraform-aws-modules/ecr/aws" + version = "~> 1.6" + + repository_name = "backstage" + repository_image_scan_on_push = false + repository_image_tag_mutability = "MUTABLE" + create_lifecycle_policy = false + + repository_force_delete = true +} diff --git a/examples/with-backstage/backstage-github.tf b/examples/with-backstage/backstage-github.tf new file mode 100644 index 0000000..8e10ea0 --- /dev/null +++ b/examples/with-backstage/backstage-github.tf @@ -0,0 +1,62 @@ +# Configure GitHub variables & secrets for Backstage itself and for all scaffolded apps + +locals { + github_app_credentials_file = "github-app-credentials.json" + github_app_credentials = jsondecode(file("${path.module}/${local.github_app_credentials_file}")) + github_app_id = local.github_app_credentials["appId"] + github_app_client_id = local.github_app_credentials["clientId"] + github_app_client_secret = local.github_app_credentials["clientSecret"] + github_app_private_key = local.github_app_credentials["privateKey"] + github_webhook_secret = local.github_app_credentials["webhookSecret"] +} + +locals { + backstage_repo = "backstage" +} + +resource "github_actions_organization_variable" "backstage_aws_region" { + variable_name = "AWS_REGION" + visibility = "all" + value = var.aws_region +} + +resource "github_actions_organization_variable" "backstage_aws_role_arn" { + variable_name = "AWS_ROLE_ARN" + visibility = "all" + value = module.iam_github_oidc_role.arn +} + +resource "github_actions_organization_variable" "backstage_humanitec_org_id" { + variable_name = "HUMANITEC_ORG_ID" + visibility = "all" + value = var.humanitec_org_id +} + +resource "github_actions_organization_secret" "backstage_humanitec_token" { + secret_name = "HUMANITEC_TOKEN" + visibility = "all" + plaintext_value = var.humanitec_ci_service_user_token +} + +# Backstage repository itself + +resource "github_repository" "backstage" { + name = local.backstage_repo + description = "Backstage" + + visibility = "public" + + template { + owner = "humanitec-architecture" + repository = "backstage" + } + + depends_on = [ + module.base, + module.backstage_ecr, + module.iam_github_oidc_role, + humanitec_application.backstage, + humanitec_resource_definition_criteria.backstage_postgres, + github_actions_organization_secret.backstage_humanitec_token, + ] +} diff --git a/examples/with-backstage/backstage-humanitec.tf b/examples/with-backstage/backstage-humanitec.tf new file mode 100644 index 0000000..1172370 --- /dev/null +++ b/examples/with-backstage/backstage-humanitec.tf @@ -0,0 +1,191 @@ +resource "humanitec_application" "backstage" { + id = "backstage" + name = "backstage" +} + +# Configure required values for backstage + +resource "humanitec_value" "backstage_github_org_id" { + app_id = humanitec_application.backstage.id + key = "GITHUB_ORG_ID" + description = "" + value = var.github_org_id + is_secret = false +} + +resource "humanitec_value" "backstage_github_app_id" { + app_id = humanitec_application.backstage.id + key = "GITHUB_APP_ID" + description = "" + value = local.github_app_id + is_secret = false +} + +resource "humanitec_value" "backstage_github_app_client_id" { + app_id = humanitec_application.backstage.id + key = "GITHUB_APP_CLIENT_ID" + description = "" + value = local.github_app_client_id + is_secret = true +} + +resource "humanitec_value" "backstage_github_app_client_secret" { + app_id = humanitec_application.backstage.id + key = "GITHUB_APP_CLIENT_SECRET" + description = "" + value = local.github_app_client_secret + is_secret = true +} + +resource "humanitec_value" "backstage_github_app_private_key" { + app_id = humanitec_application.backstage.id + key = "GITHUB_APP_PRIVATE_KEY" + description = "" + value = indent(2, local.github_app_private_key) + is_secret = true +} + +resource "humanitec_value" "backstage_github_app_webhook_secret" { + app_id = humanitec_application.backstage.id + key = "GITHUB_APP_WEBHOOK_SECRET" + description = "" + value = local.github_webhook_secret + is_secret = true +} + +resource "humanitec_value" "backstage_humanitec_org" { + app_id = humanitec_application.backstage.id + key = "HUMANITEC_ORG_ID" + description = "" + value = var.humanitec_org_id + is_secret = false +} + +resource "humanitec_value" "backstage_humanitec_token" { + app_id = humanitec_application.backstage.id + key = "HUMANITEC_TOKEN" + description = "" + value = var.humanitec_ci_service_user_token + is_secret = true +} + +resource "humanitec_value" "aws_default_region" { + app_id = humanitec_application.backstage.id + key = "AWS_DEFAULT_REGION" + description = "" + value = var.aws_region + is_secret = false +} + +# Configure required resources for backstage + +locals { + res_def_prefix = "backstage-" +} + +# in-cluster postgres + +module "backstage_postgres" { + source = "git::https://github.com/humanitec-architecture/resource-packs-in-cluster.git//humanitec-resource-defs/postgres/basic" + + prefix = local.res_def_prefix +} + +resource "humanitec_resource_definition_criteria" "backstage_postgres" { + resource_definition_id = module.backstage_postgres.id + app_id = humanitec_application.backstage.id + + force_delete = true +} + +# k8s service account (to assume an AWS role) + +module "backstage_k8s_service_account" { + source = "git::https://github.com/humanitec-architecture/resource-packs-aws.git//humanitec-resource-defs/k8s/service-account" + + prefix = local.res_def_prefix +} + +resource "humanitec_resource_definition_criteria" "backstage_k8s_service_account" { + resource_definition_id = module.backstage_k8s_service_account.id + app_id = humanitec_application.backstage.id + + force_delete = true +} + +# AWS policy to create ECR repositories (required to scaffold apps) + +module "backstage_iam_policy_ecr_create_repository" { + source = "git::https://github.com/humanitec-architecture/resource-packs-aws.git//humanitec-resource-defs/iam-policy/ecr-create-repository" + + access_key = module.base.aws_access_key_id + secret_key = module.base.aws_secret_access_key + resource_packs_aws_rev = var.resource_packs_aws_rev + humanitec_organization = var.humanitec_org_id + region = var.aws_region + + prefix = local.res_def_prefix +} + +resource "humanitec_resource_definition_criteria" "backstage_iam_policy_ecr_create_repository" { + resource_definition_id = module.backstage_iam_policy_ecr_create_repository.id + app_id = humanitec_application.backstage.id + + force_delete = true +} + +# AWS role assumable by the k8s service account + +module "backstage_iam_role_service_account" { + source = "git::https://github.com/humanitec-architecture/resource-packs-aws.git//humanitec-resource-defs/iam-role/service-account" + + access_key = module.base.aws_access_key_id + secret_key = module.base.aws_secret_access_key + resource_packs_aws_rev = var.resource_packs_aws_rev + humanitec_organization = var.humanitec_org_id + region = var.aws_region + + policy_classes = ["default"] + + oidc_provider = module.base.eks_oidc_provider + oidc_provider_arn = module.base.eks_oidc_provider_arn + prefix = local.res_def_prefix +} + +resource "humanitec_resource_definition_criteria" "backstage_iam_role_service_account" { + resource_definition_id = module.backstage_iam_role_service_account.id + app_id = humanitec_application.backstage.id + + force_delete = true +} + +# Workload resource that sets the service account + +module "backstage_workload" { + source = "git::https://github.com/humanitec-architecture/resource-packs-aws.git//humanitec-resource-defs/workload/service-account" + + prefix = local.res_def_prefix +} + +resource "humanitec_resource_definition_criteria" "backstage_workload" { + resource_definition_id = module.backstage_workload.id + app_id = humanitec_application.backstage.id + + force_delete = true +} + + +# Configure required resources for scaffolded apps + +# in-cluster mysql + +module "backstage_mysql" { + source = "git::https://github.com/humanitec-architecture/resource-packs-in-cluster.git//humanitec-resource-defs/mysql/basic" + + prefix = local.res_def_prefix +} + +resource "humanitec_resource_definition_criteria" "backstage_mysql" { + resource_definition_id = module.backstage_mysql.id + env_type = module.base.environment +} diff --git a/examples/with-backstage/create-gh-app/index.js b/examples/with-backstage/create-gh-app/index.js new file mode 100644 index 0000000..9f264d6 --- /dev/null +++ b/examples/with-backstage/create-gh-app/index.js @@ -0,0 +1,153 @@ +// Small CLI tool to create a GitHub App for Backstage +// +// Heavily inspired by https://github.com/backstage/backstage/blob/master/packages/cli/src/commands/create-github-app/ + +const http = require('http'); +const crypto = require('crypto'); +const fs = require('fs/promises') + +const hostname = '127.0.0.1'; +const port = 3000; + +const FORM_PAGE = ` + + +
+ + +
+ + + +`; + + +let baseUrl; + + +const webhookId = crypto +.randomBytes(15) +.toString('base64') +.replace(/[\+\/]/g, ''); + +const webhookUrl = `https://smee.io/${webhookId}`; + +const handleIndex = (req, res, GITHUB_ORG_ID) => { + const encodedOrg = encodeURIComponent(GITHUB_ORG_ID); + const actionUrl = `https://github.com/organizations/${encodedOrg}/settings/apps/new`; + + + res.statusCode = 200; + const manifest = { + default_events: ['create', 'delete', 'push', 'repository'], + default_permissions: { + members: 'read', + administration: 'write', + contents: 'write', + metadata: 'read', + pull_requests: 'write', + issues: 'write', + workflows: 'write', + checks: 'read', + actions_variables: 'write', + secrets: 'write', + environments: 'write', + }, + name: `backstage-${GITHUB_ORG_ID}`, + url: 'https://backstage.io', + description: 'GitHub App for Backstage', + public: false, + redirect_url: `${baseUrl}/callback`, + hook_attributes: { + url: webhookUrl, + active: false, + }, + }; + + const manifestJson = JSON.stringify(manifest).replace(/\"/g, '"'); + + let body = FORM_PAGE; + body = body.replace('MANIFEST_JSON', manifestJson); + body = body.replace('ACTION_URL', actionUrl); + + res.setHeader('content-type', 'text/html'); + res.end(body); +} + + +const writeConfigFile = async (data, webhookUrl) => { + const fileName = `github-app-credentials.json`; + const content = JSON.stringify({ + name: data.name, + slug: data.slug, + appId: data.id, + webhookUrl: webhookUrl, + clientId: data.client_id, + clientSecret: data.client_secret, + webhookSecret: data.webhook_secret, + privateKey: data.pem, + }, null, 2) + + await fs.writeFile(fileName, content); +} + +const handleCallback = async (req, res) => { + const url = new URL(req.url, `http://${req.headers.host}`); + const conversionRes = await fetch(`https://api.github.com/app-manifests/${encodeURIComponent(url.searchParams.get('code'))}/conversions`, { + method: 'POST', + }); + + if (conversionRes.status !== 201) { + const body = await conversionRes.text(); + res.statusCode = conversionRes.status; + res.end(body); + } + + const data = await conversionRes.json(); + + await writeConfigFile(data, webhookUrl); + + console.log(`Created ${fileName}, you can close the server now.`) + + res.writeHead(302, { Location: `${data.html_url}/installations/new` }); + res.end(); +} + +if (process.env.STUB_FILE === '1') { + writeConfigFile({ + name: 'stub', + slug: 'stub', + id: 'stub', + client_id: 'stub', + client_secret: 'stub', + webhook_secret: 'stub', + pem: 'stub', + }, 'https://smee.io/stub'); + + return; +} + +const GITHUB_ORG_ID = process.env.GITHUB_ORG_ID; +if (!GITHUB_ORG_ID) { + console.error('Please export GITHUB_ORG_ID'); + process.exit(1); +} + +const server = http.createServer((req, res) => { + if (req.url === '/') { + handleIndex(req, res, GITHUB_ORG_ID); + } else if (req.url.startsWith('/callback?')) { + handleCallback(req, res); + } else { + res.statusCode = 404; + res.end('Not found, url: ' + req.url); + } +}); + +server.listen(port, hostname, () => { + baseUrl = `http://${hostname}:${port}`; + + console.log(`Open ${baseUrl}`); +}); diff --git a/examples/with-backstage/main.tf b/examples/with-backstage/main.tf new file mode 100644 index 0000000..fc5e4b2 --- /dev/null +++ b/examples/with-backstage/main.tf @@ -0,0 +1,33 @@ +# AWS reference architecture + +module "base" { + source = "../../modules/base" + + region = var.aws_region +} + +provider "kubernetes" { + host = module.base.eks_cluster_endpoint + cluster_ca_certificate = base64decode(module.base.eks_cluster_certificate_authority_data) + + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "aws" + # This requires the awscli to be installed locally where Terraform is executed + args = ["eks", "get-token", "--cluster-name", module.base.eks_cluster_name] + } +} + +provider "helm" { + kubernetes { + host = module.base.eks_cluster_endpoint + cluster_ca_certificate = base64decode(module.base.eks_cluster_certificate_authority_data) + + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "aws" + # This requires the awscli to be installed locally where Terraform is executed + args = ["eks", "get-token", "--cluster-name", module.base.eks_cluster_name] + } + } +} diff --git a/examples/with-backstage/provider.tf b/examples/with-backstage/provider.tf new file mode 100644 index 0000000..1cab49e --- /dev/null +++ b/examples/with-backstage/provider.tf @@ -0,0 +1,30 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.17" + } + humanitec = { + source = "humanitec/humanitec" + version = "~> 0.13" + } + github = { + source = "integrations/github" + version = "~> 5.38" + } + } + required_version = ">= 1.3.0" +} + +provider "humanitec" { + org_id = var.humanitec_org_id +} + +provider "github" { + owner = var.github_org_id +} + +provider "aws" { + region = var.aws_region + allowed_account_ids = [var.aws_account_id] +} diff --git a/examples/with-backstage/terraform.tfvars.example b/examples/with-backstage/terraform.tfvars.example new file mode 100644 index 0000000..4c407d3 --- /dev/null +++ b/examples/with-backstage/terraform.tfvars.example @@ -0,0 +1,18 @@ + +# AWS Account (ID) to use +aws_account_id = "" + +# AWS region +aws_region = "" + +# GitHub org id +github_org_id = "" + +# Humanitec CI Service User Token +humanitec_ci_service_user_token = "" + +# Humanitec Organization ID +humanitec_org_id = "" + +# Revision of the resource-packs-aws repository to use +resource_packs_aws_rev = "refs/heads/main" \ No newline at end of file diff --git a/examples/with-backstage/variables.tf b/examples/with-backstage/variables.tf new file mode 100644 index 0000000..dd71328 --- /dev/null +++ b/examples/with-backstage/variables.tf @@ -0,0 +1,31 @@ +variable "aws_account_id" { + description = "AWS Account (ID) to use" + type = string +} + +variable "aws_region" { + description = "AWS region" + type = string +} + +variable "github_org_id" { + description = "GitHub org id" + type = string +} + +variable "humanitec_org_id" { + description = "Humanitec Organization ID" + type = string +} + +variable "humanitec_ci_service_user_token" { + description = "Humanitec CI Service User Token" + type = string + sensitive = true +} + +variable "resource_packs_aws_rev" { + description = "Revision of the resource-packs-aws repository to use" + type = string + default = "refs/heads/main" +} diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..d37a2f5 --- /dev/null +++ b/main.tf @@ -0,0 +1,56 @@ + +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.17" + } + humanitec = { + source = "humanitec/humanitec" + version = "~> 0.13" + } + } + required_version = ">= 1.3.0" +} + +provider "humanitec" { + org_id = var.humanitec_org_id +} + +provider "aws" { + region = var.aws_region + allowed_account_ids = [var.aws_account_id] +} + + +module "base" { + source = "./modules/base" + + region = var.aws_region +} + +provider "kubernetes" { + host = module.base.eks_cluster_endpoint + cluster_ca_certificate = base64decode(module.base.eks_cluster_certificate_authority_data) + + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "aws" + # This requires the awscli to be installed locally where Terraform is executed + args = ["eks", "get-token", "--cluster-name", module.base.eks_cluster_name] + } +} + +provider "helm" { + kubernetes { + host = module.base.eks_cluster_endpoint + cluster_ca_certificate = base64decode(module.base.eks_cluster_certificate_authority_data) + + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "aws" + # This requires the awscli to be installed locally where Terraform is executed + args = ["eks", "get-token", "--cluster-name", module.base.eks_cluster_name] + } + } +} diff --git a/modules/base/.terraform-docs.yaml b/modules/base/.terraform-docs.yaml new file mode 100644 index 0000000..844071f --- /dev/null +++ b/modules/base/.terraform-docs.yaml @@ -0,0 +1,11 @@ +formatter: "markdown table" + +output: + file: "./README.md" + +sort: + enabled: true + by: required + +settings: + hide-empty: true diff --git a/modules/base/README.md b/modules/base/README.md new file mode 100644 index 0000000..59df3b0 --- /dev/null +++ b/modules/base/README.md @@ -0,0 +1,83 @@ +# base + +Module that provides the reference architecture. + + +## Requirements + +| Name | Version | +|------|---------| +|
[terraform](#requirement\_terraform) | >= 1.3.0 | +| [aws](#requirement\_aws) | >= 4.50 | +| [kubernetes](#requirement\_kubernetes) | >= 2.0.3 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.50 | +| [helm](#provider\_helm) | n/a | +| [humanitec](#provider\_humanitec) | n/a | +| [kubernetes](#provider\_kubernetes) | >= 2.0.3 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [aws\_eks](#module\_aws\_eks) | terraform-aws-modules/eks/aws | ~> 19.16 | +| [aws\_vpc](#module\_aws\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.1 | +| [ebs\_csi\_irsa\_role](#module\_ebs\_csi\_irsa\_role) | terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks | ~> 5.30 | + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_access_key.humanitec_svc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_access_key) | resource | +| [aws_iam_user.humanitec_svc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user) | resource | +| [aws_iam_user_policy_attachment.humanitec_svc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user_policy_attachment) | resource | +| [helm_release.ingress_nginx](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | +| [humanitec_resource_definition.k8s_cluster_driver](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition) | resource | +| [humanitec_resource_definition.k8s_logging](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition) | resource | +| [humanitec_resource_definition.k8s_namespace](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition) | resource | +| [humanitec_resource_definition_criteria.k8s_cluster_driver](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | +| [humanitec_resource_definition_criteria.k8s_logging](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | +| [humanitec_resource_definition_criteria.k8s_namespace](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | +| [kubernetes_service.ingress_nginx_controller](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/data-sources/service) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [additional\_aws\_auth\_users](#input\_additional\_aws\_auth\_users) | Additional users add to the k8s aws-auth configmap | `list(any)` | `[]` | no | +| [capacity\_type](#input\_capacity\_type) | Defines whether to use ON\_DEMAND or SPOT EC2 instances for EKS nodes | `string` | `"ON_DEMAND"` | no | +| [cluster\_name](#input\_cluster\_name) | Name for the EKS cluster | `string` | `"ref-arch"` | no | +| [cluster\_version](#input\_cluster\_version) | Version of the EKS cluster to deploy | `string` | `null` | no | +| [eks\_public\_access\_cidrs](#input\_eks\_public\_access\_cidrs) | List of CIDRs that can access the EKS cluster's public endpoint | `list(string)` |
[
"0.0.0.0/0"
]
| no | +| [environment](#input\_environment) | Name of the environment to be deployed into | `string` | `"development"` | no | +| [iam\_user\_name](#input\_iam\_user\_name) | Name of the IAM user to create for Humanitec EKS access | `string` | `"svc-humanitec"` | no | +| [ingress\_nginx\_min\_unavailable](#input\_ingress\_nginx\_min\_unavailable) | Number of allowed unavaiable replicas for the ingress-nginx controller | `number` | `1` | no | +| [ingress\_nginx\_replica\_count](#input\_ingress\_nginx\_replica\_count) | Number of replicas for the ingress-nginx controller | `number` | `2` | no | +| [instance\_types](#input\_instance\_types) | List of EC2 instances types to use for EKS nodes | `list(string)` |
[
"t3.large"
]
| no | +| [node\_group\_desired\_size](#input\_node\_group\_desired\_size) | Desired number of nodes for the EKS node group | `number` | `3` | no | +| [node\_group\_max\_size](#input\_node\_group\_max\_size) | Maximum number of nodes for the EKS node group | `number` | `3` | no | +| [node\_group\_min\_size](#input\_node\_group\_min\_size) | Minimum number of nodes for the EKS node group | `number` | `2` | no | +| [region](#input\_region) | AWS Region to deploy into | `string` | `"us-east-1"` | no | +| [vpc\_name](#input\_vpc\_name) | AWS VPC name | `string` | `"ref-arch"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [aws\_access\_key\_id](#output\_aws\_access\_key\_id) | n/a | +| [aws\_secret\_access\_key](#output\_aws\_secret\_access\_key) | n/a | +| [eks\_cluster\_certificate\_authority\_data](#output\_eks\_cluster\_certificate\_authority\_data) | Base64 encoded certificate data required to communicate with the cluster | +| [eks\_cluster\_endpoint](#output\_eks\_cluster\_endpoint) | Endpoint for your Kubernetes API server | +| [eks\_cluster\_name](#output\_eks\_cluster\_name) | The name of the EKS cluster | +| [eks\_oidc\_provider](#output\_eks\_oidc\_provider) | The OpenID Connect identity provider (issuer URL without leading `https://`) | +| [eks\_oidc\_provider\_arn](#output\_eks\_oidc\_provider\_arn) | The ARN of the OIDC Provider | +| [environment](#output\_environment) | Name of the environment to be deployed into | +| [ingress\_nginx\_external\_dns](#output\_ingress\_nginx\_external\_dns) | External DNS entry for the Nginx ingress controller | +| [vpc\_id](#output\_vpc\_id) | VPC id | + diff --git a/modules/base/humanitec.tf b/modules/base/humanitec.tf new file mode 100644 index 0000000..e8ba08f --- /dev/null +++ b/modules/base/humanitec.tf @@ -0,0 +1,63 @@ +# Humanitec resource definition to connect the cluster to Humanitec + +locals { + ingress_address = data.kubernetes_service.ingress_nginx_controller.status.0.load_balancer.0.ingress.0.hostname +} + +resource "humanitec_resource_definition" "k8s_cluster_driver" { + driver_type = "humanitec/k8s-cluster-eks" + id = var.cluster_name + name = var.cluster_name + type = "k8s-cluster" + + driver_inputs = { + values_string = jsonencode({ + "name" = module.aws_eks.cluster_name + "loadbalancer" = local.ingress_address + "region" = var.region + }), + secrets_string = jsonencode({ + "credentials" = { + "aws_access_key_id" = aws_iam_access_key.humanitec_svc.id + "aws_secret_access_key" = aws_iam_access_key.humanitec_svc.secret + } + }) + } +} + +resource "humanitec_resource_definition_criteria" "k8s_cluster_driver" { + resource_definition_id = humanitec_resource_definition.k8s_cluster_driver.id + env_type = var.environment +} + + +resource "humanitec_resource_definition" "k8s_logging" { + driver_type = "humanitec/logging-k8s" + id = "default-logging" + name = "default-logging" + type = "logging" + + driver_inputs = {} +} + +resource "humanitec_resource_definition_criteria" "k8s_logging" { + resource_definition_id = humanitec_resource_definition.k8s_logging.id +} + + +resource "humanitec_resource_definition" "k8s_namespace" { + driver_type = "humanitec/static" + id = "default-namespace" + name = "default-namespace" + type = "k8s-namespace" + + driver_inputs = { + values_string = jsonencode({ + "namespace" = "$${context.app.id}-$${context.env.id}" + }) + } +} + +resource "humanitec_resource_definition_criteria" "k8s_namespace" { + resource_definition_id = humanitec_resource_definition.k8s_namespace.id +} diff --git a/modules/base/main.tf b/modules/base/main.tf new file mode 100644 index 0000000..706a68e --- /dev/null +++ b/modules/base/main.tf @@ -0,0 +1,158 @@ +locals { + admin_policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess" + tags = { + Terraform = "true" + Environment = var.environment + } +} + +# User for Humanitec to access the EKS cluster + +resource "aws_iam_user" "humanitec_svc" { + name = var.iam_user_name +} + +resource "aws_iam_user_policy_attachment" "humanitec_svc" { + user = aws_iam_user.humanitec_svc.name + policy_arn = local.admin_policy_arn +} + +resource "aws_iam_access_key" "humanitec_svc" { + user = aws_iam_user.humanitec_svc.name + + # Ensure that the policy is not deleted before the access key + depends_on = [aws_iam_user_policy_attachment.humanitec_svc] +} + +# VPC and EKS cluster + +data "aws_region" "current" {} + +module "aws_vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 5.1" + + name = var.vpc_name + cidr = "10.0.0.0/16" + + azs = formatlist("${data.aws_region.current.name}%s", ["a", "b", "c"]) + private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] + public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] + + enable_nat_gateway = true + + tags = local.tags +} + +data "aws_caller_identity" "current" {} + +locals { + default_aws_auth_users = [ + { + userarn = data.aws_caller_identity.current.arn + username = "creator" + groups = ["system:masters"] + }, + { + userarn = aws_iam_user.humanitec_svc.arn + username = aws_iam_user.humanitec_svc.name + groups = ["system:masters"] + } + ] + aws_auth_users = concat(local.default_aws_auth_users, var.additional_aws_auth_users) +} + +module "ebs_csi_irsa_role" { + source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + version = "~> 5.30" + + role_name = "ebs-csi" + attach_ebs_csi_policy = true + + oidc_providers = { + ex = { + provider_arn = module.aws_eks.oidc_provider_arn + namespace_service_accounts = ["kube-system:ebs-csi-controller-sa"] + } + } + + tags = local.tags +} + +module "aws_eks" { + source = "terraform-aws-modules/eks/aws" + version = "~> 19.16" + + cluster_name = var.cluster_name + cluster_version = var.cluster_version + + cluster_endpoint_public_access = true + cluster_endpoint_public_access_cidrs = var.eks_public_access_cidrs + + vpc_id = module.aws_vpc.vpc_id + subnet_ids = module.aws_vpc.private_subnets + + eks_managed_node_groups = { + green = { + min_size = var.node_group_min_size + max_size = var.node_group_max_size + desired_size = var.node_group_desired_size + + instance_types = var.instance_types + capacity_type = var.capacity_type + } + } + + cluster_addons = { + aws-ebs-csi-driver = { + most_recent = true + service_account_role_arn = module.ebs_csi_irsa_role.iam_role_arn + } + } + + manage_aws_auth_configmap = true + aws_auth_users = local.aws_auth_users + + # required for ingress-nginx see https://github.com/terraform-aws-modules/terraform-aws-eks/issues/2513 + node_security_group_additional_rules = { + ingress_self_all = { + description = "Node to node all ports/protocols" + protocol = "-1" + from_port = 0 + to_port = 0 + type = "ingress" + self = true + } + } + + tags = local.tags +} + + +# Ingress controller + +resource "helm_release" "ingress_nginx" { + name = "ingress-nginx" + namespace = "ingress-nginx" + create_namespace = true + repository = "https://kubernetes.github.io/ingress-nginx" + + chart = "ingress-nginx" + version = "4.5.0" + wait = true + timeout = 600 + + set { + type = "string" + name = "controller.replicaCount" + value = var.ingress_nginx_replica_count + } + + set { + type = "string" + name = "controller.minAvailable" + value = var.ingress_nginx_min_unavailable + } + + depends_on = [module.aws_eks.eks_managed_node_groups] +} diff --git a/modules/base/meta.tf b/modules/base/meta.tf new file mode 100644 index 0000000..fbfc111 --- /dev/null +++ b/modules/base/meta.tf @@ -0,0 +1,7 @@ +data "kubernetes_service" "ingress_nginx_controller" { + metadata { + name = "ingress-nginx-controller" + namespace = "ingress-nginx" + } + depends_on = [helm_release.ingress_nginx] +} diff --git a/modules/base/outputs.tf b/modules/base/outputs.tf new file mode 100644 index 0000000..7b99cb8 --- /dev/null +++ b/modules/base/outputs.tf @@ -0,0 +1,58 @@ +# General outputs + +output "environment" { + description = "Name of the environment to be deployed into" + value = var.environment +} + +# VPC outputs + +output "vpc_id" { + description = "VPC id" + value = module.aws_vpc.vpc_id +} + +# EKS outputs + +output "eks_oidc_provider" { + description = "The OpenID Connect identity provider (issuer URL without leading `https://`)" + value = module.aws_eks.oidc_provider +} + +output "eks_oidc_provider_arn" { + description = "The ARN of the OIDC Provider" + value = module.aws_eks.oidc_provider_arn +} + +output "eks_cluster_endpoint" { + description = "Endpoint for your Kubernetes API server" + value = module.aws_eks.cluster_endpoint +} + +output "eks_cluster_certificate_authority_data" { + description = "Base64 encoded certificate data required to communicate with the cluster" + value = module.aws_eks.cluster_certificate_authority_data +} + +output "eks_cluster_name" { + description = "The name of the EKS cluster" + value = module.aws_eks.cluster_name +} + +# Ingress outputs + +output "ingress_nginx_external_dns" { + description = "External DNS entry for the Nginx ingress controller" + value = local.ingress_address +} + + +# Key + +output "aws_access_key_id" { + value = aws_iam_access_key.humanitec_svc.id +} + +output "aws_secret_access_key" { + value = aws_iam_access_key.humanitec_svc.secret +} diff --git a/modules/base/providers.tf b/modules/base/providers.tf new file mode 100644 index 0000000..76fb784 --- /dev/null +++ b/modules/base/providers.tf @@ -0,0 +1,19 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.50" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = ">= 2.0.3" + } + helm = { + source = "hashicorp/helm" + } + humanitec = { + source = "humanitec/humanitec" + } + } + required_version = ">= 1.3.0" +} diff --git a/modules/base/variables.tf b/modules/base/variables.tf new file mode 100644 index 0000000..3bf079b --- /dev/null +++ b/modules/base/variables.tf @@ -0,0 +1,91 @@ +variable "eks_public_access_cidrs" { + description = "List of CIDRs that can access the EKS cluster's public endpoint" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "region" { + description = "AWS Region to deploy into" + type = string + default = "us-east-1" +} + +variable "vpc_name" { + description = "AWS VPC name" + type = string + default = "ref-arch" +} + +variable "environment" { + description = "Name of the environment to be deployed into" + type = string + default = "development" +} + +variable "cluster_name" { + description = "Name for the EKS cluster" + type = string + default = "ref-arch" +} + +variable "cluster_version" { + description = "Version of the EKS cluster to deploy" + type = string + default = null +} + +variable "node_group_min_size" { + description = "Minimum number of nodes for the EKS node group" + type = number + default = 2 +} + +variable "node_group_max_size" { + description = "Maximum number of nodes for the EKS node group" + type = number + default = 3 +} + +variable "node_group_desired_size" { + description = "Desired number of nodes for the EKS node group" + type = number + default = 3 +} + +variable "instance_types" { + description = "List of EC2 instances types to use for EKS nodes" + type = list(string) + default = [ + "t3.large" + ] +} + +variable "capacity_type" { + description = "Defines whether to use ON_DEMAND or SPOT EC2 instances for EKS nodes" + type = string + default = "ON_DEMAND" +} + +variable "iam_user_name" { + description = "Name of the IAM user to create for Humanitec EKS access" + type = string + default = "svc-humanitec" +} + +variable "additional_aws_auth_users" { + description = "Additional users add to the k8s aws-auth configmap" + type = list(any) + default = [] +} + +variable "ingress_nginx_replica_count" { + description = "Number of replicas for the ingress-nginx controller" + type = number + default = 2 +} + +variable "ingress_nginx_min_unavailable" { + description = "Number of allowed unavaiable replicas for the ingress-nginx controller" + type = number + default = 1 +} diff --git a/terraform.tfvars.example b/terraform.tfvars.example new file mode 100644 index 0000000..46fe5c1 --- /dev/null +++ b/terraform.tfvars.example @@ -0,0 +1,9 @@ + +# AWS Account (ID) to use +aws_account_id = "" + +# AWS Region to deploy into +aws_region = "" + +# Humanitec Organization ID +humanitec_org_id = "" \ No newline at end of file diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..2dd9f8c --- /dev/null +++ b/variables.tf @@ -0,0 +1,15 @@ + +variable "aws_region" { + description = "AWS Region to deploy into" + type = string +} + +variable "aws_account_id" { + description = "AWS Account (ID) to use" + type = string +} + +variable "humanitec_org_id" { + description = "Humanitec Organization ID" + type = string +}