Skip to content

Instantly share code, notes, and snippets.

@otterley
Created June 17, 2020 04:36
Show Gist options
  • Save otterley/28d488df145d9b1e54d7d17b0aa2b8dc to your computer and use it in GitHub Desktop.
Save otterley/28d488df145d9b1e54d7d17b0aa2b8dc to your computer and use it in GitHub Desktop.
Lambda function for propagating EKS managed nodegroup tags
#!/usr/bin/env python
import boto3
import botocore.exceptions
import logging
from time import sleep
MAX_ATTEMPTS = 100
def handler(event, context):
detail = event['detail']
if detail['eventSource'] != 'eks.amazonaws.com' or detail['eventName'] != 'CreateNodegroup':
print('Received event {} from {} - skipping'.format(detail['eventSource'], detail['eventName']))
return
cluster_name = detail['requestParameters']['name']
nodegroup = detail['responseElements']['nodegroup']
nodegroup_name = nodegroup['nodegroupName']
nodegroup_tags = nodegroup['tags']
eks = boto3.client('eks')
autoscaling = boto3.client('autoscaling')
ec2 = boto3.client('ec2')
print('[{}] Waiting for nodegroup {}'.format(cluster_name, nodegroup_name))
attempts = 0
autoscaling_group_name = None
while not autoscaling_group_name:
attempts = attempts + 1
if attempts > MAX_ATTEMPTS:
raise TimeoutError('[{}] Timed out waiting to obtain Auto Scaling Group Name for nodegroup {}'.format(cluster_name, nodegroup_name))
try:
response = eks.describe_nodegroup(
clusterName=cluster_name,
nodegroupName=nodegroup_name
)
status = response['nodegroup']['status']
if status == 'DELETING':
print('[{}] Nodegroup {} is {}'.format(cluster_name, nodegroup_name, status))
return
elif status == 'CREATING':
sleep(5)
continue
elif status == 'ACTIVE':
autoscaling_group_name = response['nodegroup']['resources']['autoScalingGroups'][0]['name']
break
else:
raise ValueError('[{}] Unknown nodegroup status: {} is {}'.format(cluster_name, nodegroup_name, status))
except KeyError:
sleep(5)
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == 'ResourceNotFoundException':
sleep(5)
else:
raise
print('[{}] Tagging Auto Scaling Group {}'.format(cluster_name, autoscaling_group_name))
autoscaling.create_or_update_tags(Tags=[
{
'ResourceId': autoscaling_group_name,
'ResourceType': 'auto-scaling-group',
'Key': tag_key,
'Value': tag_value,
'PropagateAtLaunch': True,
}
for (tag_key, tag_value) in nodegroup_tags.items() if not tag_key.startswith('aws:')])
print('[{}] Tagging running instances in Auto Scaling Group {}'.format(cluster_name, autoscaling_group_name))
response = autoscaling.describe_auto_scaling_groups(
AutoScalingGroupNames=[autoscaling_group_name]
)
instance_ids = [i['InstanceId'] for i in response['AutoScalingGroups'][0]['Instances']]
ec2.create_tags(
Resources=instance_ids,
Tags=[{
'Key': tag_key,
'Value': tag_value,
} for (tag_key, tag_value) in nodegroup_tags.items() if not tag_key.startswith('aws:')]
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment