AWS Config: Custom rule for required-tags says "no tags" even when "Name" tag exists - amazon-web-services

I have customised the managed rule - required-tags and modified the lambda function to extend upto 9 tags and more.
The code seems to work and gives me the expected result.
This rule checks for tags given in "Rule Parameters". Empty and partially tagged are non compliant; fully tagged are compliant.
The problem I face is when a new EC2 instance is created and the custom rule triggers with configuration changes gives me "no tags" even when "name" tag is present.
When I re-evaluate for the second time, the expected result is got (missing tags except name tag)
The condition goes like this
if evaluation["compliance_type"] == "NON_COMPLIANT":
print ("NON_COMPLIANT")
if len(evaluation["current_tags"]) > 0:
print ("Non zero tags")
// evaluation report
else:
print ("Zero tags")
// evaluation report
EC2 instance was laucnhed around 12:39 PM
Cloudwatch logs after automatic trigger(configuration changes) around 12:41 PM
{
'current_tags': [],
'compliance_type': 'NON_COMPLIANT',
'annotation': 'Name, Customer, Environment, etc not present'
}
Cloudwatch logs after manual re-evaluation around 12:43 PM
{
'current_tags': [{u'value': u'instance_name', u'key': u'Name'}],
'compliance_type': 'NON_COMPLIANT',
'annotation': 'Customer, Environment, etc not present'
}
The event payload passed to lambda function (trigger: configuration changes) at instance creation time has current_tags: empty (even though name tag is added during instance creation; exists). Is there a way to find out how and when the tags gets added to the instance. Or the trigger can be delayed (not periodic trigger)

Related

Filtering AWS SNS messages by attribute value but only if attribute is present

I would like to know how I can create a filtering policy for AWS SNS subscription that would check a message attribute value but only if that attribute is present. By default if I check an attribute value but attribute is not present message is ignored e.g:
"customer_interests": ["paintball"]
I also found this for attribute presence checking:
"customer_interests": [{"exists": true}]
But I'm not sure how to combine this two checks into a single policy.
I've tried the obvious thing:
{
"customer_interests": [{"exists": false}, "paintball"]
}
but it doesn't work.
i have tried the following thing ( your obvious thing ) and it worked for me, i didn't have to even wait for 15 minutes (clearly eventual consistency is not the issue )
Used the following policy
{
"customer_interests": [
{
"exists": false
},
"paintball"
]
}
Created a sns topic with email-based subscription
added filter policy to subscriber
tried with three use case
Case 1
message hello
attribute type string
atrribute name customer_interests
atrribute value paintball
status recieved
Case 3
message hello
attribute type string
atrribute name customer_interests
atrribute value xyz
status not recieved
Case 3
message hello
attribute type string
atrribute name jatin
atrribute value test
status recieved
You apply OR logic in SNS subscription filter policies, by assigning multiple values to an attribute name.
Your example:
{
"customer_interests": [{"exists": false}, "paintball"]
}
should result in filtering messages that:
do not have the customer_interests message attribute
OR have the customer_interests message attribute set to paintball
Please note that additions or changes to a subscription filter policy require up to 15 minutes to fully take effect, as Amazon SNS is eventually consistent.
Changes will not always take effect immediately.

GCP terraform - alerts module based on log metrics

As per subject, I have set up log based metrics for a platform in gcp i.e. firewall, audit, route etc. monitoring.
enter image description here
Now I need to setup alert policies tied to these log based metrics, which is easy enough to do manually in gcp.
enter image description here
However, I need to do it via terraform thus using this module:
https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/monitoring_alert_policy#nested_alert_strategy
I might be missing something very simple but finding it hard to understand this as the alert strategy is apparently required but yet does not seem to be supported?
I am also a bit confused on which kind of condition I should be using to match my already setup log based metric?
This is my module so far, PS. I have tried using the same filter as I did for setting up the log based metric as well as the name of the log based filter:
resource "google_monitoring_alert_policy" "alert_policy" {
display_name = var.display_name
combiner = "OR"
conditions {
display_name = var.display_name
condition_matched_log {
filter = var.filter
#duration = "600s"
#comparison = "COMPARISON_GT"
#threshold_value = 1
}
}
user_labels = {
foo = "bar"
}
}
var filter is:
resource.type="gce_route" AND (protoPayload.methodName:"compute.routes.delete" OR protoPayload.methodName:"compute.routes.insert")
Got this resolved in the end.
Turns out common issue:
https://issuetracker.google.com/issues/143436657?pli=1
Had to add this to the filter parameter in my terraform module after the metric name - AND resource.type="global"

CloudWatch auto alarm deletion executing multiple times

