Source code for runway.blueprints.k8s.k8s_master

#!/usr/bin/env python
"""Module with k8s cluster resources."""
from __future__ import print_function

import awacs.iam
from awacs.aws import StringLike  # pylint: disable=no-name-in-module
from awacs.aws import Allow, Condition, PolicyDocument, Statement
from awacs.helpers.trust import make_simple_assume_policy
from troposphere import Export, Join, Output, Sub, ec2, eks, iam

from runway.cfngin.blueprints.base import Blueprint
from runway.cfngin.blueprints.variables.types import (
    CFNString,
    EC2SubnetIdList,
    EC2VPCId,
)

IAM_POLICY_ARN_PREFIX = "arn:aws:iam::aws:policy/"


[docs]class Cluster(Blueprint): """Stacker blueprint for creating k8s cluster resources.""" VARIABLES = { "EksClusterName": { "type": CFNString, "description": "Name of the Kubernetes cluster", "min_length": 2, "max_length": 40, }, "EksSubnets": { "type": EC2SubnetIdList, "description": "Subnets where the Kubernetes cluster " "will live", }, "EksVersion": {"type": CFNString, "description": "Kubernetes version"}, "VPC": { "type": EC2VPCId, "description": "VPC where the Kubernetes cluster will live", }, }
[docs] def create_template(self): """Create template (main function called by Stacker).""" template = self.template variables = self.get_variables() template.add_version("2010-09-09") template.add_description("Kubernetes Master via EKS - V1.0.0") # Resources ccpsecuritygroup = template.add_resource( ec2.SecurityGroup( "ClusterControlPlaneSecurityGroup", GroupDescription="Cluster communication with worker nodes", Tags=[ { "Key": Sub("kubernetes.io/cluster/${EksClusterName}"), "Value": "owned", }, {"Key": "Product", "Value": "Kubernetes"}, {"Key": "Project", "Value": "eks"}, {"Key": "Name", "Value": Sub("${EksClusterName}-sg-worker-nodes")}, ], VpcId=variables["VPC"].ref, ) ) template.add_output( Output( ccpsecuritygroup.title, Description="Cluster communication with worker nodes", Export=Export(Sub("${AWS::StackName}-ControlPlaneSecurityGroup")), Value=ccpsecuritygroup.ref(), ) ) eksservicerole = template.add_resource( iam.Role( "EksServiceRole", AssumeRolePolicyDocument=make_simple_assume_policy("eks.amazonaws.com"), ManagedPolicyArns=[IAM_POLICY_ARN_PREFIX + "AmazonEKSClusterPolicy"], Policies=[ iam.Policy( PolicyName="EksServiceRolePolicy", PolicyDocument=PolicyDocument( Statement=[ Statement( Action=[ awacs.iam.CreateServiceLinkedRole, awacs.iam.PutRolePolicy, ], Condition=Condition( StringLike( "iam:AWSServiceName", "elasticloadbalancing.amazonaws.com", ) ), Effect=Allow, Resource=[ Sub( "arn:aws:iam::${AWS::AccountId}:role/" "aws-service-role/" "elasticloadbalancing.amazonaws.com/" "AWSServiceRoleForElasticLoadBalancing*" ) ], ) ] ), ) ], ) ) ekscluster = template.add_resource( eks.Cluster( "EksCluster", Name=variables["EksClusterName"].ref, Version=variables["EksVersion"].ref, RoleArn=eksservicerole.get_att("Arn"), ResourcesVpcConfig=eks.ResourcesVpcConfig( SecurityGroupIds=[ccpsecuritygroup.ref()], SubnetIds=variables["EksSubnets"].ref, ), ) ) template.add_output( Output( "%sName" % ekscluster.title, Description="EKS Cluster Name", Export=Export(Sub("${AWS::StackName}-%sName" % ekscluster.title)), Value=ekscluster.ref(), ) ) template.add_output( Output( "%sEndpoint" % ekscluster.title, Description="EKS Cluster Endpoint", Export=Export(Sub("${AWS::StackName}-%sEndpoint" % ekscluster.title)), Value=ekscluster.get_att("Endpoint"), ) ) # Additional Outputs template.add_output( Output( "VpcId", Description="EKS Cluster VPC Id", Export=Export(Sub("${AWS::StackName}-VpcId")), Value=variables["VPC"].ref, ) ) template.add_output( Output( "Subnets", Description="EKS Cluster Subnets", Export=Export(Sub("${AWS::StackName}-Subnets")), Value=Join(",", variables["EksSubnets"].ref), ) )
# Helper section to enable easy blueprint -> template generation # (just run `python <thisfile>` to output the json) if __name__ == "__main__": from runway.cfngin.context import Context print(Cluster("test", Context({"namespace": "test"}), None).to_json())