├── .copywrite.hcl ├── .github ├── CODEOWNERS ├── dependabot.yml ├── pull_request_template.md └── workflows │ ├── nightly-ecs-examples-validator.yml │ ├── reusable-ecs-acceptance.yml │ ├── reusable-ecs-example-validator.yml │ ├── reusable-get-go-version.yml │ ├── reusable-go-fmt-and-lint.yml │ ├── reusable-terraform-fmt.yml │ ├── scenario-validator.yml │ └── terraform-ci.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── _docs ├── ap-example.png ├── api-gateway-arch.png ├── api-gateway-client-ui.png ├── api-gateway-dc1.png ├── architecture.png ├── consul-ui.png ├── dev-server-ec2.png ├── dev-server-fargate.png ├── ec2-transparent-proxy-ui.png ├── example-app.png ├── intentions.png ├── locality-aware-app-ui.png ├── locality-aware-dc1-failover-ui.png ├── locality-aware-dc1-ui.png ├── locality-aware-routing-arch.png ├── mesh-gateways.png ├── mgw-dc1-consul-ui.png ├── mgw-dc2-consul-ui.png ├── mgw-example-app.png ├── mgw-intentions.png ├── mgw-ui-after-intention.png ├── peering-arch.png ├── peering-dc1-ui.png ├── peering-dc2-ui.png ├── peering-established.png ├── peering-exported-service.png ├── peering-intention.png ├── peering-successful.png ├── sameness-arch.png ├── sameness-client-ui.png ├── sameness-dc1-part1-ui.png ├── sameness-dc1-ui.png ├── sameness-dc2-ui.png ├── sameness-demo-1.png ├── sameness-demo-2.png ├── sameness-demo-3.png ├── sameness-demo-4.png ├── sameness-demo-5.png ├── sameness-demo-6.png ├── sameness-exported-service-dc1.png ├── sameness-peering-dc2.png ├── terminating-gateway-arch.png ├── terminating-gateway-client-tproxy-ui.png ├── terminating-gateway-client-ui.png ├── terminating-gateway-dc1.png ├── terminating-gateway-external-server-tls.png └── ui-after-intention.png ├── examples ├── admin-partitions │ ├── README.md │ ├── ap-example │ └── terraform │ │ ├── aws_ecs.tf │ │ ├── client.tf │ │ ├── hcp_consul.tf │ │ ├── outputs.tf │ │ ├── server.tf │ │ └── variables.tf ├── api-gateway │ ├── README.md │ ├── consul-server.tf │ ├── controller.tf │ ├── datacenter │ │ ├── consul-server.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── echo-apps.tf │ ├── echo-service │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── ecs-cluster.tf │ ├── gateway.tf │ ├── load_balancer.tf │ ├── main.tf │ ├── outputs.tf │ ├── provider.tf │ ├── variables.tf │ └── vpc.tf ├── cluster-peering │ ├── README.md │ ├── client-app.tf │ ├── datacenter │ │ ├── consul-server.tf │ │ ├── ecs-cluster.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── datacenters.tf │ ├── gateway │ │ ├── gateway.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── gateways.tf │ ├── outputs.tf │ ├── provider.tf │ ├── server-app.tf │ ├── variables.tf │ └── vpc.tf ├── dev-server-ec2-transparent-proxy │ ├── README.md │ ├── bastion │ │ ├── bastion.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── consul-server.tf │ ├── controller.tf │ ├── datacenter │ │ ├── consul-server.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── ecs-cluster.tf │ ├── main.tf │ ├── outputs.tf │ ├── provider.tf │ ├── variables.tf │ └── vpc.tf ├── dev-server-ec2 │ ├── README.md │ ├── bastion │ │ ├── bastion.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── consul-server.tf │ ├── ecs-cluster.tf │ ├── main.tf │ ├── outputs.tf │ ├── variables.tf │ └── vpc.tf ├── dev-server-fargate │ ├── README.md │ ├── consul-server.tf │ ├── ecs-cluster.tf │ ├── main.tf │ ├── outputs.tf │ ├── variables.tf │ └── vpc.tf ├── locality-aware-routing │ ├── README.md │ ├── client-app.tf │ ├── cluster │ │ ├── ecs_cluster.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── clusters.tf │ ├── controller │ │ ├── controller.tf │ │ └── variables.tf │ ├── controllers.tf │ ├── datacenter.tf │ ├── datacenter │ │ ├── consul_server.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── outputs.tf │ ├── providers.tf │ ├── server-app │ │ ├── outputs.tf │ │ ├── server-app.tf │ │ └── variables.tf │ ├── server-apps.tf │ ├── variables.tf │ └── vpc.tf ├── mesh-gateways │ ├── README.md │ ├── client-app.tf │ ├── datacenter │ │ ├── consul-server.tf │ │ ├── ecs-cluster.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── datacenters.tf │ ├── gateway.tf │ ├── gateway │ │ ├── gateway.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── outputs.tf │ ├── provider.tf │ ├── server-app.tf │ ├── variables.tf │ └── vpc.tf ├── service-sameness │ ├── README.md │ ├── client-app │ │ ├── client.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── client-apps.tf │ ├── cluster │ │ ├── ecs_cluster.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── clusters.tf │ ├── controller │ │ ├── controller.tf │ │ └── variables.tf │ ├── controllers.tf │ ├── datacenter │ │ ├── consul_server.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── datacenters.tf │ ├── gateway │ │ ├── gateway.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── gateways.tf │ ├── outputs.tf │ ├── peering.tf │ ├── providers.tf │ ├── sameness-test │ ├── sameness.tf │ ├── server-app │ │ ├── outputs.tf │ │ ├── server-app.tf │ │ └── variables.tf │ ├── server-apps.tf │ ├── variables.tf │ └── vpc.tf ├── terminating-gateway-tls │ ├── README.md │ ├── certs.tf │ ├── client.tf │ ├── consul-server.tf │ ├── controller.tf │ ├── datacenter │ │ ├── consul-server.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── ecs-cluster.tf │ ├── efs.tf │ ├── external-server-app.tf │ ├── gateway.tf │ ├── outputs.tf │ ├── providers.tf │ ├── variables.tf │ └── vpc.tf ├── terminating-gateway-transparent-proxy │ ├── README.md │ ├── bastion │ │ ├── bastion.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── client.tf │ ├── consul-configs.tf │ ├── consul-server.tf │ ├── controller.tf │ ├── datacenter │ │ ├── consul-server.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── ecs-cluster.tf │ ├── external-server-app.tf │ ├── gateway.tf │ ├── outputs.tf │ ├── providers.tf │ ├── variables.tf │ └── vpc.tf └── terminating-gateway │ ├── README.md │ ├── client.tf │ ├── consul-server.tf │ ├── controller.tf │ ├── datacenter │ ├── consul-server.tf │ ├── outputs.tf │ └── variables.tf │ ├── ecs-cluster.tf │ ├── external-server-app.tf │ ├── gateway.tf │ ├── outputs.tf │ ├── providers.tf │ ├── variables.tf │ └── vpc.tf ├── modules ├── controller │ ├── README.md │ ├── config.tf │ ├── main.tf │ └── variables.tf ├── dev-server │ ├── README.md │ ├── consul_1_14_compat.tf │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── gateway-task │ ├── README.md │ ├── config.tf │ ├── iam.tf │ ├── main.tf │ ├── outputs.tf │ ├── validation.tf │ └── variables.tf └── mesh-task │ ├── README.md │ ├── config.tf │ ├── iam.tf │ ├── main.tf │ ├── outputs.tf │ ├── validation.tf │ └── variables.tf └── test └── acceptance ├── .go-version ├── README.md ├── examples ├── README.md ├── main_test.go └── scenarios │ ├── api-gateway │ └── main.go │ ├── cluster-peering │ └── main.go │ ├── common │ ├── common.go │ ├── consul.go │ ├── ecs.go │ ├── fake_service.go │ └── fake_service_test.go │ ├── ec2-tproxy │ └── main.go │ ├── ec2 │ └── main.go │ ├── fargate │ └── main.go │ ├── hcp │ └── main.go │ ├── locality-aware-routing │ └── main.go │ ├── registry.go │ ├── registry_test.go │ ├── scenario.go │ ├── service-sameness │ └── main.go │ ├── terminating-gateway-tls │ └── main.go │ ├── terminating-gateway-tproxy │ └── main.go │ ├── terminating-gateway │ └── main.go │ └── wan-federation │ └── main.go ├── framework ├── config │ └── config.go ├── flags │ └── flags.go ├── helpers │ ├── cloudwatch.go │ ├── ecs_commands.go │ ├── helpers.go │ └── task.go ├── logger │ └── logger.go └── suite │ └── suite.go ├── go.mod ├── go.sum ├── setup-terraform ├── ec2 │ ├── main.tf │ └── variables.tf ├── hcp │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── main.tf ├── outputs.tf └── variables.tf └── tests ├── basic ├── basic_test.go ├── main_test.go └── terraform │ └── basic-install │ ├── .gitignore │ ├── main.tf │ └── shutdown-monitor.go ├── hcp ├── config_test.go ├── hcp_test.go ├── main_test.go ├── terraform │ ├── ap-tproxy │ │ ├── main.tf │ │ └── variables.tf │ ├── ap │ │ ├── main.tf │ │ └── variables.tf │ ├── hcp-install │ │ ├── main.tf │ │ └── variables.tf │ ├── ns-tproxy │ │ ├── main.tf │ │ └── variables.tf │ └── ns │ │ ├── main.tf │ │ └── variables.tf └── tproxy_test.go ├── tproxy ├── basic_test.go ├── main_test.go └── terraform │ ├── .gitignore │ └── main.tf └── validation ├── terraform ├── admin-partition-validate │ └── main.tf ├── api-gateway-validate │ └── main.tf ├── consul-ecs-config-validate │ ├── main.tf │ ├── test-complete-config.json │ ├── test-empty-config.json │ ├── test-invalid-config.json │ └── test-partial-config.json ├── envoy-readiness-port-validate │ └── main.tf ├── grpc-config-validate │ ├── main.tf │ ├── test-complete-config.json │ ├── test-empty-config.json │ ├── test-invalid-config.json │ └── test-partial-config.json ├── http-config-validate │ ├── main.tf │ ├── test-complete-config.json │ ├── test-empty-config.json │ ├── test-invalid-config.json │ └── test-partial-config.json ├── mesh-gateway-validate │ └── main.tf ├── pass-app-entrypoint │ └── main.tf ├── pass-existing-iam-roles │ └── main.tf ├── pass-role-additional-policies-validate │ └── main.tf ├── public-listener-port-validate │ └── main.tf ├── role-path-validate │ └── main.tf ├── service-name-validate │ └── main.tf ├── terminating-gateway-validate │ └── main.tf ├── tproxy-gateway-validate │ └── main.tf ├── tproxy-validate │ └── main.tf ├── upstreams-validate │ ├── main.tf │ ├── test-invalid-upstreams.json │ ├── test-missing-destinationName.json │ ├── test-missing-localBindPort.json │ ├── test-no-upstreams.json │ └── test-valid-upstreams.json ├── volume-variable-gateway-validate │ └── main.tf └── volume-variable │ └── main.tf └── validation_test.go /.copywrite.hcl: -------------------------------------------------------------------------------- 1 | schema_version = 1 2 | 3 | project { 4 | license = "MPL-2.0" 5 | copyright_year = 2021 6 | 7 | # (OPTIONAL) A list of globs that should not have copyright/license headers. 8 | # Supports doublestar glob patterns for more flexibility in defining which 9 | # files or folders should be ignored 10 | header_ignore = [ 11 | # "vendors/**", 12 | # "**autogen**", 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | 5 | * @hashicorp/consul-selfmanage-maintainers 6 | 7 | /.github/workflows/* @hashicorp/team-selfmanaged-releng @hashicorp/consul-selfmanage-maintainers 8 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | version: 2 5 | 6 | updates: 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | interval: "daily" 11 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Changes proposed in this PR: 2 | - 3 | - 4 | 5 | ## How I've tested this PR: 6 | 7 | ## How I expect reviewers to test this PR: 8 | 9 | ## Checklist: 10 | - [ ] Tests added 11 | - [ ] CHANGELOG entry added 12 | 13 | [HashiCorp engineers only. Community PRs should not add a changelog entry.]:: 14 | [Changelog entries should use present tense, e.g. "Add support for..."]:: -------------------------------------------------------------------------------- /.github/workflows/reusable-get-go-version.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | name: get-go-version 5 | 6 | on: 7 | workflow_call: 8 | outputs: 9 | go-version: 10 | description: "The Go version detected by this workflow" 11 | value: ${{ jobs.get-go-version.outputs.go-version }} 12 | 13 | jobs: 14 | get-go-version: 15 | runs-on: ubuntu-latest 16 | defaults: 17 | run: 18 | working-directory: ./test/acceptance 19 | outputs: 20 | go-version: ${{ steps.get-go-version.outputs.go-version }} 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 24 | - name: Determine Go version 25 | id: get-go-version 26 | run: | 27 | echo "Building with Go $(cat .go-version)" 28 | echo "go-version=$(cat .go-version)" >> "$GITHUB_OUTPUT" -------------------------------------------------------------------------------- /.github/workflows/reusable-go-fmt-and-lint.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | name: go-fmt-and-lint-acceptance 5 | 6 | on: 7 | workflow_call: 8 | inputs: 9 | go-version: 10 | description: "Golang version to be used by this workflow" 11 | required: true 12 | type: string 13 | 14 | jobs: 15 | go-fmt-and-lint-acceptance: 16 | runs-on: ubuntu-latest 17 | defaults: 18 | run: 19 | working-directory: ./test/acceptance 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 23 | - name: Setup Go 24 | uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 25 | with: 26 | go-version: ${{ inputs.go-version }} 27 | cache-dependency-path: ./test/acceptance/go.sum 28 | - name: Go CI lint 29 | uses: golangci/golangci-lint-action@3cfe3a4abbb849e10058ce4af15d205b6da42804 # v3.7.1 30 | with: 31 | args: "--verbose --enable gofmt" 32 | only-new-issues: false 33 | skip-pkg-cache: true 34 | skip-build-cache: true 35 | working-directory: ./test/acceptance 36 | - name: Lint Consul retry 37 | run: | 38 | go install github.com/hashicorp/lint-consul-retry@v1.3.0 39 | lint-consul-retry -------------------------------------------------------------------------------- /.github/workflows/reusable-terraform-fmt.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | name: terraform-fmt 5 | 6 | on: 7 | workflow_call: 8 | 9 | jobs: 10 | terraform-fmt: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 15 | - name: Setup Terraform 16 | uses: hashicorp/setup-terraform@v3 17 | with: 18 | terraform_version: 1.4.2 19 | - name: Validate 20 | run: terraform fmt -check -recursive . -------------------------------------------------------------------------------- /.github/workflows/scenario-validator.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | # Runs scenario tests for a given scenario 5 | name: Scenario validator 6 | on: 7 | workflow_dispatch: 8 | inputs: 9 | scenario_name: 10 | description: 'Name of the scenario to test' 11 | required: true 12 | 13 | jobs: 14 | get-go-version: 15 | uses: ./.github/workflows/reusable-get-go-version.yml 16 | 17 | go-fmt-and-lint-acceptance: 18 | needs: 19 | - get-go-version 20 | uses: ./.github/workflows/reusable-go-fmt-and-lint.yml 21 | with: 22 | go-version: ${{ needs.get-go-version.outputs.go-version }} 23 | 24 | terraform-fmt: 25 | uses: ./.github/workflows/reusable-terraform-fmt.yml 26 | validate-scenario: 27 | needs: 28 | - terraform-fmt 29 | - go-fmt-and-lint-acceptance 30 | - get-go-version 31 | uses: ./.github/workflows/reusable-ecs-example-validator.yml 32 | with: 33 | name: 'Scenario validator' 34 | scenario: ${{ inputs.scenario_name }} 35 | go-version: ${{ needs.get-go-version.outputs.go-version }} 36 | secrets: inherit -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Terraform files 2 | .terraform 3 | terraform.tfstate 4 | terraform.tfvars 5 | *.tfstate* 6 | *.tfvars* 7 | 8 | # OS X files 9 | .history 10 | .DS_Store 11 | 12 | # IntelliJ files 13 | .idea_modules 14 | *.iml 15 | *.iws 16 | *.ipr 17 | .idea/ 18 | build/ 19 | */build/ 20 | out/ 21 | # VIM Swap files 22 | *.swp 23 | 24 | # Go best practices dictate that libraries should not include the vendor directory 25 | vendor 26 | 27 | # Folder used to store temporary test data by Terratest 28 | .test-data 29 | # Ignore Terraform lock files, as we want to test the Terraform code in these repos with the latest provider 30 | # versions. 31 | .terraform.lock.hcl 32 | -------------------------------------------------------------------------------- /_docs/ap-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/ap-example.png -------------------------------------------------------------------------------- /_docs/api-gateway-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/api-gateway-arch.png -------------------------------------------------------------------------------- /_docs/api-gateway-client-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/api-gateway-client-ui.png -------------------------------------------------------------------------------- /_docs/api-gateway-dc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/api-gateway-dc1.png -------------------------------------------------------------------------------- /_docs/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/architecture.png -------------------------------------------------------------------------------- /_docs/consul-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/consul-ui.png -------------------------------------------------------------------------------- /_docs/dev-server-ec2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/dev-server-ec2.png -------------------------------------------------------------------------------- /_docs/dev-server-fargate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/dev-server-fargate.png -------------------------------------------------------------------------------- /_docs/ec2-transparent-proxy-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/ec2-transparent-proxy-ui.png -------------------------------------------------------------------------------- /_docs/example-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/example-app.png -------------------------------------------------------------------------------- /_docs/intentions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/intentions.png -------------------------------------------------------------------------------- /_docs/locality-aware-app-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/locality-aware-app-ui.png -------------------------------------------------------------------------------- /_docs/locality-aware-dc1-failover-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/locality-aware-dc1-failover-ui.png -------------------------------------------------------------------------------- /_docs/locality-aware-dc1-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/locality-aware-dc1-ui.png -------------------------------------------------------------------------------- /_docs/locality-aware-routing-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/locality-aware-routing-arch.png -------------------------------------------------------------------------------- /_docs/mesh-gateways.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/mesh-gateways.png -------------------------------------------------------------------------------- /_docs/mgw-dc1-consul-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/mgw-dc1-consul-ui.png -------------------------------------------------------------------------------- /_docs/mgw-dc2-consul-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/mgw-dc2-consul-ui.png -------------------------------------------------------------------------------- /_docs/mgw-example-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/mgw-example-app.png -------------------------------------------------------------------------------- /_docs/mgw-intentions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/mgw-intentions.png -------------------------------------------------------------------------------- /_docs/mgw-ui-after-intention.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/mgw-ui-after-intention.png -------------------------------------------------------------------------------- /_docs/peering-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/peering-arch.png -------------------------------------------------------------------------------- /_docs/peering-dc1-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/peering-dc1-ui.png -------------------------------------------------------------------------------- /_docs/peering-dc2-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/peering-dc2-ui.png -------------------------------------------------------------------------------- /_docs/peering-established.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/peering-established.png -------------------------------------------------------------------------------- /_docs/peering-exported-service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/peering-exported-service.png -------------------------------------------------------------------------------- /_docs/peering-intention.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/peering-intention.png -------------------------------------------------------------------------------- /_docs/peering-successful.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/peering-successful.png -------------------------------------------------------------------------------- /_docs/sameness-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/sameness-arch.png -------------------------------------------------------------------------------- /_docs/sameness-client-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/sameness-client-ui.png -------------------------------------------------------------------------------- /_docs/sameness-dc1-part1-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/sameness-dc1-part1-ui.png -------------------------------------------------------------------------------- /_docs/sameness-dc1-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/sameness-dc1-ui.png -------------------------------------------------------------------------------- /_docs/sameness-dc2-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/sameness-dc2-ui.png -------------------------------------------------------------------------------- /_docs/sameness-demo-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/sameness-demo-1.png -------------------------------------------------------------------------------- /_docs/sameness-demo-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/sameness-demo-2.png -------------------------------------------------------------------------------- /_docs/sameness-demo-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/sameness-demo-3.png -------------------------------------------------------------------------------- /_docs/sameness-demo-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/sameness-demo-4.png -------------------------------------------------------------------------------- /_docs/sameness-demo-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/sameness-demo-5.png -------------------------------------------------------------------------------- /_docs/sameness-demo-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/sameness-demo-6.png -------------------------------------------------------------------------------- /_docs/sameness-exported-service-dc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/sameness-exported-service-dc1.png -------------------------------------------------------------------------------- /_docs/sameness-peering-dc2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/sameness-peering-dc2.png -------------------------------------------------------------------------------- /_docs/terminating-gateway-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/terminating-gateway-arch.png -------------------------------------------------------------------------------- /_docs/terminating-gateway-client-tproxy-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/terminating-gateway-client-tproxy-ui.png -------------------------------------------------------------------------------- /_docs/terminating-gateway-client-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/terminating-gateway-client-ui.png -------------------------------------------------------------------------------- /_docs/terminating-gateway-dc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/terminating-gateway-dc1.png -------------------------------------------------------------------------------- /_docs/terminating-gateway-external-server-tls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/terminating-gateway-external-server-tls.png -------------------------------------------------------------------------------- /_docs/ui-after-intention.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hashicorp/terraform-aws-consul-ecs/712cf6172f87d41ce09497ec468616d173aed530/_docs/ui-after-intention.png -------------------------------------------------------------------------------- /examples/admin-partitions/terraform/outputs.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | output "hcp_public_endpoint" { 5 | value = hcp_consul_cluster.this.consul_public_endpoint_url 6 | } 7 | 8 | output "token" { 9 | value = hcp_consul_cluster.this.consul_root_token_secret_id 10 | sensitive = true 11 | } 12 | 13 | output "client" { 14 | value = { 15 | name = "example_client_${local.client_suffix}" 16 | partition = var.client_partition 17 | namespace = var.client_namespace 18 | region = var.region 19 | ecs_cluster_arn = aws_ecs_cluster.cluster_1.arn 20 | } 21 | } 22 | 23 | output "server" { 24 | value = { 25 | name = "example_server_${local.server_suffix}" 26 | partition = var.server_partition 27 | namespace = var.server_namespace 28 | region = var.region 29 | ecs_cluster_arn = aws_ecs_cluster.cluster_2.arn 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/admin-partitions/terraform/variables.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | variable "region" { 5 | default = "us-west-2" 6 | description = "AWS region" 7 | } 8 | 9 | variable "hcp_project_id" { 10 | description = "ID of the project in HCP where the Consul server will be created." 11 | type = string 12 | } 13 | 14 | variable "tags" { 15 | type = map(any) 16 | default = {} 17 | description = "Tags to attach to the created resources." 18 | } 19 | 20 | variable "consul_ecs_image" { 21 | description = "Consul ECS image to use." 22 | type = string 23 | default = "hashicorppreview/consul-ecs:0.9.0-dev" 24 | } 25 | 26 | variable "consul_dataplane_image" { 27 | description = "consul-dataplane Docker image." 28 | type = string 29 | default = "hashicorppreview/consul-dataplane:1.6.0-dev" 30 | } 31 | 32 | variable "client_partition" { 33 | description = "The Consul partition to deploy the example client into." 34 | type = string 35 | default = "part1" 36 | } 37 | 38 | variable "client_namespace" { 39 | description = "The Consul namespace to deploy the example client into." 40 | type = string 41 | default = "ns1" 42 | } 43 | 44 | variable "server_partition" { 45 | description = "The Consul partition to deploy the example server into." 46 | type = string 47 | default = "part2" 48 | } 49 | 50 | variable "server_namespace" { 51 | description = "The Consul namespace to deploy the example server into." 52 | type = string 53 | default = "ns2" 54 | } 55 | -------------------------------------------------------------------------------- /examples/api-gateway/consul-server.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | # Run the Consul dev server as an ECS task. 5 | module "dc1" { 6 | name = var.name 7 | region = var.region 8 | source = "./datacenter" 9 | ecs_cluster_arn = aws_ecs_cluster.this.arn 10 | private_subnets = module.vpc.private_subnets 11 | public_subnets = module.vpc.public_subnets 12 | vpc = module.vpc 13 | lb_ingress_ip = var.lb_ingress_ip 14 | log_group_name = aws_cloudwatch_log_group.log_group.name 15 | } 16 | -------------------------------------------------------------------------------- /examples/api-gateway/controller.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | module "ecs_controller" { 5 | depends_on = [module.dc1] 6 | source = "../../modules/controller" 7 | 8 | name_prefix = var.name 9 | ecs_cluster_arn = aws_ecs_cluster.this.arn 10 | region = var.region 11 | subnets = module.vpc.private_subnets 12 | consul_server_hosts = module.dc1.dev_consul_server.server_dns 13 | consul_ca_cert_arn = module.dc1.dev_consul_server.ca_cert_arn 14 | launch_type = "FARGATE" 15 | 16 | consul_bootstrap_token_secret_arn = module.dc1.dev_consul_server.bootstrap_token_secret_arn 17 | 18 | log_configuration = { 19 | logDriver = "awslogs" 20 | options = { 21 | awslogs-group = aws_cloudwatch_log_group.log_group.name 22 | awslogs-region = var.region 23 | awslogs-stream-prefix = "ecs-controller" 24 | } 25 | } 26 | 27 | tls = true 28 | } -------------------------------------------------------------------------------- /examples/api-gateway/datacenter/outputs.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | output "dev_consul_server" { 5 | value = module.dev_consul_server 6 | } 7 | 8 | output "datacenter" { 9 | value = var.datacenter 10 | } 11 | 12 | output "private_subnets" { 13 | value = var.private_subnets 14 | } 15 | 16 | output "public_subnets" { 17 | value = var.public_subnets 18 | } 19 | -------------------------------------------------------------------------------- /examples/api-gateway/datacenter/variables.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | variable "name" { 5 | description = "Name to be used on all the resources as identifier." 6 | type = string 7 | } 8 | 9 | variable "datacenter" { 10 | description = "Name of the consul datacenter." 11 | type = string 12 | default = "dc1" 13 | } 14 | 15 | variable "region" { 16 | description = "AWS region." 17 | type = string 18 | } 19 | 20 | variable "lb_ingress_ip" { 21 | description = "Your IP. This is used in the load balancer security groups to ensure only you can access the Consul UI and example application." 22 | type = string 23 | } 24 | 25 | variable "vpc" { 26 | description = "VPC object from terraform-aws-modules/vpc/aws module." 27 | type = object({ 28 | vpc_id = string 29 | default_security_group_id = string 30 | }) 31 | } 32 | 33 | variable "private_subnets" { 34 | description = "List of private subnet ids." 35 | type = list(string) 36 | } 37 | 38 | variable "public_subnets" { 39 | description = "List of public subnet ids." 40 | type = list(string) 41 | } 42 | 43 | variable "consul_server_startup_timeout" { 44 | description = "The number of seconds to wait for the Consul server to become available via its ALB before continuing. The default is 300s (5m), which should be enough in most cases." 45 | type = number 46 | default = 300 47 | } 48 | 49 | variable "ecs_cluster_arn" { 50 | description = "ARN of the ECS cluster where the Consul server will be deployed to." 51 | type = string 52 | } 53 | 54 | variable "log_group_name" { 55 | description = "Name of the CloudWatch log group where the server task's logs will be pushed to." 56 | type = string 57 | } 58 | -------------------------------------------------------------------------------- /examples/api-gateway/echo-service/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | resource "aws_ecs_service" "echo_app" { 5 | name = "echo-app-${var.name}" 6 | cluster = var.ecs_cluster_arn 7 | task_definition = module.echo_app.task_definition_arn 8 | desired_count = 1 9 | network_configuration { 10 | subnets = var.private_subnets 11 | } 12 | launch_type = "FARGATE" 13 | propagate_tags = "TASK_DEFINITION" 14 | enable_execute_command = true 15 | } 16 | 17 | module "echo_app" { 18 | source = "../../../modules/mesh-task" 19 | family = "echo-app-${var.name}" 20 | port = "3000" 21 | log_configuration = local.echo_app_log_config 22 | acls = true 23 | tls = true 24 | consul_ca_cert_arn = var.consul_ca_cert_arn 25 | enable_transparent_proxy = false 26 | container_definitions = [{ 27 | name = "echo-app" 28 | image = "k8s.gcr.io/ingressconformance/echoserver:v0.0.1" 29 | essential = true 30 | logConfiguration = local.echo_app_log_config 31 | environment = [ 32 | { 33 | name = "SERVICE_NAME" 34 | value = "echo-app-${var.name}" 35 | } 36 | ] 37 | }] 38 | consul_server_hosts = var.consul_server_hosts 39 | } 40 | 41 | locals { 42 | echo_app_log_config = { 43 | logDriver = "awslogs" 44 | options = { 45 | awslogs-group = var.log_group_name 46 | awslogs-region = var.region 47 | awslogs-stream-prefix = "echo-app" 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /examples/api-gateway/echo-service/outputs.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | output "name" { 5 | value = "echo-app-${var.name}" 6 | } -------------------------------------------------------------------------------- /examples/api-gateway/echo-service/variables.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | variable "name" { 5 | description = "Name to be used on all the resources as identifier." 6 | type = string 7 | } 8 | 9 | variable "region" { 10 | description = "AWS region." 11 | type = string 12 | } 13 | 14 | variable "consul_server_hosts" { 15 | description = "Address of Consul servers." 16 | type = string 17 | } 18 | 19 | variable "consul_ca_cert_arn" { 20 | description = "ARN of the secret that contains the Consul's CA cert for communication with the Consul servers." 21 | type = string 22 | } 23 | 24 | variable "private_subnets" { 25 | description = "List of private subnet ids." 26 | type = list(string) 27 | } 28 | 29 | variable "ecs_cluster_arn" { 30 | description = "ARN of the ECS cluster where the Consul server will be deployed to." 31 | type = string 32 | } 33 | 34 | variable "log_group_name" { 35 | description = "Name of the CloudWatch log group where the server task's logs will be pushed to." 36 | type = string 37 | } -------------------------------------------------------------------------------- /examples/api-gateway/ecs-cluster.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | resource "aws_ecs_cluster" "this" { 5 | name = var.name 6 | capacity_providers = ["FARGATE"] 7 | } 8 | -------------------------------------------------------------------------------- /examples/api-gateway/load_balancer.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | # This is an ALB sitting infront of the API gateway ECS task. 5 | # We configure a HTTP listener and pass the load balancer's 6 | # target group config to the gateway ECS task. 7 | resource "aws_lb" "this" { 8 | name = "${var.name}-api-gateway" 9 | internal = false 10 | load_balancer_type = "application" 11 | subnets = module.vpc.public_subnets 12 | security_groups = [aws_security_group.load_balancer.id] 13 | } 14 | 15 | resource "aws_lb_target_group" "this" { 16 | name = "${var.name}-api-gateway" 17 | port = 8443 18 | protocol = "HTTP" 19 | vpc_id = module.vpc.vpc_id 20 | target_type = "ip" 21 | deregistration_delay = 10 22 | health_check { 23 | path = "/health" 24 | healthy_threshold = 2 25 | unhealthy_threshold = 10 26 | timeout = 30 27 | interval = 60 28 | } 29 | } 30 | 31 | resource "aws_lb_listener" "this" { 32 | load_balancer_arn = aws_lb.this.arn 33 | port = "8443" 34 | protocol = "HTTP" 35 | default_action { 36 | type = "forward" 37 | target_group_arn = aws_lb_target_group.this.arn 38 | } 39 | } 40 | 41 | resource "aws_security_group" "load_balancer" { 42 | name = "${var.name}-api-gateway" 43 | description = "Security group for ${var.name}-api-gateway" 44 | vpc_id = module.vpc.vpc_id 45 | } 46 | 47 | # Allow all egress traffic from the LB 48 | resource "aws_security_group_rule" "lb_egress_rule" { 49 | type = "egress" 50 | description = "Egress rule for ${var.name}-api-gateway" 51 | from_port = 0 52 | to_port = 0 53 | protocol = "-1" 54 | cidr_blocks = ["0.0.0.0/0"] 55 | ipv6_cidr_blocks = ["::/0"] 56 | security_group_id = aws_security_group.load_balancer.id 57 | } 58 | 59 | # Allow ingress only from the user's IP. This is done to 60 | # prevent the LB from being exposed to the public internet. 61 | resource "aws_security_group_rule" "lb_ingress_rule" { 62 | type = "ingress" 63 | description = "Ingress rule for ${var.name}-api-gateway" 64 | from_port = 8443 65 | to_port = 8443 66 | protocol = "-1" 67 | cidr_blocks = ["${var.lb_ingress_ip}/32"] 68 | security_group_id = aws_security_group.load_balancer.id 69 | } -------------------------------------------------------------------------------- /examples/api-gateway/outputs.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | output "consul_server_lb_address" { 5 | value = "http://${module.dc1.dev_consul_server.lb_dns_name}:8500" 6 | } 7 | 8 | output "consul_server_bootstrap_token" { 9 | value = module.dc1.dev_consul_server.bootstrap_token_id 10 | sensitive = true 11 | } 12 | 13 | output "api_gateway_lb_url" { 14 | value = "http://${aws_lb.this.dns_name}:8443" 15 | } -------------------------------------------------------------------------------- /examples/api-gateway/provider.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | terraform { 5 | required_providers { 6 | aws = { 7 | source = "hashicorp/aws" 8 | version = "3.63.0" 9 | } 10 | consul = { 11 | source = "hashicorp/consul" 12 | version = "2.18.0" 13 | } 14 | } 15 | } 16 | 17 | provider "aws" { 18 | region = var.region 19 | } 20 | 21 | provider "consul" { 22 | alias = "dc1-cluster" 23 | address = "http://${module.dc1.dev_consul_server.lb_dns_name}:8500" 24 | datacenter = "dc1" 25 | token = module.dc1.dev_consul_server.bootstrap_token_id 26 | } -------------------------------------------------------------------------------- /examples/api-gateway/variables.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | variable "name" { 5 | description = "Name to be used on all the resources as identifier." 6 | type = string 7 | default = "consul-ecs" 8 | } 9 | 10 | variable "region" { 11 | description = "AWS region." 12 | type = string 13 | default = "us-east-1" 14 | } 15 | 16 | variable "lb_ingress_ip" { 17 | description = "Your IP. This is used in the load balancer security groups to ensure only you can access the Consul UI and example application." 18 | type = string 19 | } 20 | -------------------------------------------------------------------------------- /examples/api-gateway/vpc.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | module "vpc" { 5 | source = "terraform-aws-modules/vpc/aws" 6 | version = "2.78.0" 7 | 8 | name = var.name 9 | cidr = "10.0.0.0/16" 10 | azs = data.aws_availability_zones.available.names 11 | private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] 12 | public_subnets = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"] 13 | enable_nat_gateway = true 14 | single_nat_gateway = true 15 | enable_dns_hostnames = true 16 | } 17 | -------------------------------------------------------------------------------- /examples/cluster-peering/datacenter/ecs-cluster.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | resource "aws_ecs_cluster" "this" { 5 | name = var.name 6 | capacity_providers = ["FARGATE"] 7 | } 8 | 9 | resource "aws_cloudwatch_log_group" "log_group" { 10 | name = var.name 11 | } 12 | 13 | module "ecs_controller" { 14 | source = "../../../modules/controller" 15 | 16 | name_prefix = var.name 17 | ecs_cluster_arn = aws_ecs_cluster.this.arn 18 | region = var.region 19 | subnets = var.private_subnets 20 | consul_server_hosts = module.dev_consul_server.server_dns 21 | consul_ca_cert_arn = aws_secretsmanager_secret.ca_cert.arn 22 | launch_type = "FARGATE" 23 | 24 | consul_bootstrap_token_secret_arn = aws_secretsmanager_secret.bootstrap_token.arn 25 | 26 | log_configuration = { 27 | logDriver = "awslogs" 28 | options = { 29 | awslogs-group = aws_cloudwatch_log_group.log_group.name 30 | awslogs-region = var.region 31 | awslogs-stream-prefix = "ecs-controller" 32 | } 33 | } 34 | 35 | consul_ecs_image = var.consul_ecs_image 36 | tls = true 37 | } -------------------------------------------------------------------------------- /examples/cluster-peering/datacenter/outputs.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | output "ecs_cluster" { 5 | value = aws_ecs_cluster.this 6 | } 7 | 8 | output "dev_consul_server" { 9 | value = module.dev_consul_server 10 | } 11 | 12 | output "log_group" { 13 | value = aws_cloudwatch_log_group.log_group 14 | } 15 | 16 | output "datacenter" { 17 | value = var.datacenter 18 | } 19 | 20 | output "private_subnets" { 21 | value = var.private_subnets 22 | } 23 | 24 | output "public_subnets" { 25 | value = var.public_subnets 26 | } 27 | -------------------------------------------------------------------------------- /examples/cluster-peering/datacenter/variables.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | variable "name" { 5 | description = "Name to be used on all the resources as identifier." 6 | type = string 7 | } 8 | 9 | variable "datacenter" { 10 | description = "Name of the consul datacenter." 11 | type = string 12 | default = "dc1" 13 | } 14 | 15 | variable "region" { 16 | description = "AWS region." 17 | type = string 18 | } 19 | 20 | variable "lb_ingress_ip" { 21 | description = "Your IP. This is used in the load balancer security groups to ensure only you can access the Consul UI and example application." 22 | type = string 23 | } 24 | 25 | variable "vpc" { 26 | description = "VPC object from terraform-aws-modules/vpc/aws module." 27 | type = object({ 28 | vpc_id = string 29 | default_security_group_id = string 30 | }) 31 | } 32 | 33 | variable "private_subnets" { 34 | description = "List of private subnet ids." 35 | type = list(string) 36 | } 37 | 38 | variable "public_subnets" { 39 | description = "List of public subnet ids." 40 | type = list(string) 41 | } 42 | 43 | variable "consul_ecs_image" { 44 | description = "Consul ECS image to be used for the ECS controller" 45 | type = string 46 | } 47 | 48 | variable "consul_server_startup_timeout" { 49 | description = "The number of seconds to wait for the Consul server to become available via its ALB before continuing. The default is 300s (5m), which should be enough in most cases." 50 | type = number 51 | default = 300 52 | } -------------------------------------------------------------------------------- /examples/cluster-peering/gateway/gateway.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | locals { 5 | log_config = { 6 | logDriver = "awslogs" 7 | options = { 8 | awslogs-group = var.log_group_name 9 | awslogs-region = var.region 10 | awslogs-stream-prefix = "mesh-gateway" 11 | } 12 | } 13 | } 14 | 15 | module "mesh_gateway" { 16 | source = "../../../modules/gateway-task" 17 | family = var.name 18 | ecs_cluster_arn = var.cluster 19 | subnets = var.private_subnets 20 | security_groups = [var.vpc.default_security_group_id] 21 | log_configuration = local.log_config 22 | consul_server_hosts = var.consul_server_address 23 | kind = "mesh-gateway" 24 | tls = true 25 | consul_ca_cert_arn = var.ca_cert_arn 26 | additional_task_role_policies = var.additional_task_role_policies 27 | enable_transparent_proxy = false 28 | 29 | acls = true 30 | 31 | lb_enabled = true 32 | lb_subnets = var.public_subnets 33 | lb_vpc_id = var.vpc.vpc_id 34 | 35 | consul_ecs_image = var.consul_ecs_image 36 | } 37 | -------------------------------------------------------------------------------- /examples/cluster-peering/gateway/outputs.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | output "wan_address" { 5 | value = module.mesh_gateway.wan_address 6 | } 7 | 8 | output "wan_port" { 9 | value = module.mesh_gateway.wan_port 10 | } 11 | -------------------------------------------------------------------------------- /examples/cluster-peering/gateways.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | locals { 5 | mgw_name_1 = "${var.name}-${local.datacenter_1}-mesh-gateway" 6 | mgw_name_2 = "${var.name}-${local.datacenter_2}-mesh-gateway" 7 | } 8 | 9 | module "dc1_gateway" { 10 | source = "./gateway" 11 | name = local.mgw_name_1 12 | region = var.region 13 | vpc = module.dc1_vpc 14 | private_subnets = module.dc1_vpc.private_subnets 15 | public_subnets = module.dc1_vpc.public_subnets 16 | cluster = module.dc1.ecs_cluster.arn 17 | log_group_name = module.dc1.log_group.name 18 | 19 | consul_ecs_image = var.consul_ecs_image 20 | ca_cert_arn = module.dc1.dev_consul_server.ca_cert_arn 21 | consul_server_address = module.dc1.dev_consul_server.server_dns 22 | 23 | additional_task_role_policies = [aws_iam_policy.execute_command.arn] 24 | } 25 | 26 | // DC2 gateway 27 | module "dc2_gateway" { 28 | source = "./gateway" 29 | name = local.mgw_name_2 30 | region = var.region 31 | vpc = module.dc2_vpc 32 | private_subnets = module.dc2_vpc.private_subnets 33 | public_subnets = module.dc2_vpc.public_subnets 34 | cluster = module.dc2.ecs_cluster.arn 35 | log_group_name = module.dc2.log_group.name 36 | 37 | consul_ecs_image = var.consul_ecs_image 38 | ca_cert_arn = module.dc2.dev_consul_server.ca_cert_arn 39 | consul_server_address = module.dc2.dev_consul_server.server_dns 40 | 41 | additional_task_role_policies = [aws_iam_policy.execute_command.arn] 42 | } 43 | 44 | // Policy that allows execution of remote commands in ECS tasks. 45 | resource "aws_iam_policy" "execute_command" { 46 | name = "${var.name}-ecs-execute-command" 47 | path = "/" 48 | policy = <= 14 8 | } 9 | -------------------------------------------------------------------------------- /modules/dev-server/outputs.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | output "ecs_service_name" { 5 | description = "Name of created Consul server ECS service." 6 | value = aws_ecs_service.this.name 7 | } 8 | 9 | output "security_group_id" { 10 | description = "ID of security group for the ECS service." 11 | value = aws_security_group.ecs_service.id 12 | } 13 | 14 | output "lb_dns_name" { 15 | description = "DNS name of load balancer in front of Consul server." 16 | value = var.lb_enabled ? aws_lb.this[0].dns_name : null 17 | } 18 | 19 | output "lb_security_group_id" { 20 | description = "Security group ID of load balancer in front of Consul server." 21 | value = var.lb_enabled ? aws_security_group.load_balancer[0].id : null 22 | } 23 | 24 | output "ca_cert_arn" { 25 | description = "The ARN of the CA certificate secret for the Consul server." 26 | value = local.ca_cert_arn != "" ? local.ca_cert_arn : null 27 | } 28 | 29 | output "ca_key_arn" { 30 | description = "The ARN of the CA key secret for the Consul server." 31 | value = local.ca_key_arn != "" ? local.ca_key_arn : null 32 | } 33 | 34 | output "server_dns" { 35 | description = "The DNS name of the Consul server service in AWS CloudMap." 36 | value = "${aws_service_discovery_service.server.name}.${aws_service_discovery_private_dns_namespace.server.name}" 37 | } 38 | 39 | output "bootstrap_token_secret_arn" { 40 | description = "The Secrets Manager ARN of the ACL bootstrap token secret." 41 | value = var.acls ? local.bootstrap_token_arn : null 42 | } 43 | 44 | output "bootstrap_token_id" { 45 | description = "The Consul secret ID of the bootstrap ACL token." 46 | value = var.acls ? local.bootstrap_token : null 47 | } 48 | -------------------------------------------------------------------------------- /modules/gateway-task/README.md: -------------------------------------------------------------------------------- 1 | # Gateway Task 2 | 3 | This module deploys a Consul gateway task as part of the service mesh. 4 | 5 | The following gateway kinds are supported: 6 | * Mesh gateway 7 | * API gateway 8 | * Terminating gateway 9 | 10 | See https://www.consul.io/docs/ecs for additional documentation. 11 | -------------------------------------------------------------------------------- /modules/gateway-task/outputs.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | output "task_definition_arn" { 5 | value = aws_ecs_task_definition.this.arn 6 | } 7 | 8 | output "task_role_id" { 9 | value = aws_iam_role.task.id 10 | } 11 | 12 | output "execution_role_id" { 13 | value = aws_iam_role.execution.id 14 | } 15 | 16 | output "task_role_arn" { 17 | value = aws_iam_role.task.arn 18 | } 19 | 20 | output "execution_role_arn" { 21 | value = aws_iam_role.execution.arn 22 | } 23 | 24 | output "task_tags" { 25 | value = aws_ecs_task_definition.this.tags_all 26 | } 27 | 28 | output "wan_address" { 29 | value = local.wan_address 30 | } 31 | 32 | output "wan_port" { 33 | value = local.wan_port 34 | } 35 | 36 | output "lb_security_group_id" { 37 | value = var.lb_enabled && var.lb_create_security_group ? aws_security_group.this[0].id : null 38 | } 39 | -------------------------------------------------------------------------------- /modules/gateway-task/validation.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | locals { 5 | require_tls_for_wan_federation = var.enable_mesh_gateway_wan_federation && !var.tls ? file("ERROR: tls must be true when enable_mesh_gateway_wan_federation is true") : null 6 | wan_address_xor_lb_enabled = var.wan_address != "" && var.lb_enabled ? file("ERROR: Only one of wan_address or lb_enabled may be provided") : null 7 | require_lb_subnets_for_lb = var.lb_enabled && length(var.lb_subnets) < 1 ? file("ERROR: lb_subnets is required when lb_enabled is true") : null 8 | require_lb_vpc_for_lb = var.lb_enabled && var.lb_vpc_id == "" ? file("ERROR: lb_vpc_id is required when lb_enabled is true") : null 9 | 10 | create_xor_modify_security_group = var.lb_create_security_group && var.lb_modify_security_group ? file("ERROR: Only one of lb_create_security_group or lb_modify_security_group may be true") : null 11 | require_sg_id_for_modify = var.lb_modify_security_group && var.lb_modify_security_group_id == "" ? file("ERROR: lb_modify_security_group_id is required when lb_modify_security_group is true") : null 12 | 13 | custom_lb_config_check = var.lb_enabled && length(var.custom_load_balancer_config) > 0 ? file("ERROR: custom_load_balancer_config must only be supplied when var.lb_enabled is false") : null 14 | require_ec2_compability_for_tproxy_support = var.enable_transparent_proxy && (length(var.requires_compatibilities) != 1 || var.requires_compatibilities[0] != "EC2") ? file("ERROR: transparent proxy is supported only in ECS EC2 mode") : null 15 | require_tproxy_enabled_for_consul_dns = var.enable_consul_dns && !var.enable_transparent_proxy ? file("ERROR: var.enable_transparent_proxy must be set to true for Consul DNS to be enabled") : null 16 | } 17 | -------------------------------------------------------------------------------- /modules/mesh-task/README.md: -------------------------------------------------------------------------------- 1 | # Mesh Task 2 | 3 | This module deploys an application task as part of the service mesh. 4 | It is designed so you can easily modify existing [`ecs_task_definition`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_task_definition) 5 | resources to use this module instead. 6 | 7 | See https://www.consul.io/docs/ecs for additional documentation. 8 | -------------------------------------------------------------------------------- /modules/mesh-task/outputs.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | output "task_definition_arn" { 5 | value = aws_ecs_task_definition.this.arn 6 | } 7 | 8 | output "task_role_id" { 9 | value = local.task_role_id 10 | } 11 | 12 | output "execution_role_id" { 13 | value = local.execution_role_id 14 | } 15 | 16 | output "task_role_arn" { 17 | value = local.task_role_arn 18 | } 19 | 20 | output "execution_role_arn" { 21 | value = local.execution_role_arn 22 | } 23 | 24 | output "task_tags" { 25 | value = aws_ecs_task_definition.this.tags_all 26 | } 27 | 28 | -------------------------------------------------------------------------------- /modules/mesh-task/validation.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | locals { 5 | require_port_unless_no_port_true = !var.outbound_only && var.port == 0 ? file("ERROR: port must be set if outbound_only is false") : null 6 | require_listener_and_readiness_ports_to_be_different = (var.envoy_public_listener_port == var.envoy_readiness_port) ? file("ERROR: envoy_public_listener_port should not conflict with envoy_readiness_port") : null 7 | require_namespace_if_partition_is_set = (var.consul_partition != "" && var.consul_namespace == "") ? file("ERROR: consul_namespace must be set if consul_partition is set") : null 8 | require_partition_if_namespace_is_set = (var.consul_namespace != "" && var.consul_partition == "") ? file("ERROR: consul_partition must be set if consul_namespace is set") : null 9 | require_no_additional_task_policies_with_passed_role = (!var.create_task_role && length(var.additional_task_role_policies) > 0) ? file("ERROR: cannot set additional_task_role_policies when create_task_role=false") : null 10 | require_no_additional_execution_policies_with_passed_role = (!var.create_execution_role && length(var.additional_execution_role_policies) > 0) ? file("ERROR: cannot set additional_execution_role_policies when create_execution_role=false") : null 11 | require_ec2_compability_for_tproxy_support = var.enable_transparent_proxy && (length(var.requires_compatibilities) != 1 || var.requires_compatibilities[0] != "EC2") ? file("ERROR: transparent proxy is supported only in ECS EC2 mode") : null 12 | require_tproxy_enabled_for_consul_dns = var.enable_consul_dns && !var.enable_transparent_proxy ? file("ERROR: var.enable_transparent_proxy must be set to true for Consul DNS to be enabled") : null 13 | } -------------------------------------------------------------------------------- /test/acceptance/.go-version: -------------------------------------------------------------------------------- 1 | 1.19.7 2 | -------------------------------------------------------------------------------- /test/acceptance/examples/scenarios/common/common.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package common 5 | 6 | import ( 7 | "io" 8 | "math/rand" 9 | "net/http" 10 | "strings" 11 | "time" 12 | ) 13 | 14 | const ( 15 | characterSet = "abcdefghijklmnopqrstuvwxyz" 16 | ) 17 | 18 | // This method relies on a third party API to retrieve 19 | // the public IP of the host where this test runs. 20 | func GetPublicIP() (string, error) { 21 | resp, err := http.Get("https://api64.ipify.org?format=text") 22 | if err != nil { 23 | return "", err 24 | } 25 | defer resp.Body.Close() 26 | 27 | ip, err := io.ReadAll(resp.Body) 28 | if err != nil { 29 | return "", err 30 | } 31 | 32 | return string(ip), nil 33 | } 34 | 35 | // GenerateRandomStr generate a random string of a given length 36 | // from the predefined characterSet. 37 | // 38 | // Note: The resulting string is always lowercased. 39 | func GenerateRandomStr(length int) string { 40 | rand.Seed(time.Now().UnixNano()) 41 | result := make([]byte, length) 42 | for i := range result { 43 | result[i] = characterSet[rand.Intn(len(characterSet))] 44 | } 45 | return strings.ToLower(string(result)) 46 | } 47 | -------------------------------------------------------------------------------- /test/acceptance/examples/scenarios/registry.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package scenarios 5 | 6 | import "fmt" 7 | 8 | type scenarioName string 9 | 10 | type registry struct { 11 | scenarios map[scenarioName]ScenarioRegistration 12 | } 13 | 14 | func NewScenarioRegistry() ScenarioRegistry { 15 | return ®istry{ 16 | scenarios: make(map[scenarioName]ScenarioRegistration), 17 | } 18 | } 19 | 20 | func (s *registry) Register(reg ScenarioRegistration) { 21 | if _, ok := s.scenarios[scenarioName(reg.Name)]; ok { 22 | panic(fmt.Sprintf("scenario %s already registered", reg.Name)) 23 | } 24 | 25 | if err := reg.validate(); err != nil { 26 | panic(fmt.Errorf("error validating scenario %w", err)) 27 | } 28 | 29 | s.scenarios[scenarioName(reg.Name)] = reg 30 | } 31 | 32 | func (s *registry) Retrieve(name string) (ScenarioRegistration, error) { 33 | scenario, ok := s.scenarios[scenarioName(name)] 34 | if !ok { 35 | return ScenarioRegistration{}, fmt.Errorf("scenario %s is not registered", name) 36 | } 37 | 38 | return scenario, nil 39 | } 40 | -------------------------------------------------------------------------------- /test/acceptance/examples/scenarios/scenario.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package scenarios 5 | 6 | import ( 7 | "fmt" 8 | "testing" 9 | ) 10 | 11 | // ScenarioRegistry helps us interact with the 12 | // actual registry that holds details about the scenarios. 13 | type ScenarioRegistry interface { 14 | // Register registers a scenario into the registry 15 | Register(ScenarioRegistration) 16 | 17 | // Retrieve retrieves a scenario from the registry 18 | Retrieve(name string) (ScenarioRegistration, error) 19 | } 20 | 21 | type TerraformInputVarsHook func() (map[string]interface{}, error) 22 | type ValidateHook func(*testing.T, []byte) 23 | 24 | // ScenarioRegistration is the struct we expect each individual 25 | // scenario to use and register themselves by providing valid 26 | // lifecycle hooks 27 | type ScenarioRegistration struct { 28 | // The name of the scenario. This name should match the value 29 | // of TEST_SCENARIO environment variable which the test uses 30 | // to determine the scenario to run. 31 | Name string 32 | 33 | // The name of the example's folder under the `examples/` directory 34 | FolderName string 35 | 36 | // List of TF variables that needs to be supplied to the 37 | // example's terraform config. 38 | TerraformInputVars TerraformInputVarsHook 39 | 40 | // Validate is the hook called when validations need to be performed on the deployment. This 41 | // hook will only be called after a successful terraform apply. 42 | Validate ValidateHook 43 | } 44 | 45 | func (r *ScenarioRegistration) validate() error { 46 | if r.Name == "" { 47 | return fmt.Errorf("scenario name cannot be empty") 48 | } 49 | 50 | if r.FolderName == "" { 51 | return fmt.Errorf("scenario %s should have a folder name associated to it", r.Name) 52 | } 53 | 54 | if r.TerraformInputVars == nil { 55 | return fmt.Errorf("scenario %s should provide hooks for providing terraform input variables", r.Name) 56 | } 57 | 58 | if r.Validate == nil { 59 | return fmt.Errorf("scenario %s should provide hooks validating the deployment", r.Name) 60 | } 61 | 62 | return nil 63 | } 64 | -------------------------------------------------------------------------------- /test/acceptance/framework/config/config.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package config 5 | 6 | // TestConfig holds configuration for the test suite. 7 | type TestConfig struct { 8 | NoCleanupOnFailure bool 9 | ECSClusterARNs []string `json:"ecs_cluster_arns"` 10 | LaunchType string `json:"launch_type"` 11 | PrivateSubnets interface{} `json:"private_subnets"` 12 | PublicSubnets interface{} `json:"public_subnets"` 13 | Suffix string 14 | Region string `json:"region"` 15 | VpcID string `json:"vpc_id"` 16 | RouteTableIDs []string `json:"route_table_ids"` 17 | LogGroupName string `json:"log_group_name"` 18 | Tags interface{} 19 | ClientServiceName string 20 | ServerServiceName string 21 | ConsulVersion string `json:"consul_version"` 22 | } 23 | 24 | func (t TestConfig) TFVars(ignoreVars ...string) map[string]interface{} { 25 | vars := map[string]interface{}{ 26 | "ecs_cluster_arns": t.ECSClusterARNs, 27 | "launch_type": t.LaunchType, 28 | "private_subnets": t.PrivateSubnets, 29 | "public_subnets": t.PublicSubnets, 30 | "region": t.Region, 31 | "log_group_name": t.LogGroupName, 32 | "vpc_id": t.VpcID, 33 | "route_table_ids": t.RouteTableIDs, 34 | } 35 | 36 | // If the flag is an empty string or object then terratest 37 | // passes '-var tags=' which errors out in Terraform so instead 38 | // we don't set tags and so it never passes the tags var and so 39 | // Terraform uses the variable's default which works. 40 | if t.Tags != "" && t.Tags != "{}" { 41 | vars["tags"] = t.Tags 42 | } 43 | 44 | for _, v := range ignoreVars { 45 | delete(vars, v) 46 | } 47 | return vars 48 | } 49 | 50 | // ConsulImageURI returns the Consul image URI for the configured consul version. 51 | func (t TestConfig) ConsulImageURI(enterprise bool) string { 52 | if enterprise { 53 | return "public.ecr.aws/hashicorp/consul-enterprise:" + t.ConsulVersion + "-ent" 54 | } 55 | return "public.ecr.aws/hashicorp/consul:" + t.ConsulVersion 56 | } 57 | -------------------------------------------------------------------------------- /test/acceptance/framework/helpers/ecs_commands.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package helpers 5 | 6 | import ( 7 | "encoding/json" 8 | "fmt" 9 | "strings" 10 | "testing" 11 | 12 | "github.com/aws/aws-sdk-go-v2/service/ecs" 13 | "github.com/gruntwork-io/terratest/modules/shell" 14 | ) 15 | 16 | type ListTasksResponse struct { 17 | TaskARNs []string `json:"taskArns"` 18 | } 19 | 20 | func ListTasks(t *testing.T, clusterARN, region, family string) (*ListTasksResponse, error) { 21 | args := []string{ 22 | "ecs", 23 | "list-tasks", 24 | "--region", region, 25 | "--cluster", clusterARN, 26 | "--family", family, 27 | } 28 | 29 | taskListOut, err := shell.RunCommandAndGetOutputE(t, shell.Command{ 30 | Command: "aws", 31 | Args: args, 32 | }) 33 | if err != nil { 34 | return nil, fmt.Errorf("failed to run `aws %v`: %w", args, err) 35 | } 36 | 37 | var tasks *ListTasksResponse 38 | err = json.Unmarshal([]byte(taskListOut), &tasks) 39 | if err != nil { 40 | return nil, err 41 | } 42 | 43 | return tasks, nil 44 | } 45 | 46 | func DescribeTasks(t *testing.T, clusterARN, region, taskARN string) (*ecs.DescribeTasksOutput, error) { 47 | args := []string{ 48 | "ecs", 49 | "describe-tasks", 50 | "--region", region, 51 | "--cluster", clusterARN, 52 | "--task", taskARN, 53 | } 54 | 55 | taskListOut, err := shell.RunCommandAndGetOutputE(t, shell.Command{ 56 | Command: "aws", 57 | Args: args, 58 | }) 59 | if err != nil { 60 | return nil, fmt.Errorf("failed to run `aws %v`: %w", args, err) 61 | } 62 | 63 | var tasks *ecs.DescribeTasksOutput 64 | err = json.Unmarshal([]byte(taskListOut), &tasks) 65 | if err != nil { 66 | return nil, err 67 | } 68 | 69 | return tasks, nil 70 | } 71 | 72 | func StopTask(t *testing.T, clusterARN, region, taskARN, reason string) string { 73 | args := []string{ 74 | "ecs", 75 | "stop-task", 76 | "--region", region, 77 | "--cluster", clusterARN, 78 | "--task", taskARN, 79 | "--reason", reason, 80 | } 81 | 82 | return shell.RunCommandAndGetOutput(t, shell.Command{ 83 | Command: "aws", 84 | Args: args, 85 | }) 86 | } 87 | 88 | func GetTaskIDFromARN(taskARN string) string { 89 | arnParts := strings.Split(taskARN, "/") 90 | return arnParts[len(arnParts)-1] 91 | } 92 | -------------------------------------------------------------------------------- /test/acceptance/framework/helpers/helpers.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package helpers 5 | 6 | import ( 7 | "fmt" 8 | "testing" 9 | 10 | "github.com/gruntwork-io/terratest/modules/shell" 11 | "github.com/hashicorp/terraform-aws-consul-ecs/test/acceptance/framework/config" 12 | ) 13 | 14 | // ExecuteRemoteCommand executes a command inside a container in the task specified 15 | // by taskARN. 16 | func ExecuteRemoteCommand(t *testing.T, testConfig *config.TestConfig, clusterARN, taskARN, container, command string) (string, error) { 17 | return shell.RunCommandAndGetOutputE(t, shell.Command{ 18 | Command: "aws", 19 | Args: []string{ 20 | "ecs", 21 | "execute-command", 22 | "--region", 23 | testConfig.Region, 24 | "--cluster", 25 | clusterARN, 26 | "--task", 27 | taskARN, 28 | fmt.Sprintf("--container=%s", container), 29 | "--command", 30 | command, 31 | "--interactive", 32 | }, 33 | }) 34 | } 35 | -------------------------------------------------------------------------------- /test/acceptance/framework/logger/logger.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package logger 5 | 6 | import ( 7 | "fmt" 8 | "testing" 9 | "time" 10 | 11 | terratestTesting "github.com/gruntwork-io/terratest/modules/testing" 12 | ) 13 | 14 | // TestLogger implements terratest's TestLogger interface 15 | // so that we can pass it to terratest objects to have consistent logging 16 | // across all tests. 17 | type TestLogger struct{} 18 | 19 | // Logf takes a format string and args and calls Logf function. 20 | func (tl TestLogger) Logf(t terratestTesting.TestingT, format string, args ...interface{}) { 21 | tt, ok := t.(*testing.T) 22 | if !ok { 23 | t.Error("failed to cast") 24 | } 25 | tt.Helper() 26 | 27 | Logf(tt, format, args...) 28 | } 29 | 30 | // Logf takes a format string and args and logs 31 | // formatted string with a timestamp. 32 | func Logf(t *testing.T, format string, args ...interface{}) { 33 | t.Helper() 34 | 35 | log := fmt.Sprintf(format, args...) 36 | Log(t, log) 37 | } 38 | 39 | // Log calls t.Log, adding an RFC3339 timestamp to the beginning of the log line. 40 | func Log(t *testing.T, args ...interface{}) { 41 | t.Helper() 42 | 43 | allArgs := []interface{}{time.Now().Format(time.RFC3339)} 44 | allArgs = append(allArgs, args...) 45 | t.Log(allArgs...) 46 | } 47 | -------------------------------------------------------------------------------- /test/acceptance/framework/suite/suite.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package suite 5 | 6 | import ( 7 | "flag" 8 | "fmt" 9 | "os/exec" 10 | "testing" 11 | 12 | "github.com/hashicorp/terraform-aws-consul-ecs/test/acceptance/framework/config" 13 | "github.com/hashicorp/terraform-aws-consul-ecs/test/acceptance/framework/flags" 14 | ) 15 | 16 | // DefaultExecs holds the default external executables that are required to 17 | // run the tests. They can be overridden or customized per test as needed. 18 | var DefaultExecs = []string{ 19 | "aws", 20 | "ecs-cli", 21 | "session-manager-plugin", 22 | "terraform", 23 | } 24 | 25 | type suite struct { 26 | m *testing.M 27 | cfg *config.TestConfig 28 | flags *flags.TestFlags 29 | execs []string 30 | } 31 | 32 | type Suite interface { 33 | Run() int 34 | Config() *config.TestConfig 35 | } 36 | 37 | func NewSuite(m *testing.M, execs ...string) Suite { 38 | flags := flags.NewTestFlags() 39 | 40 | flag.Parse() 41 | 42 | exes := DefaultExecs 43 | if len(execs) > 0 { 44 | exes = execs 45 | } 46 | 47 | return &suite{ 48 | m: m, 49 | flags: flags, 50 | execs: exes, 51 | } 52 | } 53 | 54 | func (s *suite) Run() int { 55 | err := s.Vet() 56 | if err != nil { 57 | fmt.Printf("Failed to run tests: %s\n", err) 58 | return 1 59 | } 60 | 61 | testConfig, err := s.flags.TestConfigFromFlags() 62 | if err != nil { 63 | fmt.Printf("Failed to create test config: %s\n", err) 64 | return 1 65 | } 66 | s.cfg = testConfig 67 | 68 | return s.m.Run() 69 | } 70 | 71 | func (s *suite) Config() *config.TestConfig { 72 | return s.cfg 73 | } 74 | 75 | // Vet ensures that the test suite is in a state that it can run. 76 | // It returns a non-nil error if there are failures. 77 | func (s *suite) Vet() error { 78 | // validate flags 79 | if err := s.flags.Validate(); err != nil { 80 | return fmt.Errorf("flag validation failed: %s", err) 81 | } 82 | 83 | // check for required execs 84 | var missing string 85 | for _, e := range s.execs { 86 | if _, err := exec.LookPath(e); err != nil { 87 | missing += ", " + e 88 | } 89 | } 90 | if len(missing) > 0 { 91 | return fmt.Errorf("missing required executable(s) from PATH: %s", missing[2:]) 92 | } 93 | return nil 94 | } 95 | -------------------------------------------------------------------------------- /test/acceptance/setup-terraform/ec2/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | // Setup EC2 container instances for EC2 launch type tests 5 | data "aws_ssm_parameter" "ecs_optimized_ami" { 6 | name = "/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id" 7 | } 8 | 9 | locals { 10 | ecs_optimized_ami = nonsensitive(data.aws_ssm_parameter.ecs_optimized_ami.value) 11 | } 12 | 13 | resource "aws_iam_role" "instance_role" { 14 | name = var.name 15 | assume_role_policy = jsonencode({ 16 | Version = "2012-10-17" 17 | Statement = [ 18 | { 19 | Action = "sts:AssumeRole" 20 | Effect = "Allow" 21 | Principal = { 22 | Service = "ec2.amazonaws.com" 23 | } 24 | }, 25 | ] 26 | }) 27 | 28 | managed_policy_arns = [ 29 | "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" 30 | ] 31 | } 32 | 33 | resource "aws_iam_instance_profile" "instance_profile" { 34 | name = var.name 35 | role = aws_iam_role.instance_role.name 36 | } 37 | 38 | resource "aws_instance" "instances" { 39 | count = var.instance_count 40 | 41 | ami = local.ecs_optimized_ami 42 | instance_type = var.instance_type 43 | iam_instance_profile = aws_iam_instance_profile.instance_profile.name 44 | // Spread instances across subnets 45 | subnet_id = var.vpc.private_subnets[count.index % length(var.vpc.private_subnets)] 46 | vpc_security_group_ids = [var.vpc.default_security_group_id] 47 | 48 | user_data = <> /etc/ecs/ecs.config 51 | EOF 52 | 53 | tags = merge(var.tags, { 54 | Name = var.name 55 | }) 56 | } 57 | -------------------------------------------------------------------------------- /test/acceptance/setup-terraform/ec2/variables.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | variable "ecs_cluster_name" { 5 | type = string 6 | } 7 | 8 | variable "instance_count" { 9 | type = number 10 | } 11 | 12 | variable "instance_type" { 13 | type = string 14 | } 15 | 16 | variable "name" { 17 | type = string 18 | } 19 | 20 | variable "tags" { 21 | type = any 22 | } 23 | 24 | variable "vpc" { 25 | description = "VPC object from terraform-aws-modules/vpc/aws module." 26 | type = any 27 | } 28 | -------------------------------------------------------------------------------- /test/acceptance/setup-terraform/hcp/outputs.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | output "consul_public_endpoint_url" { 5 | value = hcp_consul_cluster.this.consul_public_endpoint_url 6 | } 7 | 8 | output "consul_private_endpoint_url" { 9 | value = hcp_consul_cluster.this.consul_private_endpoint_url 10 | } 11 | 12 | output "token" { 13 | value = hcp_consul_cluster.this.consul_root_token_secret_id 14 | sensitive = true 15 | } 16 | 17 | output "retry_join" { 18 | value = jsondecode(base64decode(hcp_consul_cluster.this.consul_config_file))["retry_join"] 19 | } 20 | 21 | output "bootstrap_token_secret_arn" { 22 | value = aws_secretsmanager_secret.bootstrap_token.arn 23 | } 24 | 25 | output "gossip_key_secret_arn" { 26 | value = aws_secretsmanager_secret.gossip_key.arn 27 | } 28 | 29 | output "consul_ca_cert_secret_arn" { 30 | value = aws_secretsmanager_secret.consul_ca_cert.arn 31 | } 32 | -------------------------------------------------------------------------------- /test/acceptance/setup-terraform/hcp/variables.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | variable "region" { 5 | description = "AWS region" 6 | type = string 7 | } 8 | 9 | variable "suffix" { 10 | description = "Suffix to append to resource names." 11 | type = string 12 | } 13 | 14 | variable "vpc" { 15 | description = "VPC object from terraform-aws-modules/vpc/aws module." 16 | type = any 17 | } 18 | 19 | variable "consul_version" { 20 | description = "The Consul server version." 21 | type = string 22 | } 23 | -------------------------------------------------------------------------------- /test/acceptance/setup-terraform/outputs.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | output "ecs_cluster_arns" { 5 | value = [for c in aws_ecs_cluster.clusters : c.arn] 6 | } 7 | 8 | output "vpc_id" { 9 | value = module.vpc.vpc_id 10 | } 11 | 12 | output "launch_type" { 13 | value = var.launch_type 14 | } 15 | 16 | output "private_subnets" { 17 | value = module.vpc.private_subnets 18 | } 19 | 20 | output "public_subnets" { 21 | value = module.vpc.public_subnets 22 | } 23 | 24 | output "suffix" { 25 | value = random_string.suffix.result 26 | } 27 | 28 | output "log_group_name" { 29 | value = aws_cloudwatch_log_group.log_group.name 30 | } 31 | 32 | output "region" { 33 | value = var.region 34 | } 35 | 36 | output "tags" { 37 | value = var.tags 38 | } 39 | 40 | output "route_table_ids" { 41 | value = [module.vpc.public_route_table_ids[0], module.vpc.private_route_table_ids[0]] 42 | } 43 | 44 | output "enable_hcp" { 45 | value = var.enable_hcp 46 | } 47 | 48 | output "consul_public_endpoint_url" { 49 | value = var.enable_hcp ? module.hcp[0].consul_public_endpoint_url : "" 50 | } 51 | 52 | output "consul_private_endpoint_url" { 53 | value = var.enable_hcp ? module.hcp[0].consul_private_endpoint_url : "" 54 | } 55 | 56 | output "token" { 57 | value = var.enable_hcp ? module.hcp[0].token : "" 58 | sensitive = true 59 | } 60 | 61 | output "retry_join" { 62 | value = var.enable_hcp ? module.hcp[0].retry_join : [] 63 | } 64 | 65 | output "bootstrap_token_secret_arn" { 66 | value = var.enable_hcp ? module.hcp[0].bootstrap_token_secret_arn : "" 67 | } 68 | 69 | output "gossip_key_secret_arn" { 70 | value = var.enable_hcp ? module.hcp[0].gossip_key_secret_arn : "" 71 | } 72 | 73 | output "consul_ca_cert_secret_arn" { 74 | value = var.enable_hcp ? module.hcp[0].consul_ca_cert_secret_arn : "" 75 | } 76 | 77 | output "consul_version" { 78 | value = var.consul_version 79 | } 80 | -------------------------------------------------------------------------------- /test/acceptance/setup-terraform/variables.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | variable "region" { 5 | default = "us-west-2" 6 | description = "AWS region" 7 | } 8 | 9 | variable "role_arn" { 10 | default = "" 11 | description = "AWS role for the AWS provider to assume when running these templates." 12 | } 13 | 14 | variable "tags" { 15 | type = map(any) 16 | default = {} 17 | description = "Tags to attach to the created resources." 18 | } 19 | 20 | variable "launch_type" { 21 | type = string 22 | description = "The ECS launch type for the cluster. Either EC2 or FARGATE." 23 | } 24 | 25 | variable "enable_hcp" { 26 | description = "Whether to spin up an HCP Consul cluster." 27 | type = bool 28 | } 29 | 30 | variable "instance_count" { 31 | description = "Number of EC2 instances to create for the EC2 launch type (if enabled)." 32 | type = number 33 | default = 4 34 | } 35 | 36 | variable "instance_type" { 37 | description = "The instance type for EC2 instances if launch type is EC2." 38 | type = string 39 | default = "t3a.micro" 40 | } 41 | 42 | variable "consul_version" { 43 | description = "The Consul version. Must a valid MAJOR.MINOR.PATCH version string." 44 | type = string 45 | 46 | validation { 47 | condition = can(regex("^\\d+[.]\\d+[.]\\d+$", var.consul_version)) 48 | error_message = "Must a valid MAJOR.MINOR.PATCH version string." 49 | } 50 | } 51 | 52 | variable "hcp_project_id" { 53 | description = "ID of the HCP project where the Consul specific resources will be created." 54 | type = string 55 | } 56 | -------------------------------------------------------------------------------- /test/acceptance/tests/basic/main_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package basic 5 | 6 | import ( 7 | "os" 8 | "testing" 9 | 10 | testsuite "github.com/hashicorp/terraform-aws-consul-ecs/test/acceptance/framework/suite" 11 | ) 12 | 13 | var suite testsuite.Suite 14 | 15 | func TestMain(m *testing.M) { 16 | suite = testsuite.NewSuite(m) 17 | os.Exit(suite.Run()) 18 | } 19 | -------------------------------------------------------------------------------- /test/acceptance/tests/basic/terraform/basic-install/.gitignore: -------------------------------------------------------------------------------- 1 | shutdown-monitor 2 | main 3 | -------------------------------------------------------------------------------- /test/acceptance/tests/hcp/main_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package hcp 5 | 6 | import ( 7 | "os" 8 | "testing" 9 | 10 | testsuite "github.com/hashicorp/terraform-aws-consul-ecs/test/acceptance/framework/suite" 11 | ) 12 | 13 | var suite testsuite.Suite 14 | 15 | func TestMain(m *testing.M) { 16 | suite = testsuite.NewSuite(m) 17 | os.Exit(suite.Run()) 18 | } 19 | -------------------------------------------------------------------------------- /test/acceptance/tests/tproxy/main_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package tproxy 5 | 6 | import ( 7 | "os" 8 | "testing" 9 | 10 | testsuite "github.com/hashicorp/terraform-aws-consul-ecs/test/acceptance/framework/suite" 11 | ) 12 | 13 | var suite testsuite.Suite 14 | 15 | func TestMain(m *testing.M) { 16 | suite = testsuite.NewSuite(m) 17 | os.Exit(suite.Run()) 18 | } 19 | -------------------------------------------------------------------------------- /test/acceptance/tests/tproxy/terraform/.gitignore: -------------------------------------------------------------------------------- 1 | main 2 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/admin-partition-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | provider "aws" { 5 | region = "us-west-2" 6 | } 7 | 8 | variable "partition" { 9 | type = string 10 | default = "" 11 | } 12 | 13 | variable "namespace" { 14 | type = string 15 | default = "" 16 | } 17 | 18 | module "test_client" { 19 | source = "../../../../../../modules/mesh-task" 20 | family = "family" 21 | container_definitions = [{ 22 | name = "basic" 23 | }] 24 | outbound_only = true 25 | consul_server_hosts = "consul.dc1.host" 26 | 27 | consul_partition = var.partition 28 | consul_namespace = var.namespace 29 | 30 | enable_transparent_proxy = false 31 | } 32 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/api-gateway-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | provider "aws" { 5 | region = "us-west-2" 6 | } 7 | 8 | variable "kind" { 9 | type = string 10 | } 11 | 12 | variable "lb_enabled" { 13 | description = "Whether to create an Elastic Load Balancer for the task to allow public ingress to the gateway." 14 | type = bool 15 | default = false 16 | } 17 | 18 | variable "lb_vpc_id" { 19 | type = string 20 | default = "" 21 | } 22 | 23 | variable "lb_subnets" { 24 | type = list(string) 25 | default = [] 26 | } 27 | 28 | variable "custom_lb_config" { 29 | type = any 30 | default = [] 31 | } 32 | 33 | variable "gateway_count" { 34 | type = number 35 | default = 1 36 | } 37 | 38 | module "test_gateway" { 39 | source = "../../../../../../modules/gateway-task" 40 | family = "family" 41 | ecs_cluster_arn = "cluster" 42 | subnets = ["subnets"] 43 | kind = var.kind 44 | gateway_count = var.gateway_count 45 | consul_server_hosts = "localhost:8500" 46 | tls = true 47 | lb_enabled = var.lb_enabled 48 | lb_vpc_id = var.lb_vpc_id 49 | lb_subnets = var.lb_subnets 50 | custom_load_balancer_config = var.custom_lb_config 51 | lb_create_security_group = var.lb_enabled 52 | enable_transparent_proxy = false 53 | } 54 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/consul-ecs-config-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | provider "aws" { 5 | region = "us-west-2" 6 | } 7 | 8 | variable "consul_ecs_config_file" { 9 | type = string 10 | } 11 | 12 | module "test_client" { 13 | source = "../../../../../../modules/mesh-task" 14 | family = "family" 15 | container_definitions = [{ 16 | name = "basic" 17 | }] 18 | consul_server_hosts = "consul.dc1.host" 19 | outbound_only = true 20 | consul_ecs_config = jsondecode(file("${path.module}/${var.consul_ecs_config_file}")) 21 | 22 | enable_transparent_proxy = false 23 | } 24 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/consul-ecs-config-validate/test-complete-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "service": { 3 | "enableTagOverride": false, 4 | "weights": { 5 | "passing": 1, 6 | "warning": 1 7 | } 8 | }, 9 | "proxy": { 10 | "config": { 11 | "some": "data" 12 | }, 13 | "meshGateway": { 14 | "mode": "remote" 15 | }, 16 | "expose": { 17 | "checks": true, 18 | "paths": [ 19 | { 20 | "listenerPort": 1234, 21 | "path": "/path", 22 | "localPathPort": 2345, 23 | "protocol": "http" 24 | } 25 | ] 26 | } 27 | }, 28 | "consulLogin": { 29 | "enabled": true, 30 | "method": "my-method", 31 | "includeEntity": false, 32 | "meta": { 33 | "tag-1": "val-1" 34 | }, 35 | "region": "bogus-east-1", 36 | "stsEndpoint": "https://sts.bogus-east-1.example.com", 37 | "serverIdHeaderValue": "my.consul.example.com" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/consul-ecs-config-validate/test-empty-config.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/consul-ecs-config-validate/test-invalid-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "invalid-key": "", 3 | "service": { 4 | "invalid-key": "" 5 | }, 6 | "proxy": { 7 | "invalid-key": "", 8 | "meshGateway": { 9 | "invalid-key": "" 10 | }, 11 | "expose": { 12 | "invalid-key": "", 13 | "paths": [ 14 | { 15 | "invalid-key": "" 16 | } 17 | ] 18 | } 19 | }, 20 | "consulLogin": { 21 | "invalid-key": "" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/consul-ecs-config-validate/test-partial-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "service": { 3 | "weights": { 4 | "passing": 1, 5 | "warning": 1 6 | } 7 | }, 8 | "proxy": { 9 | "meshGateway": { 10 | "mode": "remote" 11 | } 12 | }, 13 | "consulLogin": { 14 | "method": "my-method", 15 | "region": "bogus-east-1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/envoy-readiness-port-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | provider "aws" { 4 | region = "us-west-2" 5 | } 6 | 7 | variable "envoy_readiness_port" { 8 | type = number 9 | } 10 | 11 | module "test_client" { 12 | source = "../../../../../../modules/mesh-task" 13 | family = "family" 14 | container_definitions = [{ 15 | name = "basic" 16 | }] 17 | consul_server_hosts = "consul.dc1" 18 | outbound_only = true 19 | envoy_readiness_port = var.envoy_readiness_port 20 | 21 | enable_transparent_proxy = false 22 | } -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/grpc-config-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | provider "aws" { 5 | region = "us-west-2" 6 | } 7 | 8 | variable "grpc_config_file" { 9 | type = string 10 | } 11 | 12 | module "test_client" { 13 | source = "../../../../../../modules/mesh-task" 14 | family = "family" 15 | container_definitions = [{ 16 | name = "basic" 17 | }] 18 | consul_server_hosts = "consul.dc1.host" 19 | outbound_only = true 20 | grpc_config = jsondecode(file("${path.module}/${var.grpc_config_file}")) 21 | 22 | enable_transparent_proxy = false 23 | } -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/grpc-config-validate/test-complete-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "port": 8503, 3 | "tls": true, 4 | "tlsServerName": "consul.dc1.name", 5 | "caCertFile": "cert.pem" 6 | } -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/grpc-config-validate/test-empty-config.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/grpc-config-validate/test-invalid-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "invalid-field": "invalid-value", 3 | "tls": true, 4 | "tlsServerName": "consul.dc1.name" 5 | } -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/grpc-config-validate/test-partial-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "tls": true, 3 | "tlsServerName": "consul.dc1.name" 4 | } -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/http-config-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | provider "aws" { 5 | region = "us-west-2" 6 | } 7 | 8 | variable "http_config_file" { 9 | type = string 10 | } 11 | 12 | module "test_client" { 13 | source = "../../../../../../modules/mesh-task" 14 | family = "family" 15 | container_definitions = [{ 16 | name = "basic" 17 | }] 18 | consul_server_hosts = "consul.dc1.host" 19 | outbound_only = true 20 | http_config = jsondecode(file("${path.module}/${var.http_config_file}")) 21 | 22 | enable_transparent_proxy = false 23 | } -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/http-config-validate/test-complete-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "port": 8501, 3 | "https": true, 4 | "tls": true, 5 | "tlsServerName": "consul.dc1.name", 6 | "caCertFile": "cert.pem" 7 | } -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/http-config-validate/test-empty-config.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/http-config-validate/test-invalid-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "invalid-field": "invalid-value", 3 | "tls": true, 4 | "tlsServerName": "consul.dc1.name" 5 | } -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/http-config-validate/test-partial-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "tls": true, 3 | "tlsServerName": "consul.dc1.name" 4 | } -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/pass-app-entrypoint/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | // We test this with a Terraform plan only. 5 | 6 | provider "aws" { 7 | region = "us-west-2" 8 | } 9 | 10 | variable "application_shutdown_delay_seconds" { 11 | type = number 12 | default = null 13 | } 14 | 15 | module "test_client" { 16 | source = "../../../../../../modules/mesh-task" 17 | family = "family" 18 | container_definitions = [{ 19 | name = "basic" 20 | }] 21 | consul_server_hosts = "consul.dc1" 22 | outbound_only = true 23 | 24 | application_shutdown_delay_seconds = var.application_shutdown_delay_seconds 25 | 26 | enable_transparent_proxy = false 27 | } 28 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/pass-role-additional-policies-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | // We test this with a 'terraform plan' only. 5 | 6 | provider "aws" { 7 | region = "us-west-2" 8 | } 9 | 10 | variable "test_execution_role" { 11 | description = "By default, we test with the task role. Set this to true to test with the execution role." 12 | type = bool 13 | default = false 14 | } 15 | 16 | 17 | locals { 18 | container_definitions = [{ 19 | name = "basic" 20 | image = "fake" 21 | }] 22 | } 23 | 24 | module "task_role_test" { 25 | count = var.test_execution_role ? 0 : 1 26 | 27 | source = "../../../../../../modules/mesh-task" 28 | family = "family-1" 29 | log_configuration = null 30 | container_definitions = local.container_definitions 31 | consul_server_hosts = "consul.dc1" 32 | outbound_only = true 33 | 34 | create_task_role = false 35 | additional_task_role_policies = ["arn:aws:iam::000000000000:policy/some-policy"] 36 | task_role = { 37 | id = "my-task-role" 38 | arn = "arn:aws:iam::000000000000:role/some-role" 39 | } 40 | } 41 | 42 | module "execution_role_test" { 43 | count = var.test_execution_role ? 1 : 0 44 | 45 | source = "../../../../../../modules/mesh-task" 46 | family = "family-2" 47 | log_configuration = null 48 | container_definitions = local.container_definitions 49 | consul_server_hosts = "consul.dc1" 50 | outbound_only = true 51 | 52 | create_execution_role = false 53 | additional_execution_role_policies = ["arn:aws:iam::000000000000:policy/some-policy"] 54 | execution_role = { 55 | id = "my-task-role" 56 | arn = "arn:aws:iam::000000000000:role/some-role" 57 | } 58 | 59 | enable_transparent_proxy = false 60 | } 61 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/public-listener-port-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | provider "aws" { 5 | region = "us-west-2" 6 | } 7 | 8 | variable "envoy_public_listener_port" { 9 | type = number 10 | } 11 | 12 | module "test_client" { 13 | source = "../../../../../../modules/mesh-task" 14 | family = "family" 15 | container_definitions = [{ 16 | name = "basic" 17 | }] 18 | consul_server_hosts = "consul.dc1" 19 | outbound_only = true 20 | envoy_public_listener_port = var.envoy_public_listener_port 21 | 22 | enable_transparent_proxy = false 23 | } 24 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/role-path-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | provider "aws" { 5 | region = "us-west-2" 6 | } 7 | 8 | variable "iam_role_path" { 9 | type = string 10 | } 11 | 12 | module "test_client" { 13 | source = "../../../../../../modules/mesh-task" 14 | family = "family" 15 | container_definitions = [{ 16 | name = "basic" 17 | }] 18 | outbound_only = true 19 | consul_server_hosts = "consul.dc1" 20 | 21 | iam_role_path = var.iam_role_path 22 | 23 | enable_transparent_proxy = false 24 | } 25 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/service-name-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | provider "aws" { 5 | region = "us-west-2" 6 | } 7 | 8 | variable "consul_service_name" { 9 | type = string 10 | } 11 | 12 | module "test_client" { 13 | source = "../../../../../../modules/mesh-task" 14 | family = "family" 15 | container_definitions = [{ 16 | name = "basic" 17 | }] 18 | consul_server_hosts = "consul.dc1" 19 | outbound_only = true 20 | consul_service_name = var.consul_service_name 21 | 22 | enable_transparent_proxy = false 23 | } 24 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/terminating-gateway-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | provider "aws" { 5 | region = "us-west-2" 6 | } 7 | 8 | variable "kind" { 9 | type = string 10 | } 11 | 12 | variable "gateway_count" { 13 | type = number 14 | default = 1 15 | } 16 | 17 | module "test_gateway" { 18 | source = "../../../../../../modules/gateway-task" 19 | family = "family" 20 | ecs_cluster_arn = "cluster" 21 | subnets = ["subnets"] 22 | kind = var.kind 23 | enable_transparent_proxy = false 24 | gateway_count = var.gateway_count 25 | consul_server_hosts = "localhost:8500" 26 | tls = true 27 | lb_create_security_group = false 28 | } 29 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/tproxy-gateway-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | provider "aws" { 5 | region = "us-west-2" 6 | } 7 | 8 | variable "requires_compatibilities" { 9 | description = "Set of launch types required by the task." 10 | type = list(string) 11 | } 12 | 13 | variable "enable_transparent_proxy" { 14 | description = "Whether to enable or disable transparent proxy for the task" 15 | type = bool 16 | default = true 17 | } 18 | 19 | variable "enable_consul_dns" { 20 | description = "Whether to enable or disable Consul DNS for the task" 21 | type = bool 22 | default = true 23 | } 24 | 25 | module "test_gateway" { 26 | source = "../../../../../../modules/gateway-task" 27 | family = "family" 28 | subnets = ["test-subnet"] 29 | kind = "terminating-gateway" 30 | ecs_cluster_arn = "test-cluster-arn" 31 | consul_server_hosts = "consul.dc1.host" 32 | lb_create_security_group = false 33 | security_groups = ["test-security-group"] 34 | requires_compatibilities = var.requires_compatibilities 35 | enable_transparent_proxy = var.enable_transparent_proxy 36 | enable_consul_dns = var.enable_consul_dns 37 | } 38 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/tproxy-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | provider "aws" { 5 | region = "us-west-2" 6 | } 7 | 8 | variable "requires_compatibilities" { 9 | description = "Set of launch types required by the task." 10 | type = list(string) 11 | } 12 | 13 | variable "enable_transparent_proxy" { 14 | description = "Whether to enable or disable transparent proxy for the task" 15 | type = bool 16 | default = true 17 | } 18 | 19 | variable "enable_consul_dns" { 20 | description = "Whether to enable or disable Consul DNS for the task" 21 | type = bool 22 | default = true 23 | } 24 | 25 | module "test_client" { 26 | source = "../../../../../../modules/mesh-task" 27 | family = "family" 28 | container_definitions = [{ 29 | name = "basic" 30 | }] 31 | outbound_only = true 32 | consul_server_hosts = "consul.dc1.host" 33 | requires_compatibilities = var.requires_compatibilities 34 | enable_transparent_proxy = var.enable_transparent_proxy 35 | enable_consul_dns = var.enable_consul_dns 36 | } 37 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/upstreams-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | provider "aws" { 5 | region = "us-west-2" 6 | } 7 | 8 | variable "upstreams_file" { 9 | type = string 10 | } 11 | 12 | module "test_client" { 13 | source = "../../../../../../modules/mesh-task" 14 | family = "family" 15 | container_definitions = [{ 16 | name = "basic" 17 | }] 18 | consul_server_hosts = "consul.dc1" 19 | outbound_only = true 20 | upstreams = jsondecode(file("${path.module}/${var.upstreams_file}")) 21 | 22 | enable_transparent_proxy = false 23 | } 24 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/upstreams-validate/test-invalid-upstreams.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "invalid-key": "", 4 | "destinationName": "backend", 5 | "localBindPort": 1234 6 | } 7 | ] 8 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/upstreams-validate/test-missing-destinationName.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "localBindPort": 1234 4 | } 5 | ] 6 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/upstreams-validate/test-missing-localBindPort.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "destinationName": "backend" 4 | } 5 | ] 6 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/upstreams-validate/test-no-upstreams.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/upstreams-validate/test-valid-upstreams.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "destinationName": "backend", 4 | "localBindPort": 1234 5 | }, 6 | { 7 | "destinationType": "service", 8 | "destinationNamespace": "test-ns", 9 | "destinationName": "backend", 10 | "datacenter": "dc2", 11 | "localBindAddress": "localhost", 12 | "localBindPort": 1234, 13 | "config": { 14 | "data": "some-upstream-config-data" 15 | }, 16 | "meshGateway": { 17 | "mode": "local" 18 | } 19 | } 20 | ] 21 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/volume-variable-gateway-validate/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | provider "aws" { 5 | region = "us-west-2" 6 | } 7 | 8 | variable "volumes" { 9 | type = any 10 | } 11 | 12 | module "test_gateway" { 13 | source = "../../../../../../modules/gateway-task" 14 | family = "family" 15 | kind = "terminating-gateway" 16 | ecs_cluster_arn = "cluster" 17 | subnets = ["subnets"] 18 | volumes = var.volumes 19 | consul_server_hosts = "consul.dc1" 20 | lb_create_security_group = false 21 | 22 | enable_transparent_proxy = false 23 | } 24 | -------------------------------------------------------------------------------- /test/acceptance/tests/validation/terraform/volume-variable/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) HashiCorp, Inc. 2 | # SPDX-License-Identifier: MPL-2.0 3 | 4 | provider "aws" { 5 | region = "us-west-2" 6 | } 7 | 8 | variable "volumes" { 9 | type = any 10 | } 11 | 12 | module "test_client" { 13 | source = "../../../../../../modules/mesh-task" 14 | family = "family" 15 | volumes = var.volumes 16 | container_definitions = [{ 17 | name = "basic" 18 | }] 19 | consul_server_hosts = "consul.dc1" 20 | outbound_only = true 21 | 22 | enable_transparent_proxy = false 23 | } 24 | --------------------------------------------------------------------------------