-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #63 from hashicorp/webdog/hcp-eks-standard-deployment
Create HCP Consul and Amazon EKS terraform deployment
- Loading branch information
Showing
6 changed files
with
415 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
## Requirements | ||
|
||
| Name | Version | | ||
|------|---------| | ||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.1.5 | | ||
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | 3.74.0 | | ||
| <a name="requirement_hcp"></a> [hcp](#requirement\_hcp) | 0.22.0 | | ||
|
||
## Providers | ||
|
||
| Name | Version | | ||
|------|---------| | ||
| <a name="provider_aws"></a> [aws](#provider\_aws) | 3.74.0 | | ||
| <a name="provider_local"></a> [local](#provider\_local) | 2.1.0 | | ||
| <a name="provider_null"></a> [null](#provider\_null) | 3.1.0 | | ||
|
||
## Modules | ||
|
||
| Name | Source | Version | | ||
|------|--------|---------| | ||
| <a name="module_aws"></a> [aws](#module\_aws) | ./modules/aws | n/a | | ||
| <a name="module_aws_vpc"></a> [aws\_vpc](#module\_aws\_vpc) | registry.terraform.io/terraform-aws-modules/vpc/aws | 3.11.5 | | ||
| <a name="module_cleanup"></a> [cleanup](#module\_cleanup) | ./modules/cleanup | n/a | | ||
| <a name="module_eks"></a> [eks](#module\_eks) | registry.terraform.io/terraform-aws-modules/eks/aws | 18.9.0 | | ||
| <a name="module_eks_iam"></a> [eks\_iam](#module\_eks\_iam) | ./modules/iam | n/a | | ||
| <a name="module_hcp_applications"></a> [hcp\_applications](#module\_hcp\_applications) | ./modules/hcp_applications | n/a | | ||
| <a name="module_hcp_networking"></a> [hcp\_networking](#module\_hcp\_networking) | ./modules/hcp_networking | n/a | | ||
| <a name="module_hcp_networking_primitives"></a> [hcp\_networking\_primitives](#module\_hcp\_networking\_primitives) | ./modules/hcp_networking_primitives | n/a | | ||
| <a name="module_iam_role_for_service_accounts"></a> [iam\_role\_for\_service\_accounts](#module\_iam\_role\_for\_service\_accounts) | registry.terraform.io/terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks | 4.14.0 | | ||
|
||
## Resources | ||
|
||
| Name | Type | | ||
|------|------| | ||
| [local_file.kubernetes_tfvars](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file) | resource | | ||
| [null_resource.update_kubeconfig](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | | ||
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/3.74.0/docs/data-sources/caller_identity) | data source | | ||
|
||
## Inputs | ||
|
||
| Name | Description | Type | Default | Required | | ||
|------|-------------|------|---------|:--------:| | ||
| <a name="input_availability_zones"></a> [availability\_zones](#input\_availability\_zones) | Availability Zones for the EKS Cluster deployed in main.tf | `list(string)` | <pre>[<br> "us-east-1a",<br> "us-east-1b",<br> "us-east-1c"<br>]</pre> | no | | ||
| <a name="input_aws_cidr_block"></a> [aws\_cidr\_block](#input\_aws\_cidr\_block) | CIDR block for AWS VPC | `map` | <pre>{<br> "allocation": "172.16.0.0/19",<br> "subnets": {<br> "private": [<br> "172.16.2.0/24",<br> "172.16.3.0/24"<br> ],<br> "public": [<br> "172.16.4.0/24",<br> "172.16.5.0/24"<br> ]<br> }<br>}</pre> | no | | ||
| <a name="input_cloud_provider"></a> [cloud\_provider](#input\_cloud\_provider) | HCP Default Cloud Provider | `string` | `"aws"` | no | | ||
| <a name="input_cluster_and_vpc_info"></a> [cluster\_and\_vpc\_info](#input\_cluster\_and\_vpc\_info) | EKS Cluster Configuration Details | `any` | <pre>{<br> "name": "tutorialCluster",<br> "policy_description": "Grant the cluster access to describe itself and assume an IAM Role.",<br> "policy_name": "workingenvironmentpolicy",<br> "region": "us-east-1",<br> "stage": "dev",<br> "vpc_name": "hcpTutorialAwsVpc"<br>}</pre> | no | | ||
| <a name="input_default_tags"></a> [default\_tags](#input\_default\_tags) | Default tags to pass to AWS resources | `map(string)` | <pre>{<br> "github": "hashicorp/learn-consul-kubernetes"<br>}</pre> | no | | ||
| <a name="input_hcp_consul_datacenter_name"></a> [hcp\_consul\_datacenter\_name](#input\_hcp\_consul\_datacenter\_name) | Name of Consul datacenter | `string` | `"dc1"` | no | | ||
| <a name="input_hcp_hvn_config"></a> [hcp\_hvn\_config](#input\_hcp\_hvn\_config) | CIDR block for HCP HVN | `map` | <pre>{<br> "allocation": "10.100.0.0/19",<br> "consul_tier": "standard",<br> "name": "hcpTutorial",<br> "vault_tier": "starter_small"<br>}</pre> | no | | ||
| <a name="input_hcp_peering_identifier"></a> [hcp\_peering\_identifier](#input\_hcp\_peering\_identifier) | Name of the peering connection as displayed in the AWS API and Management Console | `string` | `"hcp-consul-vault-tutorial"` | no | | ||
| <a name="input_hcp_region"></a> [hcp\_region](#input\_hcp\_region) | HCP region for HCP-created resources | `string` | `"us-east-1"` | no | | ||
| <a name="input_hcp_vault_cluster_name"></a> [hcp\_vault\_cluster\_name](#input\_hcp\_vault\_cluster\_name) | name of HCP Vault cluster | `string` | `"vault-cluster"` | no | | ||
| <a name="input_hcp_vault_default_namespace"></a> [hcp\_vault\_default\_namespace](#input\_hcp\_vault\_default\_namespace) | HCP Vault's Default Namespace. Must be specified when running Vault Enterprise | `string` | `"admin"` | no | | ||
| <a name="input_kube_namespace"></a> [kube\_namespace](#input\_kube\_namespace) | Which kubernetes namespace to use in this tutorial | `string` | `"default"` | no | | ||
| <a name="input_kube_service_account_name"></a> [kube\_service\_account\_name](#input\_kube\_service\_account\_name) | Name of the Kubernetes service account that maps to an IAM Role | `string` | `"tutorial"` | no | | ||
| <a name="input_node_group_configuration"></a> [node\_group\_configuration](#input\_node\_group\_configuration) | Settings for the EKS Node Groups to pass to the EKS Module in main.tf | `any` | <pre>{<br> "ami_type": "AL2_x86_64",<br> "desired_instances": 2,<br> "disk_size_gigs": 50,<br> "instance_types": [<br> "m5.large"<br> ],<br> "max_instances": 2,<br> "min_instances": 2<br>}</pre> | no | | ||
| <a name="input_profile_name"></a> [profile\_name](#input\_profile\_name) | Profile Name for the AWS Credentials in the working environment pod | `string` | `"kubeUser"` | no | | ||
| <a name="input_region"></a> [region](#input\_region) | Region in which to run this terraform code for the AWS Provider | `string` | `"us-east-1"` | no | | ||
| <a name="input_run_cleanup"></a> [run\_cleanup](#input\_run\_cleanup) | Whether or not to run the cleanup script. False by default, set to True in the tutorial content as environment variable | `bool` | `false` | no | | ||
|
||
## Outputs | ||
|
||
| Name | Description | | ||
|------|-------------| | ||
| <a name="output_consul_auth_data"></a> [consul\_auth\_data](#output\_consul\_auth\_data) | Authentication data for Consul that is passed to the working environment | | ||
| <a name="output_eks_data"></a> [eks\_data](#output\_eks\_data) | Data for the EKS Cluster that is sent to the working environment | | ||
| <a name="output_oidc_provider_arn"></a> [oidc\_provider\_arn](#output\_oidc\_provider\_arn) | The OIDC Provider ARN. Used to connect AWS IAM Roles to Service Accounts whose identities are managed by the Kubernetes cluster. Used to allow the reader to access the AWS CLI in the Pod without copying credentials over. | | ||
| <a name="output_service_account_role_arn"></a> [service\_account\_role\_arn](#output\_service\_account\_role\_arn) | The Service Account Role ARN created for the EKS Cluster. This is passed to the working environment as a Service Annotation in the deployment's podspec. | | ||
| <a name="output_vault_auth_data"></a> [vault\_auth\_data](#output\_vault\_auth\_data) | Authentication data for Vault that is passed to the working environment | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# The identity of the AWS User running this terraform project | ||
data "aws_caller_identity" "current" {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
# Create unique resources | ||
|
||
locals { | ||
unique_id = random_id.unique_identifier.b64_url | ||
vpc_name = "${var.cluster_and_vpc_info.vpc_name}-${local.unique_id}" | ||
hvn_name = "${var.hcp_hvn_config.name}-${local.unique_id}" | ||
hcp_peering_id = "${var.hcp_peering_identifier}-${local.unique_id}" | ||
consul_datacenter_name = "${var.hcp_consul_datacenter_name}-${local.unique_id}" | ||
vault_cluster_name = "${var.hcp_vault_cluster_name}-${local.unique_id}" | ||
eks_cluster_name = "${var.cluster_and_vpc_info.name}-${local.unique_id}" | ||
policy_name = "${var.cluster_and_vpc_info.policy_name}-${local.unique_id}" | ||
|
||
} | ||
|
||
resource "random_id" "unique_identifier" { | ||
byte_length = 2 | ||
} | ||
|
||
# Builds the base VPC for the AWS EKS Cluster | ||
module "aws_vpc" { | ||
# Keep full URL for tf registry modules for cross-IDE compatibility. | ||
source = "registry.terraform.io/terraform-aws-modules/vpc/aws" | ||
version = "3.11.5" | ||
name = local.vpc_name#var.cluster_and_vpc_info.vpc_name | ||
cidr = var.aws_cidr_block.allocation | ||
azs = var.availability_zones | ||
private_subnets = var.aws_cidr_block.subnets.private | ||
public_subnets = var.aws_cidr_block.subnets.public | ||
enable_nat_gateway = true | ||
enable_vpn_gateway = false | ||
# internal-lb: Permits internal Load Balancer creation when a LoadBalancer type is passed. | ||
private_subnet_tags = { | ||
"kubernetes.io/cluster/${var.cluster_and_vpc_info.name}" = "shared" | ||
"kubernetes.io/role/internal-elb" = "1" | ||
} | ||
#elb: Permits Elastic Load Balancer creation when a LoadBalancer type is passed. | ||
public_subnet_tags = { | ||
"kubernetes.io/cluster/${var.cluster_and_vpc_info.name}" = "shared" | ||
"kubernetes.io/role/elb" = "1" | ||
} | ||
|
||
tags = { | ||
Terraform = "true" | ||
Environment = var.cluster_and_vpc_info.stage | ||
} | ||
} | ||
|
||
|
||
# Deploys Amazon EKS | ||
module "eks" { | ||
source = "registry.terraform.io/terraform-aws-modules/eks/aws" | ||
version = "18.9.0" | ||
cluster_name = local.eks_cluster_name | ||
cluster_endpoint_private_access = true | ||
cluster_endpoint_public_access = true | ||
|
||
|
||
cluster_addons = { | ||
coredns = { | ||
resolve_conflicts = "OVERWRITE" | ||
} | ||
kube-proxy = {} | ||
vpc-cni = { | ||
resolve_conflicts = "OVERWRITE" | ||
} | ||
} | ||
|
||
vpc_id = module.aws_vpc.vpc_id | ||
subnet_ids = setunion( | ||
module.aws_vpc.public_subnets, | ||
module.aws_vpc.private_subnets | ||
) | ||
|
||
eks_managed_node_group_defaults = { | ||
ami_type = var.node_group_configuration.ami_type | ||
disk_size = var.node_group_configuration.disk_size_gigs | ||
instance_types = var.node_group_configuration.instance_types | ||
vpc_security_group_ids = [module.hcp.aws_security_group_id] | ||
} | ||
|
||
eks_managed_node_groups = { | ||
blue = {} | ||
green = { | ||
min_size = var.node_group_configuration.min_instances | ||
max_size = var.node_group_configuration.max_instances | ||
desired_size = var.node_group_configuration.desired_instances | ||
} | ||
} | ||
tags = { | ||
Environment = var.cluster_and_vpc_info.stage | ||
} | ||
|
||
} | ||
|
||
# Creates the policy and policy attachment to the role created above this module. Permits the EKS Cluster | ||
# to describe itself, and assume an IAM Role, which is passed to the Kubernetes Service Account downstream. | ||
module "eks_iam" { | ||
source = "github.com/webdog/terraform-eks-iam-cluster-describe" | ||
cluster_arn = module.eks.cluster_arn | ||
description = var.cluster_and_vpc_info.policy_description | ||
policy_name = local.policy_name | ||
role_name = module.iam_role_for_service_accounts.iam_role_name | ||
} | ||
|
||
# This module maps Kubernetes ServiceAccount -> IAM Role | ||
module "iam_role_for_service_accounts" { | ||
source = "registry.terraform.io/terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" | ||
role_name = lower(local.eks_cluster_name) | ||
version = "4.14.0" | ||
|
||
oidc_providers = { | ||
one = { | ||
provider_arn = module.eks.oidc_provider_arn | ||
namespace_service_accounts = ["${var.kube_namespace}:${var.kube_service_account_name}"] | ||
} | ||
} | ||
} | ||
|
||
|
||
# Cleanup ENI module | ||
# This module's resources only run when `terraform destroy` is invoked by the user. A "start_cleanup" variable | ||
# is used to make sure cleanup scripts are not run during a follow up terraform apply, and only during terraform destroy. | ||
# This is passed as TF_VAR_start_cleanup=true to the main project by the reader at the end of the tutorial: | ||
# export TF_VAR_run_cleanup=true; terraform destroy -auto-approve | ||
module "eni_cleanup" { | ||
source = "github.com/webdog/terraform-kubernetes-delete-eni" | ||
vpc_id= module.aws_vpc.vpc_id | ||
region = var.region | ||
} | ||
|
||
|
||
# Creates the peering relationship between HCP and AWS, using the | ||
# defined variables, and module outputs. | ||
module "hcp" { | ||
source = "github.com/webdog/terraform-hcp-consul-cluster" | ||
aws_region = var.region | ||
aws_account_id = data.aws_caller_identity.current.id | ||
aws_vpc_id = module.aws_vpc.vpc_id | ||
aws_default_route_table_id = module.aws_vpc.vpc_main_route_table_id | ||
aws_vpc_cidr_block = var.aws_cidr_block.allocation | ||
hvn_peering_identifier = local.hcp_peering_id | ||
hcp_hvn_cidr_block = var.hcp_hvn_config.allocation | ||
public_route_table_ids = module.aws_vpc.public_route_table_ids | ||
private_route_table_ids = module.aws_vpc.private_route_table_ids | ||
cloud_provider = var.cloud_provider | ||
hcp_region = var.hcp_region | ||
hvn_name = local.hvn_name | ||
cidr_block = var.hcp_hvn_config.allocation | ||
consul_cluster_datacenter = local.consul_datacenter_name | ||
hcp_consul_tier = var.hcp_hvn_config.consul_tier | ||
aws_cidr = var.aws_cidr_block.allocation | ||
hvn_cidr = var.hcp_hvn_config.allocation | ||
hvn_id = local.hvn_name | ||
} | ||
|
||
|
||
# Safely update local environment's kubeconfig file. | ||
resource "null_resource" "update_kubeconfig" { | ||
|
||
provisioner "local-exec" { | ||
# Create empty kubeconfig if it doesn't exist. If it does exist, touch does nothing, but back up the config in either case and use a kubeconfig that is unique for this tutorial. Is deleted during terraform destroy | ||
command = "mv ~/.kube/config ~/.kube/config.bkp && aws eks --region ${var.cluster_and_vpc_info.region} update-kubeconfig --name ${module.eks.cluster_id} --alias ${var.cluster_and_vpc_info.name}" | ||
} | ||
depends_on = [module.eks] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Authentication data for Consul that is passed to the working environment | ||
output "consul_auth_data" { | ||
sensitive = true | ||
value = { | ||
ca_file = module.hcp.consul_ca_file | ||
root_accessor_id = module.hcp.consul_root_token_accessor_id | ||
root_secret_id = module.hcp.consul_root_token_secret_id | ||
consul_config = module.hcp.consul_config_file | ||
consul_cluster_host = module.hcp.consul_cluster_host | ||
consul_root_token = module.hcp.consul_root_token | ||
} | ||
} | ||
|
||
# Data for the EKS Cluster that is sent to the working environment | ||
output "eks_data" { | ||
sensitive = true | ||
value = { | ||
eks_host = module.eks.cluster_endpoint | ||
eks_cert = module.eks.cluster_certificate_authority_data | ||
eks_arn = module.eks.cluster_arn | ||
} | ||
} | ||
|
||
# The OIDC Provider ARN. Used to connect AWS IAM Roles to Service Accounts whose identities are managed by the Kubernetes cluster. | ||
# Used to allow the reader to access the AWS CLI in the Pod without copying credentials over. | ||
output "oidc_provider_arn" { | ||
value = module.eks.oidc_provider_arn | ||
} | ||
|
||
# The Service Account Role ARN created for the EKS Cluster. This is passed to the working environment as a Service | ||
# Annotation in the deployment's podspec. | ||
output "service_account_role_arn" { | ||
value = module.iam_role_for_service_accounts.iam_role_arn | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
terraform { | ||
required_version = ">= 1.0.11" | ||
required_providers { | ||
aws = { | ||
source = "hashicorp/aws" | ||
version = ">=3.74.0" | ||
} | ||
hcp = { | ||
source = "hashicorp/hcp" | ||
version = ">=0.22.0" | ||
} | ||
} | ||
} | ||
|
||
provider "aws" { | ||
region = var.region | ||
} | ||
|
||
provider "hcp" {} | ||
|
Oops, something went wrong.