I have a piece of python script that is running in an AWS Lambda function that deletes a CloudWatch alarm when an EC2 instance is going to the Stopped state.
elif 'source' in event and event['source'] == 'aws.ec2' and event['detail']['state'] == 'stopped':
instanceID = event['detail']['instance-id']
GetAlarmNamePrefix = "AutoAlarm-" + instanceID
print(GetAlarmNamePrefix)
for instance in instanceID:
print("deleting alarms for instance :" + instanceID)
AlarmNamePrefix = GetAlarmNamePrefix
response = cloudwatch.describe_alarms(AlarmNamePrefix=AlarmNamePrefix,)
alarm_list = []
if 'MetricAlarms' in response:
for alarm in response['MetricAlarms']:
alarm_name = alarm['AlarmName']
alarm_list.append(alarm_name)
print(alarm_list)
cloudwatch.delete_alarms(AlarmNames=alarm_list)
This code is deleting the alarms fine but when I look at the Lambda function's execution logs in the CloudWatch Log Group I could see there is a huge number of events created for the same CloudWatch alarm multiple times.
Please help me to fix this code.
Take a look at these lines:
instanceID = event['detail']['instance-id']
GetAlarmNamePrefix = "AutoAlarm-" + instanceID
print(GetAlarmNamePrefix)
for instance in instanceID:
print("deleting alarms for instance :" + instanceID)
In theory, it is looping through each instance. However:
The print() statement is printing instanceID rather than instance
Nothing in the loop is actually referring to instance
The fact is, instanceID is a string that contains one Instance ID, as can be seen when printing GetAlarmNamePrefix.
Therefore, you can remove the for loop.
It is possible that multiple events are being passed to the Lambda function. However, the section of your code that extracts the event is not shown, so I can't comment on whether that should be changed.

share multiple DNS domain with multiple aws accounts by terraform in AWS Resource Access Manager

I'm forwarding DNS requests sent to a list of internal domains (on premise) by using AWS Route53 resolver. By terraform, I want to share the rules I created to other accounts of the company, so I have the following:
# I create as much share endpoint as domain I have, so If I have 30 domains, I'll make 30 endpoint RAM:
resource "aws_ram_resource_share" "endpoint_share" {
count = length(var.forward_domain)
name = "route53-${var.forward_domain[count.index]}-share"
allow_external_principals = false
}
# Here I share every single endpoint with all the AWS ACcount we have
resource "aws_ram_principal_association" "endpoint_ram_principal" {
count = length(var.resource_share_accounts)
principal = var.resource_share_accounts[count.index]
resource_share_arn = {
for item in aws_ram_resource_share.endpoint_share[*]:
item.arn
}
}
The last block, calls the arn output of the first one which is a list.
Now, this last block doesn't work, I don't know how to use multiple counts, when I run this, I get the following error:
Error: Invalid 'for' expression
line 37: Key expression is required when building an object.
Any idea how to make this work?
Terraform version: 0.12.23
Use square brackets in resource_share_arn, like this:
resource_share_arn = [
for item in aws_ram_resource_share.endpoint_share[*]:
item.arn
]

Pubnub functions not working on AWS Lambda

I'm trying to use history method provided by Pubnub to get the chat history of a channel and running my node.js code on AWS Lambda. However, my function is not getting called. I'm not sure if I'm doing it correctly, but here's the code snippet-
var publishKey = "pub-c-cfe10ea4-redacted";
var subscribeKey = "sub-c-fedec8ba-redacted";
var channelId = "ChatRoomDemo";
var uuid;
var pubnub = {};
function readMessages(intent,session,callback){
pubnub = require("pubnub")({
publish_key : publishKey,
subscribe_key: subscribeKey
});
pubnub.history({
channel : 'ChatRoomDemo',
callback : function(m){
console.log(JSON.stringify(m));
},
count : 100,
reverse : false
});
}
I expect the message history in JSON format to be displayed on the console.
I had the same problem and finally got it working. What you will need to do is allow the CIDR address for pubnub.com. This was a foreign idea to me until I figured it out! Here's how to do that to publish to a channel:
Copy the CIDR address for pubnub.com which is 54.246.196.128/26 (Source) [WARNING: do not this - see comment below]
Log into https://console.aws.amazon.com
Under "Services" go to "VPC"
On the left, under "Security," click "Network ACLs"
Click "Create Network ACL" give it a name tag like "pubnub.com"
Select the VPC for your Lambda skill (if you're not sure, click around your Lambda function, you'll see it. You probably only have one listed like me)
Click "Yes, Create"
Under the "Outbound Rules" tab, click "Edit"
For "Rule #" I just used "1"
For "Type" I used "HTTP (80)"
For "Destination" I pasted in the CIDR from step 1
"Save"
Note, if you're subscribing to a channel, you'll also need to add an "Inbound Rule" too.