
EKS on EC2にHCP Consulを接続してみる
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
「HCP Consulをさくっと試してみたい」
HCP Consulのサービスメッシュの機能を試してみたいことがありました。
サービスメッシュを試すのは、EKSクラスターを用意したりが必要で少し面倒です。
簡単に試せる方法はないかと思っていたら、いい感じのサンプルコードが用意されていました。
terraform-aws-hcp-consul/examples/hcp-eks-demo at main · hashicorp/terraform-aws-hcp-consul · GitHub
このサンプルコードは、EKSクラスターの作成~ConsulのインストールまでTerraformでやっています。
簡単にHCP Consulと接続したEKSクラスターを作成できたため、紹介します。
HCP Consulとは
ConsulはHashiCorpが提供しているネットワーク関連のツールです。
サービスディスカバリやサービスメッシュの機能等を提供しています。
Consulの概要については、HashiCorpのYoutubeで分かりやすく解説されています。
ConsulはOSSでも提供されていますが、HCP ConsulとしてSaas版も提供されています。
OSSのConsulは自前でKubernetesクラスター等にインストールする必要がありますが、HCP Consulではユーザー側でConsul Clusterのインフラ管理不要で使用できます。
HashiCorp Consul: Enterprise Pricing, Packages & Features
やってみた
HCPクライアントシークレット発行
サンプルコードのTerraform実行に必要なため、HCPクライアントシークレットを発行します。
クライアントシークレットは、Access control(IAM) -> Service principals内で作成できます。


Terraformコード確認
main.tfの中身は以下です。最新の状態やその他のファイル(variables.tf、output.tf等)はGitHubをご確認ください。
terraform-aws-hcp-consul/examples/hcp-eks-demo at main · hashicorp/terraform-aws-hcp-consul · GitHub
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
data "aws_availability_zones" "available" {
  filter {
    name   = "zone-type"
    values = ["availability-zone"]
  }
}
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "2.78.0"
  name                 = "${var.cluster_id}-vpc"
  cidr                 = "10.0.0.0/16"
  azs                  = data.aws_availability_zones.available.names
  public_subnets       = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  private_subnets      = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"]
  enable_nat_gateway   = true
  single_nat_gateway   = true
  enable_dns_hostnames = true
}
data "aws_eks_cluster" "cluster" {
  count = var.install_eks_cluster ? 1 : 0
  name  = module.eks[0].cluster_id
}
data "aws_eks_cluster_auth" "cluster" {
  count = var.install_eks_cluster ? 1 : 0
  name  = module.eks[0].cluster_id
}
module "eks" {
  count                  = var.install_eks_cluster ? 1 : 0
  source                 = "terraform-aws-modules/eks/aws"
  version                = "17.24.0"
  kubeconfig_api_version = "client.authentication.k8s.io/v1beta1"
  cluster_name    = "${var.cluster_id}-eks"
  cluster_version = "1.25"
  subnets         = module.vpc.private_subnets
  vpc_id          = module.vpc.vpc_id
  manage_aws_auth = false
  node_groups = {
    application = {
      name_prefix    = "hashicups"
      instance_types = ["t3a.medium"]
      desired_capacity = 3
      max_capacity     = 3
      min_capacity     = 3
    }
  }
}
# The HVN created in HCP
resource "hcp_hvn" "main" {
  hvn_id         = var.hvn_id
  cloud_provider = "aws"
  region         = var.hvn_region
  cidr_block     = var.hvn_cidr_block
}
# Note: Uncomment the below module to setup peering for connecting to a private HCP Consul cluster
# module "aws_hcp_consul" {
#   source  = "hashicorp/hcp-consul/aws"
#   version = "~> 0.12.1"
#
#   hvn                = hcp_hvn.main
#   vpc_id             = module.vpc.vpc_id
#   subnet_ids         = module.vpc.private_subnets
#   route_table_ids    = module.vpc.private_route_table_ids
#   security_group_ids = var.install_eks_cluster ? [module.eks[0].cluster_primary_security_group_id] : [""]
# }
resource "hcp_consul_cluster" "main" {
  cluster_id         = var.cluster_id
  hvn_id             = hcp_hvn.main.hvn_id
  public_endpoint    = true
  tier               = var.tier
  min_consul_version = "v1.14.0"
}
resource "hcp_consul_cluster_root_token" "token" {
  cluster_id = hcp_consul_cluster.main.id
}
module "eks_consul_client" {
  source  = "hashicorp/hcp-consul/aws//modules/hcp-eks-client"
  version = "~> 0.12.1"
  boostrap_acl_token = hcp_consul_cluster_root_token.token.secret_id
  cluster_id         = hcp_consul_cluster.main.cluster_id
  # strip out url scheme from the public url
  consul_hosts     = tolist([substr(hcp_consul_cluster.main.consul_public_endpoint_url, 8, -1)])
  consul_version   = hcp_consul_cluster.main.consul_version
  datacenter       = hcp_consul_cluster.main.datacenter
  k8s_api_endpoint = var.install_eks_cluster ? module.eks[0].cluster_endpoint : ""
  # The EKS node group will fail to create if the clients are
  # created at the same time. This forces the client to wait until
  # the node group is successfully created.
  depends_on = [module.eks]
}
module "demo_app" {
  count   = var.install_demo_app ? 1 : 0
  source  = "hashicorp/hcp-consul/aws//modules/k8s-demo-app"
  version = "~> 0.12.1"
  depends_on = [module.eks_consul_client]
}
ざっくり以下のリソースを作成しています。
- AWS 
- VPC
 - EKS Cluste
 
 - HCP
