Skip to content

Commit

Permalink
Add EksPublicAccessCidrs parameter and enable EKS control plane loggi…
Browse files Browse the repository at this point in the history
…ng (#117)

* add EKS public_access_cidrs

* enable api, audit, and authenticator EKS control plane logging

* update changelog

* allow bastion access to Kubernetes API endpoint

* use eks.LaunchTemplateSpecification to enforce HttpTokens-based metadata

* update changelog

* set HttpPutResponseHopLimit=3
  • Loading branch information
copelco authored Apr 25, 2023
1 parent d6382ec commit b8c8fc0
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 6 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ Change Log
* Add ``EksClusterName`` parameter to control name of EKS cluster. If upgrading, set this to STACK_NAME-cluster to match existing name.
* Drop support for RDS PostgreSQL 9.x
* Upgrade to troposphere v4.2.0

* Add ``EksPublicAccessCidrs`` parameter to optionally restrict access to your public Kubernetes API endpoint using CIDR blocks. If defined, both public and private endpoint access enabled as detailed in `API server endpoint access options <https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html#modify-endpoint-access>`_.
* Enable ``api``, ``audit``, and ``authenticator`` log types for `EKS control plane logging <https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html>`_.
* Allow bastion access to Kubernetes API endpoint
* Add ``eks.LaunchTemplateSpecification`` to enforce `HttpTokens-based metadata <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html>`_

`2.1.2`_ (2022-03-10)
---------------------
Expand Down
12 changes: 12 additions & 0 deletions stack/bastion.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,18 @@
if USE_EKS:
from .eks import cluster
backend_server_id = GetAtt(cluster, "ClusterSecurityGroupId")
# Allow bastion access to Kubernetes API endpoint
container_security_group_k8s_ingress = ec2.SecurityGroupIngress(
'ContainerSecurityGroupKubernetesBastionIngress',
template=template,
GroupId=backend_server_id,
IpProtocol='tcp',
FromPort=443,
ToPort=443,
SourceSecurityGroupId=Ref(bastion_security_group),
Condition=bastion_type_set,
Description="Kubernetes API endpoint",
)
else:
from .security_groups import container_security_group
backend_server_id = Ref(container_security_group)
Expand Down
63 changes: 58 additions & 5 deletions stack/eks.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
iam
)

from .common import cmk_arn
from .common import cmk_arn, use_aes256_encryption, use_cmk_arn
from .containers import (
container_instance_role,
container_instance_type,
Expand Down Expand Up @@ -69,7 +69,7 @@
AllowedValues=["true", "false"],
Default="false",
),
group="Global",
group="Elastic Kubernetes Service (EKS)",
label="Enable EKS EncryptionConfig",
))
use_eks_encryption_config_cond = "EnableEksEncryptionConfigCond"
Expand All @@ -78,6 +78,20 @@
Not(Equals(Ref(cmk_arn), ""))
))

# https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html#modify-endpoint-access
public_access_cidrs = Ref(template.add_parameter(
Parameter(
"EksPublicAccessCidrs",
Description="The CIDR blocks that are allowed access to your cluster's public Kubernetes API server endpoint.", # noqa
Type="CommaDelimitedList",
Default="",
),
group="Elastic Kubernetes Service (EKS)",
label="Kubernetes API public access CIDRs",
))
restrict_eks_api_access_cond = "RestrictEksApiAccessCond"
template.add_condition(restrict_eks_api_access_cond, Not(Equals(Join("", public_access_cidrs), "")))

# Unlike most other resources in the stack, we specify the cluster name
# via a stack parameter so it's easy to find and so it cannot be accidentally
# recreated (for example if the ResourcesVpcConfig is changed).
Expand All @@ -87,14 +101,23 @@
Description="The unique name to give to your cluster.", # noqa
Type="String",
),
group="Global",
group="Elastic Kubernetes Service (EKS)",
label="Cluster name",
))

cluster = eks.Cluster(
"EksCluster",
template=template,
Name=cluster_name,
Logging=eks.Logging(
ClusterLogging=eks.ClusterLogging(
EnabledTypes=[
eks.LoggingTypeConfig(Type="api"),
eks.LoggingTypeConfig(Type="audit"),
eks.LoggingTypeConfig(Type="authenticator"),
]
)
),
ResourcesVpcConfig=eks.ResourcesVpcConfig(
SubnetIds=[
# For load balancers
Expand All @@ -105,6 +128,9 @@
Ref(private_subnet_b),
],
SecurityGroupIds=[Ref(eks_security_group)],
EndpointPrivateAccess=If(restrict_eks_api_access_cond, True, False),
EndpointPublicAccess=True,
PublicAccessCidrs=If(restrict_eks_api_access_cond, public_access_cidrs, NoValue),
),
EncryptionConfig=If(
use_eks_encryption_config_cond,
Expand All @@ -114,6 +140,32 @@
RoleArn=GetAtt(eks_service_role, "Arn"),
)

# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-launchtemplate.html
nodegroup_launch_template = ec2.LaunchTemplate(
"NodegroupLaunchTemplate",
template=template,
LaunchTemplateData=ec2.LaunchTemplateData(
BlockDeviceMappings=[
ec2.LaunchTemplateBlockDeviceMapping(
DeviceName="/dev/xvda",
Ebs=ec2.EBSBlockDevice(
DeleteOnTermination=True,
Encrypted=use_aes256_encryption,
KmsKeyId=If(use_cmk_arn, Ref(cmk_arn), Ref("AWS::NoValue")),
VolumeType="gp2",
VolumeSize=container_volume_size,
),
),
],
InstanceType=container_instance_type,
MetadataOptions=ec2.MetadataOptions(
HttpTokens="required",
# Why 3? See note: https://github.com/adamchainz/ec2-metadata#instance-metadata-service-version-2
HttpPutResponseHopLimit=3,
),
)
)

eks.Nodegroup(
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-nodegroup.html
"Nodegroup",
Expand All @@ -125,9 +177,10 @@
ClusterName=Ref(cluster),
# The NodeRole must be specified as an ARN.
NodeRole=GetAtt(container_instance_role, "Arn"),
LaunchTemplate=eks.LaunchTemplateSpecification(
Id=Ref(nodegroup_launch_template),
),
# The rest are optional.
DiskSize=container_volume_size,
InstanceTypes=[container_instance_type],
ScalingConfig=eks.ScalingConfig(
DesiredSize=desired_container_instances,
MaxSize=max_container_instances,
Expand Down

0 comments on commit b8c8fc0

Please sign in to comment.