Readying Terraform Modules
If your organization intends to use AWS, then it is recommended that you review the Terraform modules that Cogynt provides to guide the installation, and modify them if necessary. These modules define everything that is needed from AWS in order to run Cogynt. Terraform uses the files to build the required Cogynt infrastructure and set up guardrails for Cogynt's working clusters.
Note
Terraform modules are meant to facilitate AWS installation. They are not required for installing, deploying, or running Cogynt.
Cogynt provides a set of .tf files in the eksv2 and ia directories. The directory contents are described in greater detail under the corresponding topic headings.
eksv2 Directory Contents
The eksv2 directory contains the following files.
iam.tf
The iam.tf file defines the roles for every node and application type for the OID connection. It includes the following definitions by default.
Nodes
Master Node
Description
The master node monitors, manages, and controls the other nodes in the cluster. It accepts client requests, schedules containers, and runs control loops to guide the cluster toward the correct state and outcome.
Node Definition
resource "aws_iam_role" "master_role" {
name = var.master_node.role_name
description = var.master_node.role_description
assume_role_policy = jsonencode({
"Version" = "2012-10-17",
"Statement" = [
{
"Action" = "sts:AssumeRole",
"Principal" = {
"Service" = "eks.amazonaws.com"
},
"Effect" = "Allow",
"Sid" = ""
}
]
})
inline_policy {
name = var.master_node.inline_policy_name
policy = jsonencode({
"Version" = "2012-10-17",
"Statement" = [
{
"Effect" = "Allow",
"Action" = [
"ec2:DescribeAccountAttributes",
"ec2:DescribeInstances",
"ec2:DescribeInternetGateways",
"ec2:DescribeRegions",
"ec2:DescribeRouteTables",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeVolumes"
],
"Resource" = [
"*"
]
},
{
"Effect" = "Allow",
"Action" = [
"ec2:CreateSecurityGroup",
"ec2:CreateTags",
"ec2:CreateVolume",
"ec2:DescribeVolumesModifications",
"ec2:ModifyInstanceAttribute",
"ec2:ModifyVolume"
],
"Resource" = [
"*"
]
},
{
"Effect" = "Allow",
"Action" = [
"ec2:AttachVolume",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CreateRoute",
"ec2:DeleteRoute",
"ec2:DeleteSecurityGroup",
"ec2:DeleteVolume",
"ec2:DetachVolume",
"ec2:RevokeSecurityGroupIngress"
],
"Resource" = [
"*"
],
"Condition" = {
"StringEquals" = {
"eks:cluster-name" = "${var.cluster.name}"
}
}
},
{
"Effect" = "Allow",
"Action" = [
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeTags",
"ec2:DescribeLaunchTemplateVersions"
],
"Resource" = [
"*"
]
},
{
"Effect" = "Allow",
"Action" = [
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup",
"autoscaling:UpdateAutoScalingGroup"
],
"Resource" = [
"*"
],
"Condition" = {
"StringEquals" = {
"autoscaling:ResourceTag/KubernetesCluster" = "${var.cluster.name}"
}
}
},
{
"Effect" = "Allow",
"Action" = [
"elasticloadbalancing:AddTags",
"elasticloadbalancing:AttachLoadBalancerToSubnets",
"elasticloadbalancing:ApplySecurityGroupsToLoadBalancer",
"elasticloadbalancing:CreateLoadBalancer",
"elasticloadbalancing:CreateLoadBalancerPolicy",
"elasticloadbalancing:CreateLoadBalancerListeners",
"elasticloadbalancing:ConfigureHealthCheck",
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:DeleteLoadBalancerListeners",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeLoadBalancerAttributes",
"elasticloadbalancing:DetachLoadBalancerFromSubnets",
"elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"elasticloadbalancing:RegisterInstancesWithLoadBalancer",
"elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer"
],
"Resource" = [
"*"
]
},
{
"Effect" = "Allow",
"Action" = [
"ec2:DescribeVpcs",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:CreateListener",
"elasticloadbalancing:CreateTargetGroup",
"elasticloadbalancing:DeleteListener",
"elasticloadbalancing:DeleteTargetGroup",
"elasticloadbalancing:DeregisterTargets",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:DescribeLoadBalancerPolicies",
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:ModifyListener",
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:SetLoadBalancerPoliciesOfListener"
],
"Resource" = [
"*"
]
},
{
"Effect" = "Allow",
"Action" = [
"iam:ListServerCertificates",
"iam:GetServerCertificate"
],
"Resource" = [
"*"
]
},
{
"Effect" = "Allow",
"Action" = [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:BatchGetImage"
],
"Resource" = [
"*"
]
}
]
})
}
}
resource "aws_iam_instance_profile" "master_profile" {
name = var.master_node.instance_profile_name
role = aws_iam_role.master_role.name
}
Worker Node
Description
Worker nodes execute containerized application workloads as dictated by the master node.
Node Definition
resource "aws_iam_role" "worker_role" {
name = var.worker_node.role_name
description = var.worker_node.role_description
assume_role_policy = jsonencode({
"Version" = "2012-10-17"
"Statement" = [
{
"Action" = "sts:AssumeRole"
"Principal" = {
"Service" = "ec2.amazonaws.com"
},
"Effect" = "Allow"
}
]
})
inline_policy {
name = var.worker_node.inline_policy_name
policy = jsonencode({
"Version" = "2012-10-17"
"Statement" = [
{
"Effect" = "Allow"
"Action" = [
"ec2:DescribeInstances",
"ec2:DescribeRegions"
],
"Resource" = [
"*"
]
},
{
"Effect" = "Allow",
"Action" = [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:BatchGetImage"
],
"Resource" = [
"*"
]
},
{
"Effect" = "Allow",
"Action" = [
"autoscaling:DescribeTags",
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup",
"autoscaling:DescribeLaunchConfigurations",
"ec2:DescribeLaunchTemplateVersions"
],
"Resource" = [
"*"
]
}
]
})
}
}
resource "aws_iam_instance_profile" "worker_profile" {
name = var.worker_node.instance_profile_name
role = aws_iam_role.worker_role.name
}
resource "aws_iam_role_policy_attachment" "worker_s3_policy" {
role = aws_iam_role.worker_role.name
policy_arn = aws_iam_policy.s3_data.arn
}
resource "aws_iam_role_policy_attachment" "worker_additional_policies" {
for_each = var.worker_node.additional_policy_arn_attachments
role = aws_iam_role.worker_role.name
policy_arn = each.value
}
Storage Node
Description
Storage nodes provide long-term and temporary storage for the cluster.
Node Definition
resource "aws_iam_role" "storage_role" {
name = var.storage_node.role_name
description = var.storage_node.role_description
assume_role_policy = jsonencode({
"Version" = "2012-10-17",
"Statement" = [
{
"Action" = "sts:AssumeRole",
"Principal" = {
"Service" = "ec2.amazonaws.com"
},
"Effect" = "Allow",
"Sid" = ""
}
]
})
inline_policy {
name = var.storage_node.inline_policy_name
policy = jsonencode({
"Version" = "2012-10-17"
"Statement" = [
{
"Effect" = "Allow"
"Action" = [
"ec2:DescribeInstances",
"ec2:DescribeRegions"
],
"Resource" = [
"*"
]
},
{
"Effect" = "Allow",
"Action" = [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:BatchGetImage"
],
"Resource" = [
"*"
]
},
{
"Effect" = "Allow",
"Action" = [
"autoscaling:DescribeTags",
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup",
"autoscaling:DescribeLaunchConfigurations",
"ec2:DescribeLaunchTemplateVersions"
],
"Resource" = [
"*"
]
}
]
})
}
inline_policy {
name = var.storage_node.portworx_inline_policy_name
policy = jsonencode({
"Version" = "2012-10-17",
"Statement" = [
{
"Effect" = "Allow",
"Action" = [
"ec2:AttachVolume",
"ec2:ModifyVolume",
"ec2:DetachVolume",
"ec2:CreateTags",
"ec2:CreateVolume",
"ec2:DeleteTags",
"ec2:DeleteVolume",
"ec2:DescribeTags",
"ec2:DescribeVolumeAttribute",
"ec2:DescribeVolumesModifications",
"ec2:DescribeVolumeStatus",
"ec2:DescribeVolumes",
"ec2:DescribeInstances",
"autoscaling:DescribeAutoScalingGroups"
],
"Resource" = [
"*"
]
},
{
"Effect" = "Allow",
"Action" = [
"autoscaling:DescribeTags",
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup",
"autoscaling:DescribeLaunchConfigurations",
"ec2:DescribeLaunchTemplateVersions"
],
"Resource" = ["*"]
}
]
})
}
}
resource "aws_iam_instance_profile" "storage_profile" {
name = var.storage_node.instance_profile_name
role = aws_iam_role.storage_role.name
}
resource "aws_iam_role_policy_attachment" "storage_s3_policy" {
role = aws_iam_role.storage_role.name
policy_arn = aws_iam_policy.s3_data.arn
}
resource "aws_iam_role_policy_attachment" "master-AmazonEKSClusterPolicy" {
policy_arn = "arn:${var.aws_partition}:iam::aws:policy/AmazonEKSClusterPolicy"
role = aws_iam_role.master_role.name
}
resource "aws_iam_role_policy_attachment" "master-AmazonEKSVPCResourceController" {
policy_arn = "arn:${var.aws_partition}:iam::aws:policy/AmazonEKSVPCResourceController"
role = aws_iam_role.master_role.name
}
resource "aws_iam_role_policy_attachment" "worker-AmazonEKSWorkerNodePolicy" {
policy_arn = "arn:${var.aws_partition}:iam::aws:policy/AmazonEKSWorkerNodePolicy"
role = aws_iam_role.worker_role.name
}
resource "aws_iam_role_policy_attachment" "worker-AmazonEKS_CNI_Policy" {
policy_arn = "arn:${var.aws_partition}:iam::aws:policy/AmazonEKS_CNI_Policy"
role = aws_iam_role.worker_role.name
}
resource "aws_iam_role_policy_attachment" "worker-AmazonEC2ContainerRegistryReadOnly" {
policy_arn = "arn:${var.aws_partition}:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
role = aws_iam_role.worker_role.name
}
resource "aws_iam_role_policy_attachment" "worker-AmazonSSMManagedInstanceCore" {
policy_arn = "arn:${var.aws_partition}:iam::aws:policy/AmazonSSMManagedInstanceCore"
role = aws_iam_role.worker_role.name
}
resource "aws_iam_role_policy_attachment" "storage-AmazonEKSWorkerNodePolicy" {
policy_arn = "arn:${var.aws_partition}:iam::aws:policy/AmazonEKSWorkerNodePolicy"
role = aws_iam_role.storage_role.name
}
resource "aws_iam_role_policy_attachment" "storage-AmazonEKS_CNI_Policy" {
policy_arn = "arn:${var.aws_partition}:iam::aws:policy/AmazonEKS_CNI_Policy"
role = aws_iam_role.storage_role.name
}
resource "aws_iam_role_policy_attachment" "storage-AmazonEC2ContainerRegistryReadOnly" {
policy_arn = "arn:${var.aws_partition}:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
role = aws_iam_role.storage_role.name
}
resource "aws_iam_role_policy_attachment" "storage-AmazonSSMManagedInstanceCore" {
policy_arn = "arn:${var.aws_partition}:iam::aws:policy/AmazonSSMManagedInstanceCore"
role = aws_iam_role.storage_role.name
}
Applications
OIDC Provider
Description
In Cogynt, the OIDC provider establishes a trust relationship between Cogynt's external identity provider and the hosting AWS account.
For more information about OIDC providers, refer to the official AWS documentation.
Sample Code
data "tls_certificate" "eks" {
url = aws_eks_cluster.cluster.identity[0].oidc[0].issuer
}
resource "aws_iam_openid_connect_provider" "eks" {
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = [data.tls_certificate.eks.certificates[0].sha1_fingerprint]
url = aws_eks_cluster.cluster.identity[0].oidc[0].issuer
}
External DNS
Description
The external DNS makes Kubernetes resources discoverable via public DNS servers. This allows configuring external DNS servers (such as AWS) for Kubernetes services.
Sample Code
resource "aws_iam_policy" "externaldns" {
count = var.hosted_zone.name != "" ? 1 : 0
name = var.externaldns.policy_name
path = "/"
description = var.externaldns.policy_description
policy = jsonencode({
Version = "2012-10-17"
"Statement" = [
{
"Effect" = "Allow",
"Action" = [
"route53:ChangeResourceRecordSets"
],
"Resource" = [
"arn:${var.aws_partition}:route53:::hostedzone/${data.aws_route53_zone.this[count.index].id}"
]
},
{
"Effect" = "Allow",
"Action" = [
"route53:ListHostedZones",
"route53:ListResourceRecordSets"
],
"Resource" = [
"*"
]
}
]
})
}
module "externaldns_role" {
count = var.hosted_zone.name != "" ? 1 : 0
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "~> 3.0"
create_role = true
role_name = var.externaldns.role_name
provider_url = aws_eks_cluster.cluster.identity[0].oidc[0].issuer
role_policy_arns = [
aws_iam_policy.externaldns[count.index].arn
]
number_of_role_policy_arns = 1
}
Project Istio
Description
The project Istio is an infrastructure layer that adds observability, traffic management, and security capabilities.
For more information about Istio, refer to the official Istio documentation.
Sample Code
resource "aws_iam_policy" "istio" {
name = var.istio.policy_name
path = "/"
description = var.istio.policy_description
policy = jsonencode({
Version = "2012-10-17"
"Statement" = [
{
"Effect" = "Allow",
"Action" = [
"elasticloadbalancing:AddTags",
"elasticloadbalancing:AttachLoadBalancerToSubnets",
"elasticloadbalancing:ApplySecurityGroupsToLoadBalancer",
"elasticloadbalancing:CreateLoadBalancer",
"elasticloadbalancing:CreateLoadBalancerPolicy",
"elasticloadbalancing:CreateLoadBalancerListeners",
"elasticloadbalancing:ConfigureHealthCheck",
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:DeleteLoadBalancerListeners",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeLoadBalancerAttributes",
"elasticloadbalancing:DetachLoadBalancerFromSubnets",
"elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"elasticloadbalancing:RegisterInstancesWithLoadBalancer",
"elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer"
],
"Resource" = [
"*"
]
},
{
"Effect" = "Allow",
"Action" = [
"ec2:DescribeVpcs",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:CreateListener",
"elasticloadbalancing:CreateTargetGroup",
"elasticloadbalancing:DeleteListener",
"elasticloadbalancing:DeleteTargetGroup",
"elasticloadbalancing:DeregisterTargets",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:DescribeLoadBalancerPolicies",
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:ModifyListener",
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:SetLoadBalancerPoliciesOfListener"
],
"Resource" = [
"*"
]
},
{
"Effect" = "Allow",
"Action" = [
"iam:ListServerCertificates",
"iam:GetServerCertificate"
],
"Resource" = [
"*"
]
}
]
})
}
module "istio_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "~> 3.0"
create_role = true
role_name = var.istio.role_name
provider_url = aws_eks_cluster.cluster.identity[0].oidc[0].issuer
role_policy_arns = [
aws_iam_policy.istio.arn
]
number_of_role_policy_arns = 1
}
AWS S3 Data
Description
The Amazon S3 data contains the necessary code to make use of Amazon S3 object storage.
Sample Code
resource "aws_iam_policy" "s3_data" {
name = var.s3_data.policy_name
path = "/"
description = var.s3_data.policy_description
policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Action" : [
"s3:PutAnalyticsConfiguration",
"s3:GetObjectVersionTagging",
"s3:CreateBucket",
"s3:ReplicateObject",
"s3:GetObjectAcl",
"s3:GetBucketObjectLockConfiguration",
"s3:DeleteBucketWebsite",
"s3:PutLifecycleConfiguration",
"s3:GetObjectVersionAcl",
"s3:DeleteObject",
"s3:GetBucketPolicyStatus",
"s3:GetObjectRetention",
"s3:GetBucketWebsite",
"s3:PutReplicationConfiguration",
"s3:PutObjectLegalHold",
"s3:GetObjectLegalHold",
"s3:GetBucketNotification",
"s3:PutBucketCORS",
"s3:GetReplicationConfiguration",
"s3:ListMultipartUploadParts",
"s3:PutObject",
"s3:GetObject",
"s3:PutBucketNotification",
"s3:PutBucketLogging",
"s3:GetAnalyticsConfiguration",
"s3:PutBucketObjectLockConfiguration",
"s3:GetObjectVersionForReplication",
"s3:GetLifecycleConfiguration",
"s3:GetInventoryConfiguration",
"s3:GetBucketTagging",
"s3:PutAccelerateConfiguration",
"s3:DeleteObjectVersion",
"s3:GetBucketLogging",
"s3:ListBucketVersions",
"s3:RestoreObject",
"s3:ListBucket",
"s3:GetAccelerateConfiguration",
"s3:GetBucketPolicy",
"s3:PutEncryptionConfiguration",
"s3:GetEncryptionConfiguration",
"s3:GetObjectVersionTorrent",
"s3:AbortMultipartUpload",
"s3:GetBucketRequestPayment",
"s3:GetObjectTagging",
"s3:GetMetricsConfiguration",
"s3:DeleteBucket",
"s3:PutBucketVersioning",
"s3:GetBucketPublicAccessBlock",
"s3:ListBucketMultipartUploads",
"s3:PutIntelligentTieringConfiguration",
"s3:PutMetricsConfiguration",
"s3:PutBucketOwnershipControls",
"s3:GetBucketVersioning",
"s3:GetBucketAcl",
"s3:PutInventoryConfiguration",
"s3:GetObjectTorrent",
"s3:PutBucketWebsite",
"s3:PutBucketRequestPayment",
"s3:PutObjectRetention",
"s3:GetBucketCORS",
"s3:GetBucketLocation",
"s3:ReplicateDelete",
"s3:GetObjectVersion"
],
"Resource" : [
"arn:${var.aws_partition}:s3:::${var.s3_data.bucket}/*",
"arn:${var.aws_partition}:s3:::${var.s3_data.bucket}"
]
},
{
"Effect" : "Allow",
"Action" : [
"s3:PutStorageLensConfiguration",
"s3:CreateJob"
],
"Resource" : "*"
}
]
})
}
module "s3_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "~> 3.0"
create_role = true
role_name = var.s3_data.role_name
provider_url = aws_eks_cluster.cluster.identity[0].oidc[0].issuer
role_policy_arns = concat([aws_iam_policy.s3_data.arn], tolist(var.worker_node.additional_policy_arn_attachments))
number_of_role_policy_arns = length(concat([aws_iam_policy.s3_data.arn], tolist(var.worker_node.additional_policy_arn_attachments)))
}
HashiCorp Vault
Description
This file defines Cogynt's secret and encryption policies for HashiCorp Vault.
For more information about HashiCorp Vault, refer to the official HashiCorp Vault documentation.
Sample Code
resource "aws_iam_policy" "hcvault" {
name = var.hcvault.policy_name
path = "/"
description = var.hcvault.policy_description
policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Action" : [
"kms:DescribeKey",
"kms:Encrypt",
"kms:Decrypt"
],
"Resource" : [
"${aws_kms_key.hcvault.arn}"
]
}
]
})
}
module "hcvault_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "~> 3.0"
create_role = true
role_name = var.hcvault.role_name
provider_url = aws_eks_cluster.cluster.identity[0].oidc[0].issuer
role_policy_arns = [
aws_iam_policy.hcvault.arn
]
number_of_role_policy_arns = 1
}
kms.tf
Description
The kms.tf file contains data for the key management system. It unseals the HashiCorp Vault in configuration.
Definition
The file's default configuration is as follows:
# Create KMS CMK for this cluster
resource "aws_kms_key" "hcvault" {
description = var.hcvault.kms_key_description
tags = {
name = var.hcvault.kms_key_name
}
}
# Add an alias to the key
resource "aws_kms_alias" "hcvault" {
name = "alias/${var.hcvault.kms_alias_name}"
target_key_id = aws_kms_key.hcvault.key_id
}
locals.tf
The locals.tf puts credentials for Cogility repos in an EC2 boot script.
Note
Contact Cogility for a default version of the file.
main.tf
Description
The main.tf file defines the AWS EKS cluster composition, along with launch templates for nodes, groups, and add-ons.
Sample Code
resource "aws_eks_cluster" "cluster" {
name = var.cluster.name
version = var.cluster.version
role_arn = aws_iam_role.master_role.arn
vpc_config {
subnet_ids = var.network.subnet_ids
endpoint_private_access = true
endpoint_public_access = var.cluster.endpoint_public_access
security_group_ids = [aws_security_group.sg.id]
}
enabled_cluster_log_types = [
"api",
"audit",
"authenticator",
"controllerManager",
"scheduler",
]
tags = var.tags
}
###############
## Workers
###############
resource "aws_launch_template" "worker" {
name = local.worker_node.launch_template_name
tags = var.tags
image_id = local.ami_image_id
user_data = base64encode(local.userdata)
vpc_security_group_ids = [aws_security_group.sg.id]
ebs_optimized = true
block_device_mappings {
device_name = local.worker_node.block_device_name
ebs {
volume_type = local.worker_node.ephemeral_volume_type
volume_size = local.worker_node.ephemeral_volume_size
throughput = local.worker_node.ephemeral_volume_throughput
iops = local.worker_node.ephemeral_volume_iops
}
}
tag_specifications {
resource_type = "instance"
tags = {
Name = local.worker_node.launch_template_name
}
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_eks_node_group" "worker" {
cluster_name = aws_eks_cluster.cluster.name
node_group_name = local.worker_node.node_group_name
node_role_arn = aws_iam_role.worker_role.arn
subnet_ids = var.network.single_az == true ? split(",", var.network.subnet_ids[0]) : var.network.subnet_ids
instance_types = [local.worker_node.instance_type]
tags = var.tags
scaling_config {
desired_size = local.worker_node.scaling_min_size
max_size = local.worker_node.scaling_max_size
min_size = local.worker_node.scaling_min_size
}
labels = {
"px/enabled" = "false"
"k8s.cogynt.io/node" = "worker"
}
launch_template {
name = aws_launch_template.worker.name
version = aws_launch_template.worker.latest_version
}
lifecycle {
ignore_changes = [scaling_config[0].desired_size]
}
timeouts {}
depends_on = [
aws_iam_role_policy_attachment.worker-AmazonEKSWorkerNodePolicy,
aws_iam_role_policy_attachment.worker-AmazonEKS_CNI_Policy,
aws_iam_role_policy_attachment.worker-AmazonEC2ContainerRegistryReadOnly,
]
}
###############
## Storage
###############
resource "aws_launch_template" "storage" {
name = local.storage_node.launch_template_name
tags = var.tags
image_id = local.ami_image_id
user_data = base64encode(local.userdata)
vpc_security_group_ids = [aws_security_group.sg.id]
block_device_mappings {
device_name = local.storage_node.block_device_name
ebs {
volume_type = local.storage_node.ephemeral_volume_type
volume_size = local.storage_node.ephemeral_volume_size
throughput = local.storage_node.ephemeral_volume_throughput
iops = local.storage_node.ephemeral_volume_iops
}
}
tag_specifications {
resource_type = "instance"
tags = {
Name = local.storage_node.launch_template_name
}
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_eks_node_group" "storage" {
cluster_name = aws_eks_cluster.cluster.name
node_group_name = local.storage_node.node_group_name
node_role_arn = aws_iam_role.storage_role.arn
subnet_ids = var.network.single_az == true ? split(",", var.network.subnet_ids[0]) : var.network.subnet_ids
instance_types = [local.storage_node.instance_type]
tags = merge({"k8s.io/cluster-autoscaler/enabled" : "false"},var.tags)
scaling_config {
desired_size = local.storage_node.scaling_size
max_size = local.storage_node.scaling_size
min_size = local.storage_node.scaling_size
}
labels = {
"px/enabled" = "true",
"k8s.cogynt.io/node" = "storage"
}
launch_template {
name = aws_launch_template.storage.name
version = aws_launch_template.storage.latest_version
}
lifecycle {
ignore_changes = [scaling_config[0].desired_size]
}
timeouts {}
depends_on = [
aws_iam_role_policy_attachment.storage-AmazonEKSWorkerNodePolicy,
aws_iam_role_policy_attachment.storage-AmazonEKS_CNI_Policy,
aws_iam_role_policy_attachment.storage-AmazonEC2ContainerRegistryReadOnly,
]
}
resource "aws_eks_addon" "vpc-cni" {
depends_on = [aws_eks_node_group.storage]
cluster_name = data.aws_eks_cluster.cluster.name
addon_name = "vpc-cni"
}
resource "aws_eks_addon" "kube-proxy" {
depends_on = [aws_eks_node_group.storage]
cluster_name = data.aws_eks_cluster.cluster.name
addon_name = "kube-proxy"
}
resource "aws_eks_addon" "coredns" {
depends_on = [aws_eks_node_group.storage]
cluster_name = data.aws_eks_cluster.cluster.name
addon_name = "coredns"
}
s3.tf
Description
The s3.tf file creates directories in a bucket that Cogility scripts externally establish.
Sample Code
resource "aws_s3_object" "s3_cluster_folder" {
bucket = var.s3_data.bucket
key = "${var.cluster.name}/"
content = ""
}
resource "aws_s3_object" "s3_cluster_folder_druid" {
bucket = var.s3_data.bucket
key = "${var.cluster.name}/druid/"
content = ""
}
resource "aws_s3_object" "s3_cluster_folder_flink" {
bucket = var.s3_data.bucket
key = "${var.cluster.name}/flink/"
content = ""
}
resource "aws_s3_object" "s3_cluster_folder_kafka" {
bucket = var.s3_data.bucket
key = "${var.cluster.name}/kafka/"
content = ""
}
resource "aws_s3_object" "s3_cluster_folder_workstation" {
bucket = var.s3_data.bucket
key = "${var.cluster.name}/workstation/"
content = ""
}
sg.tf
Description
The sg.tf file defines the security group rules.
Sample Code
resource "aws_security_group" "sg" {
name = var.network.security_group_name
description = var.network.security_group_description
vpc_id = var.network.vpc_id
ingress = [
{
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = var.network.vpc_cidr_blocks
description = "EKS cluster VPC cidr"
ipv6_cidr_blocks = null
prefix_list_ids = null
self = null
security_groups = null
},
{
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["172.20.0.0/16"]
description = "EKS cluster internal cidr"
ipv6_cidr_blocks = null
prefix_list_ids = null
self = null
security_groups = null
},
{
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = [var.network.vpn_cidr_block]
description = "VPN CIDR block"
ipv6_cidr_blocks = null
prefix_list_ids = null
self = null
security_groups = null
},
]
egress = [
{
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
description = null
ipv6_cidr_blocks = null
prefix_list_ids = null
self = null
security_groups = null
}
]
}
variables.tf
Description
The variables.tf file is a Terraform-specific item that helps navigate the other Terraform files in the repository. It contains the definitions of variables to use in other scripts.
Sample Code
data "aws_caller_identity" "current" {}
data "aws_route53_zone" "this" {
count = var.hosted_zone.name != "" ? 1 : 0
name = var.hosted_zone.name
private_zone = var.hosted_zone.type == "Private" ? true : false
}
data "aws_eks_cluster" "cluster" {
name = aws_eks_cluster.cluster.name
}
data "aws_ami" "eks" {
owners = ["amazon"]
most_recent = true
name_regex = "^amazon-eks-node-${var.cluster.version}-v\\d{8}$"
filter {
name = "name"
values = ["amazon-eks-node-${var.cluster.version}-*"]
}
}
variable "ami_image_id" {
type = string
description = "ID for the AMI"
default = ""
}
variable "aws_partition" {
type = string
description = "The AWS partition in which the resource is located."
default = "aws"
}
variable "user_data" {
type = string
description = "User Data to include in the nodes"
default = ""
}
variable "cluster" {
type = object({
name = string
version = optional(string)
endpoint_public_access = optional(bool)
})
description = "EKS cluster details"
}
variable "hosted_zone" {
type = object({
name = string
type = string
})
validation {
condition = var.hosted_zone.type == "Private" || var.hosted_zone.type == "Public"
error_message = "DNS Hosted Zone type can only be either Private or Public."
}
}
variable "network" {
type = object({
vpc_id = string
vpc_cidr_blocks = list(string)
single_az = optional(bool)
subnet_ids = list(string)
security_group_name = optional(string)
security_group_description = optional(string)
vpn_cidr_block = optional(string)
egress_cidr_block = optional(string)
})
description = "EKS cluster network details."
}
variable "master_node" {
type = object({
role_name = optional(string)
role_description = optional(string)
inline_policy_name = optional(string)
instance_profile_name = optional(string)
})
description = "Master EKS Node details for roles & policies."
}
variable "worker_node" {
type = object({
instance_type = optional(string)
launch_template_name = optional(string)
node_group_name = optional(string)
scaling_min_size = optional(number)
scaling_max_size = optional(number)
block_device_name = optional(string)
ephemeral_volume_type = optional(string)
ephemeral_volume_size = optional(number)
ephemeral_volume_iops = optional(number)
ephemeral_volume_throughput = optional(number)
role_name = optional(string)
role_description = optional(string)
inline_policy_name = optional(string)
instance_profile_name = optional(string)
additional_policy_arn_attachments = optional(set(string))
})
description = "Worker EKS Node details for launch template, role, policy, & EKS node groups."
}
variable "storage_node" {
type = object({
instance_type = optional(string)
launch_template_name = optional(string)
node_group_name = optional(string)
scaling_size = optional(number)
block_device_name = optional(string)
ephemeral_volume_type = optional(string)
ephemeral_volume_size = optional(number)
ephemeral_volume_iops = optional(number)
ephemeral_volume_throughput = optional(number)
role_name = optional(string)
role_description = optional(string)
inline_policy_name = optional(string)
portworx_inline_policy_name = optional(string)
instance_profile_name = optional(string)
})
description = "Storage EKS Node details for launch template, role, policy, & EKS node groups."
}
variable "externaldns" {
type = object({
role_name = string
policy_name = string
policy_description = string
})
description = "Name and descriptions of the role & policy used for ExternalDNS."
}
variable "istio" {
type = object({
role_name = string
policy_name = string
policy_description = string
})
description = "Name and descriptions of the role & policy used for Istio."
}
variable "s3_data" {
type = object({
bucket = string
role_name = string
policy_name = string
policy_description = string
})
description = "Name and descriptions of the bucket, role, & policy used for S3 data."
}
variable "hcvault" {
type = object({
role_name = string
policy_name = string
policy_description = string
kms_key_name = string
kms_key_description = string
kms_alias_name = string
})
description = "Name and descriptions of the kms, role, & policy used for Hashicorp Vault."
}
variable "tags" {
type = map(string)
description = "Tags to use globally on resources."
}
versions.tf
Description
The versions.tf file is a Terraform-specific item that helps navigate the other Terraform files in the repository. It contains some of the base-level configuration needed for the rest of the scripts to work. The backend and list of required providers are contained in this file.
Sample Code
terraform {
required_version = ">= 1.0"
experiments = [module_variable_optional_attrs]
required_providers {
aws = {
source = "hashicorp/aws"
version = "4.19.0"
}
tls = {
source = "hashicorp/tls"
version = "3.4.0"
}
}
}
ia Directory Contents
The ia directory contains the following files.
ia.env.yaml
The ia.env.yaml file is not a Terraform file. It defines the configuration for the Cogynt Delivery Tool.
For more information, see Configuring the Cogynt Delivery Tool.
main.tf
The main.tf file creates modules using abstractions from other files. Common variables are abstracted in this file to make editing configurations easier.
outputs.tf
The outputs.tf file contains the variables that should display their values at the end of a Terraform apply in the terminal.
variables.tf
The variables.tf file is a Terraform-specific item that helps navigate the other Terraform files in the repository. It contains the definitions of variables to use in other scripts.
vars.auto.tfvars
The vars.auto.tfvars file contains the values of the variables to use in other scripts.
Customers may want to review this file if they want to use values other than the Cogility defaults.
versions.tf
The versions.tf file is a Terraform-specific item that helps navigate the other Terraform files in the repository. It contains some of the base-level configuration needed for the rest of the scripts to work. The backend and list of required providers are contained in this file.
Customers may want to review this file, as it determines where Terraform stores its state.