Cloudwatch rule to match ssm hierarchy - amazon-cloudwatch

I'd like to create a cloudwatch rule to trigger an action whenever a SSM parameter in a given hiearchy is updated (in my example anything in the /config hierarchy)
If I put a rule matching the whole name of the parameter the action gets triggered correctly.
I tried the following thus far:
{
"source": [
"aws.ssm"
],
"detail-type": [
"Parameter Store Change"
],
"detail": {
"name": [
"/config/",
"/config/*",
"/config/%"
],
"operation": [
"Update"
]
}
}
Is there any way to achieve such behaviour ?

Not exactly what you want, but you can leave off the "name" array entirely. You will then get notifications for all parameters, and then filter from the message receive side.

Related

OPA authorization policies with scopes and roles

I'm using Open Policy Agent as an authorization component together with OIDC enabled apps.
I have input from the apps in the format:
{
"token": {
"scopes": [
"read:books",
"write:books"
]
},
"principal": {
"roles": [
"user",
"moderator"
]
},
"context": {
"action": "read",
"resource": "books"
}
}
Then I have data with access mapping in the format:
{
"user": [
"read:books"
],
"moderator": [
"read:books",
"write:books"
],
"administrator": [
"read:books",
"write:books",
"read:store",
"write:store"
]
}
And the policy currently looks like this:
package whatever.authz
context_scope := concat(":", [input.context.action, input.context.resource])
default allow = false
allow {
token_has_context_scope
principal_has_resource_access
}
token_has_context_scope {
context_scope == input.token.scopes[_]
}
principal_has_resource_access {
principal_role := input.principal.roles[_]
context_scope == data[principal_role][_]
}
This produces the following error:
2 errors occurred:
policy.rego:16: rego_recursion_error: rule principal_has_resource_access is recursive: principal_has_resource_access -> principal_has_resource_access
policy.rego:7: rego_recursion_error: rule allow is recursive: allow -> principal_has_resource_access -> allow
It is the recursive lookup in the principal_has_resource_access function that is causing the error.
I need to check if one of the roles of the principal is allowed to access the resource as specified by the context. Since roles is an array i need to find the union of all access scopes in the data and see if one of them matches the context scope. What am I doing wrong in the policy?
The snippet can be found in the Rego Playground https://play.openpolicyagent.org/p/KhovLRgMup
OPA stores all data under the data path, including policy and rules. There's no way for the compiler to know that the input you're providing isn't referencing the policy itself (i.e. data["whatever"]) which would be recursive. The easiest way to work around this is to simply use a top level attribute for your data which differs from your policy (i.e package name), like this:
{
"attributes": {
"user": [
"read:books"
],
"moderator": [
"read:books",
"write:books"
],
"administrator": [
"read:books",
"write:books",
"read:store",
"write:store"
]
}
}
And update your policy to reference this:
context_scope == data["attributes"][principal_role][_]
Since data.attributes != data.whatever.authz there is no risk of recursion, and the compiler won't complain. You might want a better name than "attributes", but I'll leave that to you :)

Make CloudWatch Event pass an integer timestamp instead of string of UTC time

I'm invoking a scheduled Step Function with a CloudWatch event. The input of the first batch job in the step function state machine is like the following:
{
"version": "0",
"id": "sdjlafgdf05-7c32-435hf-aa3b5a8sfade815",
"detail-type": "Scheduled Event",
"source": "aws.events",
"account": "xxxxxxxx",
"time": "2022-01-14T19:46:49Z",
"region": "us-east-1",
"resources": [
"arn:aws:events:us-east-1:xxxxxxxxxxxx:rule/adfnwelkqnlngqrej-SAFFJKHF734"
],
"detail": {}
}
I want the "time" field can give me the integer. Specifically, instead of "2022-01-14T19:46:49Z", I want "1642189609" (epoch in seconds), so I don't need to parse it in my batch job code. I'm using CDK to build the infrastructure. Is there any way of doing this?
At the moment this is not possible directly with native Step Functions "Intrinsic Functions". So you have two options:
Do it via a lambda as explained in this other answer
Pass it first to EventBridge and then create a rule for EventBridge to foward it to CloudWatch

ADF v2 - Web Activity- POST output not retrievable

