diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index 74766ee..c75d2e9 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -44,6 +44,26 @@ provider "registry.terraform.io/hashicorp/boundary" { ] } +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "2.27.0" + constraints = ">= 2.20.0, ~> 2.27.0" + hashes = [ + "h1:/3kLyOR2jTaWS1MKso4xAztrocGBMxi8yVadWiqSWOg=", + "zh:3bdba30ae67c55dc7e9a317ac0da3b208ea7926fe9c2f0ae6587ee88dcc58d1f", + "zh:3f35138a831c00b188d2ffee27111dd0cf59afad2dd5653ed9e67d59646de12c", + "zh:64066d18f6ae9a316c2bc840ef3e641d7ab94e1ea3a41d12523e77345ad442ef", + "zh:653063d44b44881af3a480f7f8eaa94fa300e0229df2072d30f606bddcc9f025", + "zh:87f306e37efb61d13efa6da53a1e45e97e5996ebc0568b1caf8c3c5e54c05809", + "zh:8c428b9708f9634391e52300218771eab3fe942bb1295d8c0ad50ca4b33db3d9", + "zh:a44e87119a0337ded15479851786a13f412b413d9a463ba550d1210249206b0f", + "zh:aa2c4d110b0de6ef997c0d45f3f23f8a98f5530753095d6eff439a6d91a8ea31", + "zh:eb15ed8781ac6a0dec2f7d03cf090e23cfa05e3225806c6231ff2c574662fd63", + "zh:eb81c563f93bd3303f9620d11cd49f21f3f89ac3475c6d3e821b239feb9c217d", + "zh:f1a344a7f16131123577e4ec994d04a34ea458ec16c1ccac53fe7946bd817b18", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + provider "registry.terraform.io/hashicorp/tls" { version = "4.0.5" hashes = [ diff --git a/database/setup.sql b/database/setup.sql new file mode 100644 index 0000000..2010abd --- /dev/null +++ b/database/setup.sql @@ -0,0 +1,12 @@ +set time zone 'UTC'; +create extension pgcrypto; + +CREATE TABLE products ( + id VARCHAR(255) PRIMARY KEY NOT NULL, + name VARCHAR(255) NOT NULL, + description VARCHAR(255) NOT NULL +); + +INSERT INTO products (id, name, description) VALUES ('2310d6be-0e80-11ed-861d-0242ac120002', 'Vault', 'Secrets management'); +INSERT INTO products (id, name, description) VALUES ('b3bdc008-be8d-4e52-bd0e-73053b397322', 'Boundary', 'Modern privileged access management'); +INSERT INTO products (id, name, description) VALUES ('ed7d5231-55cd-4691-920d-34a8004bcb9f', 'Terraform', 'Infrastructure as code'); \ No newline at end of file diff --git a/eks.tf b/eks.tf new file mode 100644 index 0000000..b1a9180 --- /dev/null +++ b/eks.tf @@ -0,0 +1,44 @@ +data "aws_caller_identity" "current" {} + +data "aws_iam_session_context" "current" { + arn = data.aws_caller_identity.current.arn +} + +data "aws_eks_node_groups" "cluster" { + cluster_name = data.terraform_remote_state.setup.outputs.kubernetes.id +} + +data "aws_eks_node_group" "cluster" { + for_each = data.aws_eks_node_groups.cluster.names + + cluster_name = data.terraform_remote_state.setup.outputs.kubernetes.id + node_group_name = each.value +} + +locals { + node_groups = [for group in data.aws_eks_node_group.cluster : { + rolearn = group.node_role_arn + username = "system:node:{{EC2PrivateDNSName}}" + groups = ["system:bootstrappers", "system:nodes"] + }] +} + +module "eks_auth_configmap" { + source = "terraform-aws-modules/eks/aws//modules/aws-auth" + version = "20.3.0" + + manage_aws_auth_configmap = true + + aws_auth_roles = concat(local.node_groups, [ + { + rolearn = data.aws_iam_session_context.current.issuer_arn + username = "admin-dev" + groups = ["system:masters"] + }, + { + rolearn = aws_iam_role.vault_server.arn + username = "admin-vault" + groups = ["system:masters"] + }, + ]) +} \ No newline at end of file diff --git a/outputs.tf b/outputs.tf new file mode 100644 index 0000000..2d9fd12 --- /dev/null +++ b/outputs.tf @@ -0,0 +1,3 @@ +output "vault_endpoint" { + value = "https://${aws_lb.vault_server.dns_name}:8200" +} \ No newline at end of file diff --git a/providers.tf b/providers.tf index ef36bda..9f18fbf 100644 --- a/providers.tf +++ b/providers.tf @@ -14,6 +14,10 @@ terraform { source = "hashicorp/tls" version = "~> 4.0.5" } + kubernetes = { + source = "hashicorp/kubernetes" + version = "~> 2.27.0" + } } } @@ -36,4 +40,20 @@ provider "boundary" { addr = data.terraform_remote_state.setup.outputs.boundary.public_endpoint auth_method_login_name = data.terraform_remote_state.setup.outputs.boundary.username auth_method_password = data.terraform_remote_state.setup.outputs.boundary.password +} + +data "aws_eks_cluster" "cluster" { + name = data.terraform_remote_state.setup.outputs.kubernetes.id +} +data "aws_eks_cluster_auth" "cluster" { + name = data.terraform_remote_state.setup.outputs.kubernetes.id +} +provider "kubernetes" { + host = data.aws_eks_cluster.cluster.endpoint + cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority[0].data) + exec { + api_version = "client.authentication.k8s.io/v1beta1" + args = ["eks", "get-token", "--cluster-name", data.terraform_remote_state.setup.outputs.kubernetes.id] + command = "aws" + } } \ No newline at end of file diff --git a/scripts/server.sh b/scripts/server.sh index 13970f7..bd4ae5f 100644 --- a/scripts/server.sh +++ b/scripts/server.sh @@ -2,10 +2,26 @@ instance_id=$( curl -Ss -H "X-aws-ec2-metadata-token: $imds_token" 169.254.169.254/latest/meta-data/instance-id ) +apt update && apt -y install apt-transport-https ca-certificates curl jq unzip + wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list -apt update && sudo apt -y install vault jq consul +apt update && sudo apt -y install vault + +curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg +echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list + +apt update && sudo apt -y install kubectl + +curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list + +apt update && sudo apt -y install helm + +curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" +unzip awscliv2.zip +sudo ./aws/install mkdir -p /opt/vault.d chown vault:vault -R /opt/vault.d diff --git a/setup/eks.tf b/setup/eks.tf index 64953be..8a8afb4 100644 --- a/setup/eks.tf +++ b/setup/eks.tf @@ -29,4 +29,15 @@ module "eks" { instance_types = ["m5.large"] } } + + cluster_security_group_additional_rules = { + vault_servers = { + description = "Allow Vault servers to access Kubernetes cluster" + protocol = "tcp" + from_port = 443 + to_port = 443 + type = "ingress" + cidr_blocks = [module.vpc.vpc_cidr_block] + } + } } \ No newline at end of file diff --git a/vault-server-iam.tf b/vault-server-iam.tf index fe522d6..7c84870 100644 --- a/vault-server-iam.tf +++ b/vault-server-iam.tf @@ -77,6 +77,18 @@ data "aws_iam_policy_document" "instance_permissions_policy" { aws_iam_role.vault_server.arn ] } + + statement { + sid = "VaultEC2toAWSEKS" + effect = "Allow" + actions = [ + "eks:DescribeCluster", + "eks:ListClusters" + ] + resources = [ + "*" + ] + } } resource "aws_iam_role_policy" "vault_server" {