Announcing Terraform Support for Kubernetes Service on AWS

Announcing Terraform Support for Kubernetes Service on AWS

Jun 05 2018    Anubhav Mishra

Today, AWS announced the general availability of their new Elastic Container Service for Kubernetes (EKS). AWS EKS is a managed service that makes it easier for users to run Kubernetes on AWS across multiple availability zones with less manual configuration. HashiCorp, an Advanced tier member of the AWS Partner Network, worked closely with AWS engineers on this new resource and is pleased to announce that HashiCorp Terraform will offer day-zero support of AWS EKS. Terraform users will now be able to create and manage EKS clusters as a part of their AWS configurations without having to change their current workflow.

Creating an EKS cluster is incredibly easy using Terraform. It requires using a single resource aws_eks_cluster in the Terraform AWS provider. This post explores creating an EKS cluster using Terraform and an EKS Getting Started Guide is also available.

» Setup

In order to create an EKS cluster using Terraform, users first need to configure the AWS provider. This can be done by adding the provider stanza to the Terraform configuration file.

provider "aws" {
  region = "us-west-2"
}

Then provide AWS credentials using various authentication methods options that are available in Terraform.

In this case, environment variables will be used to configure the AWS provider.

export AWS_ACCESS_KEY_ID={AWS_ACCESS_KEY_ID_HERE}
export AWS_SECRET_ACCESS_KEY={AWS_SECRET_ACCESS_KEY_HERE}

» Creating Resources

In AWS, the EKS cluster lives in a VPC with subnets associated with it and also requires users to provide an IAM role that is associated with the cluster.

Users can provide their existing VPC subnets IDs to create an EKS cluster. The AWS VPC Terraform module is also a good alternative to create a VPC and the associated resources such as subnets.

Terraform can create the IAM role and policy required for an EKS cluster. Below is an example how to create these.

resource "aws_iam_role" "eks-example" {
  name = "terraform-eks-demo"

  assume_role_policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "eks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
POLICY
}

resource "aws_iam_role_policy_attachment" "eks-example-AmazonEKSClusterPolicy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
  role       = "${aws_iam_role.eks-example.name}"
}

resource "aws_iam_role_policy_attachment" "eks-example-AmazonEKSServicePolicy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSServicePolicy"
  role       = "${aws_iam_role.eks-example.name}"
}

The resource required to create a cluster is aws_eks_cluster; this can be seen in the example below.

resource "aws_eks_cluster" "demo" {
  name            = "terraform-eks-demo"
  role_arn        = "${aws_iam_role.eks-example.arn}"

    vpc_config {
    subnet_ids = ["${aws_subnet.default.*.id}"]
  }

  depends_on = [
    "aws_iam_role_policy_attachment.eks-example-AmazonEKSClusterPolicy",
    "aws_iam_role_policy_attachment.eks-example-AmazonEKSServicePolicy",
  ]
}

The resource has standard attributes that are required to be set such as name, role_arn, and subnet_ids. There is a policy attached to the IAM role associated with the aws_eks_cluster resource that is critical for the function of the cluster. In order to make sure that the IAM policy is created first, the depends_on attribute in the resource is used to associate the aws_eks_cluster resource with the two policy attachments.

In order to connect to the Kubernetes cluster created using Terraform, a Kubernetes configuration is required. This can be generated and shown to the user using locals and outputs in Terraform. Below is an example of how one might use locals and an output variable to generate a Kubernetes configuration file using Terraform for the aws_eks_cluster defined in the above example.

locals {
  kubeconfig = <<KUBECONFIG


apiVersion: v1
clusters:
- cluster:
    server: ${aws_eks_cluster.demo.endpoint}
    certificate-authority-data: ${aws_eks_cluster.demo.certificate_authority.0.data}
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: aws
  name: aws
current-context: aws
kind: Config
preferences: {}
users:
- name: aws
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      command: heptio-authenticator-aws
      args:
        - "token"
        - "-i"
        - "${var.cluster-name}"
KUBECONFIG
}

output "kubeconfig" {
  value = "${local.kubeconfig}"
}

Next, run terraform init followed by terraform plan to generate a plan for creating the EKS cluster.

terraform init
terraform plan

If this is the first time a Terraform configuration is being applied, the terraform plan will show _ resources that will be created. If everything looks good, run terraform apply to apply the Terraform configuration.

terraform apply

The terraform apply command will make API calls to AWS to provision the cluster. It might take up to 10 minutes before the EKS cluster is ready.

» Connecting to the Cluster

In order to connect to the Kubernetes cluster using kubectl (the Kubernetes command line tool), heptio-aws-authenticator and a configuration file are required. The configuration can be generated using the command below.

echo $(terraform output kubeconfig) > ~/.kube/eksconfig

Set the KUBECONFIG environment variable to the allow kubectl to use the configuration created above.

export KUBECONFIG=~/.kube/eksconfig

Check the cluster health using kubectl.

kubectl get componentstatus

» Conclusion

Kubernetes is one of the more popular container services available today. AWS is trusted as one of the leading public clouds for running Kubernetes servers. The purpose of EKS is to reduce some of the manual coding required for running Kubernetes on AWS. Support for EKS on the Terraform AWS Provider makes it easier for more users to deploy the service as a part of their current workflow. HashiCorp is pleased to have worked in partnership with AWS to offer support for this new service at its initial release.

For more information on Terraform, please visit: https://www.hashicorp.com/terraform

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×