Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
codepipeline.ActionConfig {
const createEvent = this.props.trigger === undefined ||
this.props.trigger === CodeCommitTrigger.EVENTS;
if (createEvent) {
this.props.repository.onCommit(stage.pipeline.node.uniqueId + 'EventRule', {
target: new targets.CodePipeline(stage.pipeline),
branches: [this.branch],
});
}
// the Action will write the contents of the Git repository to the Bucket,
// so its Role needs write permissions to the Pipeline Bucket
options.bucket.grantReadWrite(options.role);
// https://docs.aws.amazon.com/codecommit/latest/userguide/auth-and-access-control-permissions-reference.html#aa-acp
options.role.addToPolicy(new iam.PolicyStatement({
resources: [this.props.repository.repositoryArn],
actions: [
'codecommit:GetBranch',
'codecommit:GetCommit',
'codecommit:UploadArchive',
'codecommit:GetUploadArchiveStatus',
'codecommit:CancelUploadArchive',
],
}));
return {
configuration: {
RepositoryName: this.props.repository.repositoryName,
BranchName: this.branch,
PollForSourceChanges: this.props.trigger === CodeCommitTrigger.POLL,
},
private makePolicyStatements(task: sfn.Task): iam.PolicyStatement[] {
const stack = cdk.Stack.of(task);
// https://docs.aws.amazon.com/step-functions/latest/dg/ecs-iam.html
const policyStatements = [
new iam.PolicyStatement({
actions: ['ecs:RunTask'],
resources: [this.props.taskDefinition.taskDefinitionArn],
}),
new iam.PolicyStatement({
actions: ['ecs:StopTask', 'ecs:DescribeTasks'],
resources: ['*'],
}),
new iam.PolicyStatement({
actions: ['iam:PassRole'],
resources: cdk.Lazy.listValue({ produce: () => this.taskExecutionRoles().map(r => r.roleArn) })
}),
];
if (this.integrationPattern === sfn.ServiceIntegrationPattern.SYNC) {
policyStatements.push(new iam.PolicyStatement({
actions: ["events:PutTargets", "events:PutRule", "events:DescribeRule"],
resources: [stack.formatArn({
service: 'events',
resource: 'rule',
resourceName: 'StepFunctionsGetEventsForECSTaskRule'
})]
}));
}
if (!options.canContainersAccessInstanceRole) {
// Deny containers access to instance metadata service
// Source: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/instance_IAM_role.html
autoScalingGroup.addUserData('sudo iptables --insert FORWARD 1 --in-interface docker+ --destination 169.254.169.254/32 --jump DROP');
autoScalingGroup.addUserData('sudo service iptables save');
// The following is only for AwsVpc networking mode, but doesn't hurt for the other modes.
autoScalingGroup.addUserData('echo ECS_AWSVPC_BLOCK_IMDS=true >> /etc/ecs/ecs.config');
}
if (autoScalingGroup.spotPrice && options.spotInstanceDraining) {
autoScalingGroup.addUserData('echo ECS_ENABLE_SPOT_INSTANCE_DRAINING=true >> /etc/ecs/ecs.config');
}
// ECS instances must be able to do these things
// Source: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/instance_IAM_role.html
autoScalingGroup.addToRolePolicy(new iam.PolicyStatement({
actions: [
"ecs:CreateCluster",
"ecs:DeregisterContainerInstance",
"ecs:DiscoverPollEndpoint",
"ecs:Poll",
"ecs:RegisterContainerInstance",
"ecs:StartTelemetrySession",
"ecs:Submit*",
"ecr:GetAuthorizationToken",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
resources: ['*']
}));
// 0 disables, otherwise forward to underlying implementation which picks the sane default
): ActionConfig {
const { parameterName, regExp, logParameter = false } = this.props;
const checkParameterFunction = new Function(
scope,
'CheckParamterFunction',
{
runtime: Runtime.PYTHON_3_7,
code: Code.fromAsset(`${LAMBDA_PATH}/check-parameter`),
handler: 'check_parameter.lambda_handler',
},
);
// allow pipeline to list functions
options.role.addToPolicy(
new PolicyStatement({
actions: ['lambda:ListFunctions'],
resources: ['*'],
}),
);
// allow pipeline to invoke this lambda functionn
options.role.addToPolicy(
new PolicyStatement({
actions: ['lambda:InvokeFunction'],
resources: [checkParameterFunction.functionArn],
}),
);
// allow lambda to put job results for this pipeline
// CodePipeline requires this to be granted to '*'
// (the Pipeline ARN will not be enough)
taskDefinition.addContainer('cloudmapper-container', {
image: ecs.ContainerImage.fromAsset('./resources'),
memoryLimitMiB: 512,
cpu: 256,
environment: {
S3_BUCKET: config['s3_bucket'],
MINIMUM_ALERT_SEVERITY: config['minimum_alert_severity']
},
logging: new ecs.AwsLogDriver({
streamPrefix: 'cloudmapper',
logRetention: logs.RetentionDays.TWO_WEEKS
})
});
// Grant the ability to assume the IAM role in any account
taskDefinition.addToTaskRolePolicy(new iam.PolicyStatement({
resources: ["arn:aws:iam::*:role/"+config['iam_role']],
actions: ['sts:AssumeRole']
}));
// Grant the ability to read and write the files from the S3 bucket
taskDefinition.addToTaskRolePolicy(new iam.PolicyStatement({
resources: ["arn:aws:s3:::"+config['s3_bucket']],
actions: ['s3:ListBucket']
}));
taskDefinition.addToTaskRolePolicy(new iam.PolicyStatement({
resources: ["arn:aws:s3:::"+config['s3_bucket']+"/*"],
actions: ['s3:GetObject','s3:PutObject', 's3:DeleteObject']
}));
// Grant the ability to record the stdout to CloudWatch Logs
taskDefinition.addToTaskRolePolicy(new iam.PolicyStatement({
actions: ['ecs:DescribeContainerInstances', 'ecs:DescribeTasks'],
resources: ['*'],
}));
// Restrict to the ECS Cluster
fn.addToRolePolicy(new iam.PolicyStatement({
actions: [
'ecs:ListContainerInstances',
'ecs:SubmitContainerStateChange',
'ecs:SubmitTaskStateChange'
],
resources: [props.cluster.clusterArn]
}));
// Restrict the container-instance operations to the ECS Cluster
fn.addToRolePolicy(new iam.PolicyStatement({
actions: [
'ecs:UpdateContainerInstancesState',
'ecs:ListTasks'
],
conditions: {
ArnEquals: {'ecs:cluster': props.cluster.clusterArn}
},
resources: ['*']
}));
}
}
// Create Lambda to forward alarms
const alarm_forwarder = new lambda.Function(this, "alarm_forwarder", {
runtime: lambda.Runtime.PYTHON_3_7,
code: lambda.Code.asset("resources/alarm_forwarder"),
handler: "main.handler",
description: "Forwards alarms from the local SNS to another",
logRetention: logs.RetentionDays.TWO_WEEKS,
timeout: cdk.Duration.seconds(30),
memorySize: 128,
environment: {
"ALARM_SNS": config['alarm_sns_arn']
},
});
// Add priv to publish the events so the alarms can be forwarded
alarm_forwarder.addToRolePolicy(new iam.PolicyStatement({
resources: [config['alarm_sns_arn']],
actions: ['sns:Publish']
}));
// Connect the SNS to the Lambda
sns_topic.addSubscription(new sns_subscription.LambdaSubscription(alarm_forwarder));
}
}
public bind(_task: sfn.Task): sfn.StepFunctionsTaskConfig {
return {
resourceArn: getResourceArn("sns", "publish", this.integrationPattern),
policyStatements: [new iam.PolicyStatement({
actions: ['sns:Publish'],
resources: [this.topic.topicArn]
})],
parameters: {
TopicArn: this.topic.topicArn,
Message: this.props.message.value,
MessageStructure: this.props.messagePerSubscriptionType ? "json" : undefined,
Subject: this.props.subject,
}
};
}
}
constructor(scope: Construct, id: string, props: TrailProps = {}) {
super(scope, id, {
physicalName: props.trailName,
});
const cloudTrailPrincipal = new iam.ServicePrincipal("cloudtrail.amazonaws.com");
this.s3bucket = props.bucket || new s3.Bucket(this, 'S3', {encryption: s3.BucketEncryption.UNENCRYPTED});
this.s3bucket.addToResourcePolicy(new iam.PolicyStatement({
resources: [this.s3bucket.bucketArn],
actions: ['s3:GetBucketAcl'],
principals: [cloudTrailPrincipal],
}));
this.s3bucket.addToResourcePolicy(new iam.PolicyStatement({
resources: [this.s3bucket.arnForObjects(`AWSLogs/${Stack.of(this).account}/*`)],
actions: ["s3:PutObject"],
principals: [cloudTrailPrincipal],
conditions: {
StringEquals: {'s3:x-amz-acl': "bucket-owner-full-control"}
}
}));
let logGroup: logs.CfnLogGroup | undefined;
let logsRole: iam.IRole | undefined;
if (props.sendToCloudWatchLogs) {
logGroup = new logs.CfnLogGroup(this, "LogGroup", {
retentionInDays: props.cloudWatchLogsRetention || logs.RetentionDays.ONE_YEAR
});
private addVpcRequiredPermissions(props: ProjectProps, project: CfnProject): void {
if (!props.vpc || !this.role) {
return;
}
this.role.addToPolicy(new iam.PolicyStatement({
resources: [`arn:aws:ec2:${Aws.REGION}:${Aws.ACCOUNT_ID}:network-interface/*`],
actions: ['ec2:CreateNetworkInterfacePermission'],
conditions: {
StringEquals: {
'ec2:Subnet': props.vpc
.selectSubnets(props.subnetSelection).subnetIds
.map(si => `arn:aws:ec2:${Aws.REGION}:${Aws.ACCOUNT_ID}:subnet/${si}`),
'ec2:AuthorizedService': 'codebuild.amazonaws.com'
},
},
}));
const policy = new iam.Policy(this, 'PolicyDocument', {
statements: [
new iam.PolicyStatement({
resources: ['*'],