- HCP Consul Cluster
 - HVN
 
 - Kubernetes
- デモアプリ用各種リソース
 
 
ちなみに、EKSとHCP Consulを接続するには、最低以下のステップが必要です。 (Consul ClusterをPrivateにする場合は、VPCピアリングなど必要)
| 手順 | |
|---|---|
| HCP Portal | 1. HVN(Hashicorp Virtual Network)とHCP Consul Cluster作成 | 
| 2. EKSからHCP Consulに通信するためのToken発行 | |
| Kubernetes(EKS) | 3. HCP ConsulのTokenをSecrets登録 | 
| 4. HelmでHCP Consulをインストール | 
Terraformのmodule等を使っていい感じに抽象化してくれていますね。
Terraform実行
発行したHCPクライアントシークレットを環境変数に設定します。
$ export HCP_CLIENT_ID=<クライアントID> $ export HCP_CLIENT_SECRET=<クライアントシークレット>
AWS認証情報を設定します。
$ export AWS_ACCESS_KEY_ID=<AWSアクセスキー> $ export AWS_SECRET_ACCESS_KEY=<AWSシークレットアクセスキー> $ export AWS_SESSION_TOKEN=<(必要に応じて)AWSセッショントークン>
terraform applyでリソースをデプロイします。
$ git clone git@github.com:hashicorp/terraform-aws-hcp-consul.git $ cd examples/hcp-eks-demo $ terraform init $ terraform apply
サンプルアプリケーションの確認
デプロイが成功すると、以下のようなサンプルアプリケーションが表示されます。(terraformのoutputsのhashicups_url)

Consul確認
terraformのoutputsのconsul_urlにアクセスしてみると、以下の画面が表示されます。

Serviceを選択すると、他のサービスとどう通信するかといったことも確認できます。

後片付け
以下コマンドで作成したリソースを削除します。
terraform destroy
まとめ
HCP ConsulをEKSに接続してみました。
Service Meshの製品ということで、設定が大変という印象を持っていました。
しかし、実際にやってみると思ったより導入ハードルは低いと感じました。
TerraformでHCPのProviderやConsulのModuleが提供されており、記述量を抑えつつ設定ができました。
以上、AWS事業本部の佐藤(@chari7311)でした。







