Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
function buildLambda(options) {
let fn = {
Resources: {}
};
// all function parameters available as environment variables
fn.Resources[options.name] = {
Type: 'AWS::Lambda::Function',
Properties: {
Code: {
S3Bucket: cf.ref('CodeS3Bucket'),
S3Key: cf.join([cf.ref('CodeS3Prefix'), cf.ref('GitSha'), '.zip'])
},
Role: cf.if('HasDispatchSnsArn', cf.getAtt('LambdaCfnDispatchRole', 'Arn'), cf.getAtt('LambdaCfnRole', 'Arn')),
Description: cf.stackName,
Environment: {
Variables: {}
}
}
};
fn.Resources[options.name].Properties.Timeout = setLambdaTimeout(options.timeout);
fn.Resources[options.name].Properties.MemorySize = setLambdaMemorySize(options.memorySize);
fn.Resources[options.name].Properties.Runtime = setLambdaRuntine(options.runtime);
fn.Resources[options.name].Properties.Handler = setLambdaHandler(options.handler);
return fn;
}
Effect: "Allow",
Principal: {
Service: ["ec2.amazonaws.com"]
},
Action: ["sts:AssumeRole"]
}
]
},
RoleName: cf.join("-", [cf.stackName, "ec2", "role"])
}
},
VisualizeChangeEC2InstanceProfile: {
Type: "AWS::IAM::InstanceProfile",
Properties: {
Roles: [cf.ref("VisualizeChangeEC2Role")],
InstanceProfileName: cf.join("-", [cf.stackName, "ec2", "instance", "profile"])
}
},
VisualizeChangeLoadBalancer: {
Type: "AWS::ElasticLoadBalancingV2::LoadBalancer",
Properties: {
Name: cf.stackName,
SecurityGroups: [
cf.importValue(
cf.join("-", ["hotosm-network-production", cf.ref("Environment"), "elbs-security-group", cf.region])
)
],
Subnets: cf.split(",", cf.ref("ELBSubnets")),
Type: "application"
}
},
VisualizeChangeTargetGroup: {
AutoScalingRollingUpdate: {
PauseTime: 'PT60M',
WaitOnResourceSignals: true
}
}
},
TaskingManagerScaleUp: {
Type: "AWS::AutoScaling::ScalingPolicy",
Properties: {
AutoScalingGroupName: cf.ref('TaskingManagerASG'),
PolicyType: 'TargetTrackingScaling',
TargetTrackingConfiguration: {
TargetValue: 600,
PredefinedMetricSpecification: {
PredefinedMetricType: 'ALBRequestCountPerTarget',
ResourceLabel: cf.join('/', [
cf.select(1,
cf.split('loadbalancer/',
cf.select(5,
cf.split(':', cf.ref("TaskingManagerLoadBalancer"))
)
)
),
cf.select(5,
cf.split(':', cf.ref("TaskingManagerTargetGroup"))
)
])
}
},
Cooldown: 600
}
},
['arn:aws:s3:::',
cf.select(1,
cf.split('s3://', cf.ref('DatabaseDump'))
)]
)]
}]
}
}],
RoleName: cf.join('-', [cf.stackName, 'ec2', 'database-dump-access', 'role'])
}
},
TaskingManagerEC2InstanceProfile: {
Type: "AWS::IAM::InstanceProfile",
Properties: {
Roles: cf.if('DatabaseDumpFileGiven', [cf.ref('TaskingManagerDatabaseDumpAccessRole')], [cf.ref('TaskingManagerEC2Role')]),
InstanceProfileName: cf.join('-', [cf.stackName, 'ec2', 'instance', 'profile'])
}
},
TaskingManagerLoadBalancer: {
Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer',
Properties: {
Name: cf.stackName,
SecurityGroups: [cf.importValue(cf.join('-', ['hotosm-network-production', cf.ref('NetworkEnvironment'), 'elbs-security-group', cf.region]))],
Subnets: cf.split(',', cf.ref('ELBSubnets')),
Type: 'application'
}
},
TaskingManagerTargetGroup: {
Type: 'AWS::ElasticLoadBalancingV2::TargetGroup',
Properties: {
HealthCheckIntervalSeconds: 60,
HealthCheckPort: 8000,
's3:GetObject',
's3:GetObjectAcl',
's3:ListObjects',
's3:ListBucket'
],
Effect: 'Allow',
Resource: [cf.join('',
['arn:aws:s3:::',
cf.select(1,
cf.split('s3://', cf.ref('DatabaseDump'))
)]
)]
}]
}
}],
RoleName: cf.join('-', [cf.stackName, 'ec2', 'database-dump-access', 'role'])
}
},
TaskingManagerEC2InstanceProfile: {
Type: "AWS::IAM::InstanceProfile",
Properties: {
Roles: cf.if('DatabaseDumpFileGiven', [cf.ref('TaskingManagerEC2Role'), cf.ref('TaskingManagerDatabaseDumpAccessRole')], [cf.ref('TaskingManagerEC2Role')]),
InstanceProfileName: cf.join('-', [cf.stackName, 'ec2', 'instance', 'profile'])
}
},
TaskingManagerLoadBalancer: {
Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer',
Properties: {
Name: cf.stackName,
SecurityGroups: [cf.importValue(cf.join('-', ['hotosm-network-production', cf.ref('Environment'), 'elbs-security-group', cf.region]))],
Subnets: cf.split(',', cf.ref('ELBSubnets')),
Type: 'application'
Resources[prefixed('Role')].Properties.Policies[0].PolicyDocument.Statement.push({
Effect: 'Allow',
Action: 'sns:Publish',
Resource: cf.ref(prefixed('Topic'))
});
if (options.permissions)
Resources[prefixed('Role')].Properties.Policies.push({
PolicyName: cf.join([cf.stackName, '-user-defined-worker']),
PolicyDocument: {
Statement: options.permissions
}
});
if (options.reduce) {
const tableName = cf.join('-', [cf.stackName, prefixed('-progress')]);
const tableThroughput = {
readCapacityUnits: options.readCapacityUnits,
writeCapacityUnits: options.writeCapacityUnits
};
Resources[prefixed('ProgressTable')] = table(tableName, tableThroughput);
const tableArn = cf.join(['arn:aws:dynamodb:', cf.region, ':', cf.accountId, ':table/', cf.ref(prefixed('ProgressTable'))]);
Resources[prefixed('ProgressTablePermission')] = {
Type: 'AWS::IAM::Policy',
Properties: {
Roles: [cf.ref(prefixed('Role'))],
PolicyName: 'watchbot-progress',
PolicyDocument: {
Statement: [
QueueName: cf.join([cf.stackName, '-', prefixed('DeadLetterQueue')]),
MessageRetentionPeriod: 1209600
}
};
if (options.fifo) {
Resources[prefixed('DeadLetterQueue')].Properties.FifoQueue = true;
Resources[prefixed('DeadLetterQueue')].Properties.ContentBasedDeduplication = true;
Resources[prefixed('DeadLetterQueue')].Properties.QueueName = cf.join([cf.stackName, '-', prefixed('DeadLetterQueue'), '.fifo']);
}
Resources[prefixed('Queue')] = {
Type: 'AWS::SQS::Queue',
Properties: {
VisibilityTimeout: 180,
QueueName: cf.join([cf.stackName, '-', prefixed('Queue')]),
MessageRetentionPeriod: options.messageRetention,
RedrivePolicy: {
deadLetterTargetArn: cf.getAtt(prefixed('DeadLetterQueue'), 'Arn'),
maxReceiveCount: options.deadletterThreshold
}
}
};
if (options.fifo) {
Resources[prefixed('Queue')].Properties.FifoQueue = true;
Resources[prefixed('Queue')].Properties.ContentBasedDeduplication = true;
Resources[prefixed('Queue')].Properties.QueueName = cf.join([cf.stackName, '-', prefixed('Queue'), '.fifo']);
}
if (!options.fifo) Resources[prefixed('Topic')] = {
Type: 'AWS::SNS::Topic',
Period: 600,
ComparisonOperator: 'LessThanThreshold',
Namespace: 'Mapbox/ecs-watchbot',
Dimensions: [
{ Name: 'QueueName', Value: cf.getAtt(prefixed('Queue'), 'QueueName') }
],
MetricName: 'TotalMessages',
AlarmActions: [cf.ref(prefixed('ScaleDown'))]
}
};
if (options.deadletterAlarm) {
Resources[prefixed('DeadLetterAlarm')] = {
Type: 'AWS::CloudWatch::Alarm',
Properties: {
AlarmName: cf.join('-', [cf.ref('AWS::StackName'), prefixed('-dead-letter'), cf.region]),
AlarmDescription:
'Provides notification when messages are visible in the dead letter queue',
EvaluationPeriods: 1,
Statistic: 'Minimum',
Threshold: 1,
Period: '60',
ComparisonOperator: 'GreaterThanOrEqualToThreshold',
Namespace: 'AWS/SQS',
Dimensions: [
{ Name: 'QueueName', Value: cf.getAtt(prefixed('DeadLetterQueue'), 'QueueName') }
],
MetricName: 'ApproximateNumberOfMessagesVisible',
AlarmActions: [notify]
}
};
}
Protocol: 'HTTP'
}
},
TaskingManagerRDS: {
Type: 'AWS::RDS::DBInstance',
Properties: {
Engine: 'postgres',
DBName: cf.if('UseASnapshot', cf.noValue, cf.ref('PostgresDB')),
EngineVersion: '9.5.15',
MasterUsername: cf.if('UseASnapshot', cf.noValue, cf.ref('PostgresUser')),
MasterUserPassword: cf.if('UseASnapshot', cf.noValue, cf.ref('PostgresPassword')),
AllocatedStorage: cf.ref('DatabaseSize'),
StorageType: 'gp2',
DBInstanceClass: 'db.m3.large', //rethink here
DBSnapshotIdentifier: cf.if('UseASnapshot', cf.ref('DBSnapshot'), cf.noValue),
VPCSecurityGroups: [cf.importValue(cf.join('-', ['hotosm-network-production', cf.ref('Environment'), 'ec2s-security-group', cf.region]))],
}
}
};
module.exports = { Parameters, Resources, Conditions }
Resources[prefixed('Role')] = {
Type: 'AWS::IAM::Role',
Properties: {
AssumeRolePolicyDocument: {
Statement: [
{
Effect: 'Allow',
Principal: { Service: ['ecs-tasks.amazonaws.com'] },
Action: ['sts:AssumeRole']
}
]
},
Policies: [
{
PolicyName: cf.join([cf.stackName, '-default-worker']),
PolicyDocument: {
Statement: [
{
Effect: 'Allow',
Action: [
'sqs:ReceiveMessage',
'sqs:DeleteMessage',
'sqs:ChangeMessageVisibility'
],
Resource: cf.getAtt(prefixed('Queue'), 'Arn')
},
{
Effect: 'Allow',
Action: [
'logs:CreateLogStream',
'logs:PutLogEvents',