diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d4585e..5987854 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,3 +33,7 @@ * 0.0.22 -- 2022-02-22 - code 0.0.13 - fix typo + +* 0.0.23 -- 2022-02-22 + - code 0.1.0 + - add heritage TXT record support diff --git a/README.md b/README.md index 8c069fc..1e3c14d 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ No modules. | [component\_tags](#input\_component\_tags) | Additional tags for Components (s3, kms, ddb) | `map(map(string))` |
{
"ddb": {},
"kms": {},
"s3": {}
} | no |
| [create](#input\_create) | Flag to indicate whether to create the resources or not (default: true) | `bool` | `true` | no |
| [dynamodb\_table\_name](#input\_dynamodb\_table\_name) | Different DynamoDB table name to override default of var.name) | `string` | `null` | no |
-| [lambda\_environment\_variables](#input\_lambda\_environment\_variables) | Map of lambda environment variables and values | `map(string)` | {
"DNS_RR_TimeToLive": 60,
"DynamoDBName": null,
"SleepTime": 60,
"TagKeyCname": "boc:dns:cname",
"TagKeyHostName": "boc:dns:name",
"TagKeyZone": "boc:dns:zone"
} | no |
+| [lambda\_environment\_variables](#input\_lambda\_environment\_variables) | Map of lambda environment variables and values | `map(string)` | {
"DNS_RR_TimeToLive": 60,
"DynamoDBName": null,
"HeritageIdentifier": "dynr53",
"HeritageTXTRecordPrefix": "_txt",
"SleepTime": 60,
"TagKeyCname": "boc:dns:cname",
"TagKeyHostName": "boc:dns:name",
"TagKeyZone": "boc:dns:zone"
} | no |
| [lambda\_name](#input\_lambda\_name) | Different Lambda name to override default of var.name) | `string` | `null` | no |
| [name](#input\_name) | Name to use within all the created resources (default: inf-dynamic-route53) | `string` | `"inf-dynamic-route53"` | no |
| [override\_prefixes](#input\_override\_prefixes) | Override built-in prefixes by component. This should be used primarily for common infrastructure things | `map(string)` | `{}` | no |
diff --git a/code/ddns-lambda.py b/code/ddns-lambda.py
index 309f630..76c7559 100755
--- a/code/ddns-lambda.py
+++ b/code/ddns-lambda.py
@@ -72,7 +72,7 @@
LOGGER = logging.getLogger()
ACCOUNT = None
REGION = None
-VERSION = '0.0.13'
+VERSION = '0.1.0'
# Adjust the logging level [logging.INFO, logging.DEBUG, logging.WARNING, etc]
LOGGER.setLevel(logging.DEBUG)
@@ -86,6 +86,9 @@
DNS_RR_TTL = int(os.environ.get('DNS_RR_TimeToLive', '60'))
DNS_RR_TTL = 60 if DNS_RR_TTL == 0 else DNS_RR_TTL
TF_MODULE_VERSION = os.environ.get('tf_module_version', '(unknown)')
+# for CNAMEs
+TXT_RR_PREFIX = os.environ.get('HeritageTXTRecordPrefix', '_txt')
+HERITAGE_TAG = os.environ.get('HeritageIdentifier', 'dynr53')
print('Loading function v{} tf_module_version {}: {}'.format(
VERSION, TF_MODULE_VERSION, datetime.datetime.now().time().isoformat()))
@@ -132,12 +135,25 @@ def get_dynamodb_client():
print("Unexpected error: %s" % err)
+def get_caller_account_id():
+ """
+ Get AWS Account ID from STS
+ :return str: AWS Account ID
+ """
+ try:
+ return boto3.client('sts').get_caller_identity()['Account'])
+ except ClientError as err:
+ print("Unexpected error: %s" % err)
+
+
def lambda_handler(
event,
context,
- dynamodb_client=get_dynamodb_client(),
- compute=get_ec2_client(),
- route53=get_route53_client()
+ dynamodb_client = get_dynamodb_client(),
+ compute = get_ec2_client(),
+ route53 = get_route53_client()
+
+
):
"""
Check to see whether a DynamoDB table already exists. If not, create it.
@@ -155,9 +171,9 @@ def lambda_handler(
LOGGER.info("event: %s", str(event) + lineno())
LOGGER.info("context: %s", str(context) + lineno())
- caller_response = []
+ caller_response=[]
# Checking to make sure there is a dynamodb table named in the Env Variable
- tables = list_tables(dynamodb_client)
+ tables=list_tables(dynamodb_client)
LOGGER.info("tables: %s", str(tables))
if DDBNAME in tables['TableNames']:
@@ -168,21 +184,23 @@ def lambda_handler(
# Set variables
# Get the state from the Event stream
- state = event['detail']['state']
+ state=event['detail']['state']
LOGGER.debug("instance state: %s", str(state) + lineno())
# Get the instance id, region, and tag collection
- instance_id = event['detail']['instance-id']
+ instance_id=event['detail']['instance-id']
LOGGER.debug("instance id: %s", str(instance_id) + lineno())
- region = event['region']
+ region=event['region']
LOGGER.debug("region: %s", str(region) + lineno())
+ account_id=get_caller_account_id()
+ LOGGER.debug("account_id: %s", str(account_id) + lineno())
# Only doing something if the state is running
if state == 'running':
LOGGER.debug("sleeping for maximum {} seconds {}".format(SLEEPTIME, lineno()))
# wait increment and wait until maximum sleeptime
- i = 1
+ i=1
while i < SLEEPTIME:
LOGGER.debug("waiting count: %s", str(i) + lineno())
time.sleep(1)
@@ -190,12 +208,12 @@ def lambda_handler(
try:
# Get instance information
- instance = get_instances(compute, instance_id)
+ instance=get_instances(compute, instance_id)
- t_private_ip = instance['Reservations'][0]['Instances'][0]['PrivateIpAddress']
- t_private_dns_name = instance['Reservations'][0]['Instances'][0]['PrivateDnsName']
- t_subnet_id = instance['Reservations'][0]['Instances'][0]['SubnetId']
- t_vpc_id = instance['Reservations'][0]['Instances'][0]['VpcId']
+ t_private_ip=instance['Reservations'][0]['Instances'][0]['PrivateIpAddress']
+ t_private_dns_name=instance['Reservations'][0]['Instances'][0]['PrivateDnsName']
+ t_subnet_id=instance['Reservations'][0]['Instances'][0]['SubnetId']
+ t_vpc_id=instance['Reservations'][0]['Instances'][0]['VpcId']
# if key attributes are found, then break out of the loop
if all([t_private_ip, t_private_dns_name, t_subnet_id, t_vpc_id]):
@@ -211,9 +229,9 @@ def lambda_handler(
# Remove null values from the response. You cannot save a dict/JSON
# document in DynamoDB if it contains null values
LOGGER.debug("instance: %s", str(instance) + lineno())
- instance = remove_empty_from_dict(instance)
- instance_dump = json.dumps(instance, default=json_serial)
- instance_attributes = json.loads(instance_dump)
+ instance=remove_empty_from_dict(instance)
+ instance_dump=json.dumps(instance, default = json_serial)
+ instance_attributes=json.loads(instance_dump)
LOGGER.debug("instance_attributes: %s", str(instance_attributes) + lineno())
LOGGER.debug("trying to put instance information in "
"dynamo table %s", str(instance_attributes) + lineno())
@@ -586,6 +604,17 @@ def lambda_handler(
LOGGER.debug("valid_dns_zones:"
" %s", str(valid_dns_zones) + lineno())
+ # create the TXT heritage record
+ heritage = initialize_heritage(HERITAGE_TAG,VERSION,
+ {
+ 'instance_id': instance_id,
+ 'account_id': account_id,
+ 'region': region
+ } )
+ add_heritage_item_timestamp(heritage,'create_time')
+ heritage_value = format_heritage(heritage)
+# txt=format_heritage(h)
+
# Create OR Delete the A / PTR Record
if state == 'running':
# create the records
@@ -608,6 +637,25 @@ def lambda_handler(
' with value: ' +
str(private_ip))
+ if len(heritage)>0:
+ LOGGER.debug("Creating heritage TXT resource records %s", lineno())
+ create_resource_record(
+ route53,
+ final_hosted_zone_id,
+ final_private_hostname,
+ final_hosted_zone_name,
+ 'TXT',
+ heritage_value
+ )
+
+ caller_response.append('Created TXT record in zone id: ' +
+ str(final_hosted_zone_id) +
+ ' for hosted zone ' +
+ str(final_private_hostname) + '.' +
+ str(final_hosted_zone_name) +
+ ' with value: ' +
+ str(heritage_value))
+
if reverse_zone_associated:
create_resource_record(
route53,
@@ -625,6 +673,24 @@ def lambda_handler(
'in-addr.arpa with value: ' +
str(final_private_dns_name))
+ if len(heritage)>0:
+ create_resource_record(
+ route53,
+ reverse_lookup_zone_id,
+ reversed_ip_address,
+ 'in-addr.arpa',
+ 'TXT',
+ heritage_value
+ )
+
+ caller_response.append('Created TXT reverse record in zone id: ' +
+ str(reverse_lookup_zone_id) +
+ ' for hosted zone ' +
+ str(reversed_ip_address) +
+ 'in-addr.arpa with value: ' +
+ str(heritage_value))
+
+
except BaseException as err:
LOGGER.info("unexpected error. %s\n", str(err) + lineno())
@@ -650,6 +716,26 @@ def lambda_handler(
' with value: ' +
str(private_ip))
+ if len(heritage)>0:
+ # pause 1 before deleting to avoid API limit
+ time.sleep(1)
+ delete_resource_record(
+ route53,
+ final_hosted_zone_id,
+ final_private_hostname,
+ final_hosted_zone_name,
+ 'TXT',
+ heritage_value
+ )
+
+ caller_response.append('Deleted TXT record in zone id: ' +
+ str(final_hosted_zone_id) +
+ ' for hosted zone ' +
+ str(final_private_hostname) + '.' +
+ str(final_hosted_zone_name) +
+ ' with value: ' +
+ str(heritage_value))
+
# pause 1 before deleting to avoid API limit
time.sleep(1)
delete_resource_record(
@@ -669,6 +755,26 @@ def lambda_handler(
' with value: ' +
str(final_private_dns_name))
+ if len(heritage)>0:
+ # pause 1 before deleting to avoid API limit
+ time.sleep(1)
+ delete_resource_record(
+ route53,
+ reverse_lookup_zone_id,
+ reversed_ip_address,
+ 'in-addr.arpa',
+ 'TXT',
+ heritage_value
+ )
+
+ caller_response.append('Deleted PTR record in zone id: ' +
+ str(reverse_lookup_zone_id) +
+ ' for hosted zone ' +
+ str(reversed_ip_address) +
+ str(private_dns_name) +
+ ' with value: ' +
+ str(heritage_value))
+
except BaseException as err:
LOGGER.debug("%s", str(err) + lineno())
@@ -708,6 +814,25 @@ def lambda_handler(
' with value: ' +
str(final_private_dns_name))
+ if len(heritage)>0:
+ create_resource_record(
+ route53,
+ cname_domain_suffix_id,
+ TXT_RR_PREFIX + '.' + cname_host_name,
+ cname_domain_suffix,
+ 'TXT',
+ heritage_value
+ )
+
+ caller_response.append('Created TXT for CNAME record in zone id: ' +
+ str(cname_domain_suffix_id) +
+ ' for hosted zone ' +
+ str(TXT_RR_PREFIX) + '.' +
+ str(cname_host_name) + '.' +
+ str(cname_domain_suffix) +
+ ' with value: ' +
+ str(heritage_value))
+
except BaseException as err:
LOGGER.debug("%s", str(err) + lineno())
else:
@@ -733,6 +858,25 @@ def lambda_handler(
' with value: ' +
str(final_private_dns_name))
+ if len(heritage)>0:
+ delete_resource_record(
+ route53,
+ cname_domain_suffix_id,
+ TXT_RR_PREFIX + '.' + cname_host_name,
+ cname_domain_suffix,
+ 'TXT',
+ heritage_value
+ )
+
+ caller_response.append('Deleted TXT for CNAME record in zone id: ' +
+ str(cname_domain_suffix_id) +
+ ' for hosted zone ' +
+ str(TXT_RR_PREFIX) + '.' +
+ str(cname_host_name) + '.' +
+ str(cname_domain_suffix) +
+ ' with value: ' +
+ str(heritage_value))
+
except BaseException as err:
LOGGER.debug("%s", str(err) + lineno())
diff --git a/code/ddns-lambda.zip b/code/ddns-lambda.zip
index ba3ca7c..157de09 100644
Binary files a/code/ddns-lambda.zip and b/code/ddns-lambda.zip differ
diff --git a/variables.tf b/variables.tf
index afb4945..060eafb 100644
--- a/variables.tf
+++ b/variables.tf
@@ -20,11 +20,13 @@ variable "lambda_environment_variables" {
description = "Map of lambda environment variables and values"
type = map(string)
default = {
- SleepTime = 60
- DynamoDBName = null
- TagKeyCname = "boc:dns:cname"
- TagKeyZone = "boc:dns:zone"
- TagKeyHostName = "boc:dns:name"
- DNS_RR_TimeToLive = 60
+ SleepTime = 60
+ DynamoDBName = null
+ TagKeyCname = "boc:dns:cname"
+ TagKeyZone = "boc:dns:zone"
+ TagKeyHostName = "boc:dns:name"
+ DNS_RR_TimeToLive = 60
+ HeritageTXTRecordPrefix = "_txt"
+ HeritageIdentifier = "dynr53"
}
}
diff --git a/version.tf b/version.tf
index ac63989..4c5fed3 100644
--- a/version.tf
+++ b/version.tf
@@ -1,3 +1,3 @@
locals {
- _module_version = "0.0.22"
+ _module_version = "0.0.23"
}