Skip to main content

Amazon Web Services (AWS)

The following APIs are supported within FPL via the built-in AWS integration.

AWS

AWS_AccountRegionLambda

  • AWS_AccountRegionLambda(accounts, regions, (account, region) ⇒ { return {} })
    • Run lambda function on specific AWS accounts and regions
    • accounts: "*" enables all configured AWS accounts. Account could also be one account name or an array of names
    • accounts: "Production" or ["Production", "UnitTest"]
    • regions: "*" enables all configured regions. Regions could also be one region name or an array of names
    • regions: "us-east-1" or ["us-east-1", "us-east-2"]
    • this function returns a map of objects
    • results from different regions will be merged into one
// enabling only the Production account from the region us-east-1
AWS_AccountRegionLambda("Production","us-east-1", (account, region) => {
/*
code block
*/
return {table1, table2, ...}
})

// enabling all configured accounts from all configured region
AWS_AccountRegionLambda("*","*", (account, region) => {
/*
code block
*/
return {table1, table2, ...}
})

AWS_AccountLambda

  • AWS_AccountLambda(accounts, (account) ⇒ { return {} })
    • lambda function on specific AWS accounts (One example is AWS Cost and Usage API, which does not limit to one specific region)

AWS Resource Loading Support

AWS_Cli_List

  • AWS_Cli_List(<cmd_line>, (obj) ⇒ { })
    • list AWS assets via AWS cli

AWS_Cli_Get

  • AWS_Cli_Get(<cmd_line>, idList, (id, obj) ⇒ {})
    • get asset attributes from a list of ID

NOTE: the AWS_Cli_List and AWS_Cli_Get are not open for production deployment. For security concerns. If the role IAM policy is not properly configured, it may cause security issues.

let natGateways = AWS_Cli_List("ec2 describe-nat-gateways", (obj) => {
let ID = obj.NatGatewayId
let State = obj.State
let VpcId = obj.VpcId
let PublicIp = obj.NatGatewayAddresses[0].PublicIp
return {ID, State, VpcId, PublicIp}
})
// call AWS cli: "aws ec2 describe-nat-gateways"
// same as AWS_LoadAsset( "ec2:natgateway", ...
function main() {
return AWS_AccountRegionLambda("*", "us-west-2", () => {
let queues = AWS_Cli_List("sqs list-queues", (url) => {
let QueueUrl = url
let segments = split(QueueUrl, "/")
let ID = segments[len(segments)-1]
let fifo = endsWith(ID, ".fifo")
return { ID, QueueUrl, fifo }
})

let queueTags = AWS_Cli_Get("sqs list-queue-tags --queue-url", queues.GetColumnValues("QueueUrl"), (id, obj) => {
let QueueUrl = id
let TagCount = len(obj.Tags)
return {QueueUrl, TagCount}
})

let queueAttributes = AWS_Cli_Get("sqs get-queue-attributes --attribute-names All --queue-url", queues.GetColumnValues("QueueUrl"), (id, obj) => {
let QueueUrl = id
let QueueArn = obj.Attributes.QueueArn
return {QueueUrl, QueueArn}
})
queues.Join(queueTags, {QueueUrl:"QueueUrl"})
queues.Join(queueAttributes, {QueueUrl:"QueueUrl"})
return {queues}
})
}

AWS_LoadAsset

  • AWS_LoadAsset(<resource>, (obj) ⇒ { })
    • loads an AWS resource and convert them into a table
    • resource:
      • lambda:function
      • ec2:vpc
      • ec2:instance
      • ec2:volume
      • s3:bucket
      • ec2:natgateway
      • eks:cluster
      • eks:nodegroup
      • sqs:queue
      • elasticloadbalancing:loadbalancer
      • elasticloadbalancing:targetgroup
      • apigateway:apis
    • Must have an ID variable
    • if the lambda function return null, the entry will be skipped (filterMap function)
    • extracting values from tags
      • jsonGetTag(obj, <tagArrayPath>, <keyField>, <keyValue>, <valueField>)
      • jsonGetAWSTag(obj, <tagName>)