With Azure Data Factory v2, I created Web Activity using the POST method and got the desired response output.
But can't get the rows data from the output response in the next activity.
How do I reference columns in the rows in this output?
The data in the rows doesn't have any headers.
{
"Tables": [
{
"TableName": "Table_0",
"Columns": [
{
"ColumnName": "MyFieldA",
"DataType": "String",
"ColumnType": "string"
},
{
"ColumnName": "MyFieldB",
"DataType": "String",
"ColumnType": "string"
}
],
"Rows": [
[
"ABCDEF",
"AAAABBBBBCCCDDDDD"
],
[
"CCCCCCC",
"CCCCCCC"
],
I can't reference the value in the rows
I've tried numerous things
e.g. #activity('WebActivity').output.Rows
Nothing seems to work.
What's the point of getting a response from a web activity and then not being able to reference the output in data factory?
Thanks Pacodel!!! You've helped me out.
And to use in the a For Each Loop and Array, when I pass in the Rows to my Execute pipeline activity #activity('WebActivity').output.Tables[0].Rows:
[
[
"ABCDEF",
"AAAABBBBBCCCDDDDD"
],
[
"CCCCCCC",
"CCCCCCC"
]
]
I can use the following to reference the rows:
#{item()[0]}
#{item()[1]}
I use the #item to populate parameters in a stored procedure activity which loads my table
Thanks
For your example.
#activity('WebActivity').output.Tables[0].Rows
will return the following:
[
[
"ABCDEF",
"AAAABBBBBCCCDDDDD"
],
[
"CCCCCCC",
"CCCCCCC"
]
]
If you want to access even deeper, you just need to specify the index.
#activity('WebActivity').output.Tables[0].Rows[0][0] will return ABCDEF
If you need to automate this, you can have a pattern of foreach with an execute pipeline inside passing an array as a parameter until you get to the properties that you need.

Cloudwatch event for out of region creation

I am trying to create a auto-remediation process that will stop/delete any VPC, Cloudformation Stack, VPC, Lambda, Internet Gateway or EC2 created outside of the eu-central-1 region. My first step is to parameter a CloudWatch event rule to detect any of the previously mentioned event.
{
"source": [
"aws.cloudtrail"
],
"detail-type": [
"AWS API Call via CloudTrail"
],
"detail": {
"eventSource": [
"ec2.amazonaws.com",
"cloudformation.amazonaws.com",
"lambda.amazonaws.com"
],
"eventName": [
"CreateStack",
"CreateVpc",
"CreateFunction20150331",
"CreateInternetGateway",
"RunInstances"
],
"awsRegion": [
"us-east-1",
"us-east-2",
"us-west-1",
"us-west-2",
"ap-northeast-1",
"ap-northeast-2",
"ap-south-1",
"ap-southeast-1",
"ap-southeast-2",
"ca-central-1",
"ap-south-1",
"eu-west-1",
"eu-west-2",
"eu-west-3"
"sa-east-1"
]
}
}
For now, the event should only trigger an SNS topic that will send me an email, but in the future there will be a lambda fonction to do the remediation.
Unfortunately, when I go create an Internet Gateway in another region (let's say eu-west-1), no notification occur. The Event does not appear if I want to set an alarm on it either, while it does appear in CloudWatch Events).
Any idea what could be wrong with my event config?
OK, I figured it out. The source of the event changes even if the notification comes from CloudTrail. The "source" parameters should therefore be:
"source": [
"aws.cloudtrail",
"aws.ec2",
"aws.cloudformation",
"aws.lambda"
]

AWS data pipeline activity with multiple inputs

As part of an Amazon AWS data pipeline, I have a hive activity using two unstaged S3 data nodes as input. What I want is to be able to set two script variables on the activity, each pointing to an input data node, but I can't get the syntax right. With the single input, I could write the following and it would work just fine:
INPUT_FOO=#{input.directoryPath}
When I add the second input, I run into a problem of how to reference them since they are now an array of inputs, as you can see in the pipeline definition below. Essentially, I want to achieve the following, but can't figure out the correct syntax:
INPUT_FOO=#{input[1].directoryPath}
INPUT_BAR=#{input[2].directoryPath}
Here's the activity portion of the pipeline definition:
{
"id": "ActivityId_7u1sR",
"input": [
{
"ref": "DataNodeId_iYnxf"
},
{
"ref": "DataNodeId_162Ka"
}
],
"schedule": {
"ref": "DefaultSchedule"
},
"scriptUri": "#{myS3ScriptLocation}calculate-results.q",
"name": "Perform Calculations",
"runsOn": {
"ref": "EmrClusterId_jHeiV"
},
"scriptVariable": [
"INPUT_SOURCE1=#{input[1].directoryPath}",
"OUTPUT=#{output.directoryPath}Results/",
"INPUT_SOURCE2=#{input[2].directoryPath}"
],
"output": {
"ref": "DataNodeId_2jY6v"
},
"type": "HiveActivity",
"stage": "false"
}
I plan to keep the tables unstaged and take care of table creation in the hive script so that it's easier to run each Hive activity in isolation as well as in the pipeline itself.
Here's the error I see when using array syntax:
Unable to resolve input[1].directoryPath for object ActivityId_7u1sR'
As it stands now, this scenario is not supported, but a feature request was added to support it in the future.