// AWS_LoadAsset example
function main() {
return AWS_AccountRegionLambda("FluencySIEM", "us-east-1", () => {
let clusters = AWS_LoadAsset("eks:cluster", (obj) => {
let {Name:ID, Status, CreatedAt} = obj
return {ID, Status, CreatedAt}
})
return {clusters}
})
}

/*
"Tags": [
{
"Key": "Name",
"Value": "my-instance"
}
],
*/
// Suppose the JSON tag, Value can be extracted through
let Name = jsonGetTag(obj, "Tags", "Key", "Name", "Value")
let Name = jsonGetAWSTag(obj, "Name")

AWS_LoadAsset

  • AWS_LoadAsset() with aggregate/groupBy
    • the return object. { aggregate: { groupBy:{groupByKey1,…​}, columns:{ aggregates }}}
return AWS_AccountRegionLambda("*","*", () => {
let volumes = AWS_LoadAsset("ec2:volume",({VolumeType, State, Iops, Size}) => {
return {aggregate:{ groupBy:{VolumeType}, columns: {Sum:{Size}}}}
})
volumes.SetColumnUnit("Size", "GB")
return {volumes}
})

AWS Metric Loading Support

AWS_GetMetric

  • AWS_GetMetric(metricName, options, filters) // load AWS metrics
    • options: {from, to, dimensions, namespace, period, stat, unit, timezone}
    • options.dimensions could be one string or a list of strings
    • filters: {dimensionName: assetTable}
function getLambdaCost(assetTable) {
let options = {from: "-60m@m", to: "@m", dimensions: "FunctionName", namespace: "AWS/Lambda", period: "5m", stat: "Sum"}
let filters = {FunctionName:assetTable}
options.unit = "Millisecond"
let duration = AWS_GetMetric("Duration", options, filters)
options.unit = "Count"
let invocation = AWS_GetMetric("Invocations", options, filters)
return {duration, invocation}
}

AWS Pricing API Support

AWS_GetPrice

  • AWS_GetPrice(service, resource, options)
    • service: "Lambda", resource: "GB-Second" , "Request"
    • service: "S3", resource: "StorageType"
    • service: "NatGateway", resource "GB" , "Hour"
    • service: "ApplicationLoadBalancer", resource "Hour", "LCU-Hour"

AWS_GetCostUsage

  • AWS_GetCostUsage(options)
    • from: report start time
    • to: report end time
    • metric: AmortizedCost | BlendedCost | UnblendedCost | UsageQuantity
    • granularity: DAILY | HOURLY
    • dimensions: AZ, INSTANCE_TYPE, LEGAL_ENTITY_NAME, INVOICING_ENTITY, LINKED_ACCOUNT, OPERATION, PLATFORM, PURCHASE_TYPE, SERVICE, TENANCY, RECORD_TYPE, and USAGE_TYPE
    • tags: customer defined cost allocation tags
function main() {
return AWS_AccountLambda("Production", () => {
let dailyUsage=AWS_GetCostUsage({from:"-60d@d", to:"-1d@d", metric:"UsageQuantity", granularity:"DAILY"})
let dailyBlended=AWS_GetCostUsage({from:"-30d@d", to:"-1d@d", metric:"BlendedCost", granularity:"DAILY"})
let dailyUnBlended=AWS_GetCostUsage({from:"-30d@d", to:"-1d@d", metric:"UnblendedCost", granularity:"DAILY"})
let dailyAmortized=AWS_GetCostUsage({from:"-60d@d", to:"-1d@d", metric:"AmortizedCost", granularity:"DAILY"})
let dailyCostByService=AWS_GetCostUsage({from:"-30d@d", to:"-1d@d", metric:"AmortizedCost", granularity:"DAILY", dimensions:"SERVICE"})
dailyCostByService.Sort(10)
return {dailyUsage, dailyBlended, dailyUnBlended, dailyAmortized, dailyCostByService}
})
}