Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
constructor(name: string, args: ClusterArgs = {}, opts: pulumi.ComponentResourceOptions = {}) {
super("awsx:x:ecs:Cluster", name, {}, opts);
// First create an ECS cluster.
const parentOpts = { parent: this };
const cluster = args.cluster || new aws.ecs.Cluster(name, args, parentOpts);
this.cluster = cluster;
this.id = cluster.id;
this.vpc = args.vpc || x.ec2.Vpc.getDefault();
// IDEA: Can we re-use the network's default security group instead of creating a specific
// new security group in the Cluster layer? This may allow us to share a single Security Group
// across both instance and Lambda compute.
this.securityGroups = x.ec2.getSecurityGroups(this.vpc, name, args.securityGroups, parentOpts) ||
[Cluster.createDefaultSecurityGroup(name, this.vpc, parentOpts)];
this.extraBootcmdLines = () => cluster.id.apply(clusterId =>
[{ contents: `- echo ECS_CLUSTER='${clusterId}' >> /etc/ecs/ecs.config` }]);
this.registerOutputs({});
}
// // for (const volumeMount of container.volumes) {
// // const volume = volumeMount.sourceVolume;
// // volumes.push({
// // hostPath: (volume as Volume).getHostPath(),
// // name: (volume as Volume).getVolumeName(),
// // });
// // }
// // }
// // }
this.containers = args.containers;
const containerDefinitions = computeContainerDefinitions(this, name, this.containers, this.logGroup);
const containerString = containerDefinitions.apply(d => JSON.stringify(d));
const family = containerString.apply(s => name + "-" + utils.sha1hash(pulumi.getStack() + containerString));
this.taskDefinition = new aws.ecs.TaskDefinition(name, {
...args,
family,
taskRoleArn: this.taskRole.arn,
executionRoleArn: this.executionRole.arn,
containerDefinitions: containerString,
}, parentOpts);
this.run = createRunFunction(isFargate, this.taskDefinition.arn);
}
],
mostRecent: true,
owners: ["099720109477"], // Canonical
}));
const instance = new aws.ec2.Instance("web", {
ami: ubuntu.apply(ubuntu => ubuntu.id),
instanceType: "t2.micro",
tags: {
Name: "HelloWorld",
},
});
const instanceMetric = instance.metrics.cpuUtilization();
const instanceAlarm = instanceMetric.createAlarm("alarm" + alarmIndex++, { threshold: 120, evaluationPeriods: 2 });
const cluster = new aws.ecs.Cluster("foo", {});
const clusterMetric = cluster.metrics.cpuUtilization({ unit: "Percent" });
const clusterAlarm = clusterMetric.createAlarm("alarm" + alarmIndex++, { threshold: 50, evaluationPeriods: 2 });
const userPool = new aws.cognito.UserPool("pool", {});
const userPoolMetric = userPool.metrics.compromisedCredentialsRisk();
const userPoolAlarm = userPoolMetric.createAlarm("alarm" + alarmIndex++, { threshold: 120, evaluationPeriods: 2 });
const eventRule = new aws.cloudwatch.EventRule("console", {
description: "Capture each AWS Console Sign In",
eventPattern: `{
"detail-type": [
"AWS Console Sign In via CloudTrail"
]
}
`,
});
],
mostRecent: true,
owners: ["099720109477"], // Canonical
}));
const instance = new aws.ec2.Instance("web", {
ami: ubuntu.apply(ubuntu => ubuntu.id),
instanceType: "t2.micro",
tags: {
Name: "HelloWorld",
},
});
const instanceMetric = awsx.ec2.metrics.cpuUtilization({ instance });
const instanceAlarm = instanceMetric.createAlarm("alarm" + alarmIndex++, { threshold: 120, evaluationPeriods: 2 });
const cluster = new aws.ecs.Cluster("foo", {});
const clusterMetric = awsx.ecs.metrics.cpuUtilization({ cluster, unit: "Percent" });
const clusterAlarm = clusterMetric.createAlarm("alarm" + alarmIndex++, { threshold: 50, evaluationPeriods: 2 });
const userPool = new aws.cognito.UserPool("pool", {});
const userPoolMetric = awsx.cognito.metrics.compromisedCredentialsRisk({ userPool });
const userPoolAlarm = userPoolMetric.createAlarm("alarm" + alarmIndex++, { threshold: 120, evaluationPeriods: 2 });
const eventRule = new aws.cloudwatch.EventRule("console", {
description: "Capture each AWS Console Sign In",
eventPattern: `{
"detail-type": [
"AWS Console Sign In via CloudTrail"
]
}
`,
});
}
}
}
// Create the task definition, parented to this component.
const taskDefinition = createTaskDefinition(this, name, containers, ports);
// If the cluster has an autoscaling group, ensure the service depends on it being created.
const serviceDependsOn = [];
if (cluster.autoScalingGroupStack) {
serviceDependsOn.push(cluster.autoScalingGroupStack);
}
// Create the service.
const securityGroups = cluster.securityGroupId ? [ cluster.securityGroupId ] : [];
this.ecsService = new aws.ecs.Service(name, {
desiredCount: replicas,
taskDefinition: taskDefinition.task.arn,
cluster: cluster.ecsClusterARN,
loadBalancers: loadBalancers,
placementConstraints: placementConstraintsForHost(args.host),
waitForSteadyState: args.waitForSteadyState === undefined ? true : args.waitForSteadyState,
launchType: config.useFargate ? "FARGATE" : "EC2",
networkConfiguration: {
assignPublicIp: config.useFargate && !network.usePrivateSubnets,
securityGroups: securityGroups,
subnets: network.subnetIds,
},
}, { parent: this, dependsOn: serviceDependsOn });
const localEndpoints = getEndpoints(ports);
this.endpoints = localEndpoints;
const volume = volumeMount.sourceVolume;
volumes.push({
hostPath: (volume as Volume).getHostPath(),
name: (volume as Volume).getVolumeName(),
});
}
}
}
// Create the task definition for the group of containers associated with this Service.
const containerDefinitions = computeContainerDefinitions(containers, ports, logGroup);
// Compute the memory and CPU requirements of the task for Fargate
const taskMemoryAndCPU = containerDefinitions.apply(taskMemoryAndCPUForContainers);
const taskDefinition = new aws.ecs.TaskDefinition(name, {
family: name,
containerDefinitions: containerDefinitions.apply(JSON.stringify),
volumes: volumes,
taskRoleArn: getTaskRole().arn,
requiresCompatibilities: config.useFargate ? ["FARGATE"] : undefined,
memory: config.useFargate ? taskMemoryAndCPU.apply(t => t.memory) : undefined,
cpu: config.useFargate ? taskMemoryAndCPU.apply(t => t.cpu) : undefined,
networkMode: "awsvpc",
executionRoleArn: getExecutionRole().arn,
}, { parent: parent });
return {
task: taskDefinition,
logGroup: logGroup,
};
}
/**
* Optional auto-scaling group for the cluster. Can be created with
* [cluster.createAutoScalingGroup]
*/
autoScalingGroup?: mod.ClusterAutoScalingGroup;
}>;
/**
* A mapping from a container name and it's exposed port, to the hostname/port it can be reached at.
*/
export interface Endpoints {
[containerName: string]: { [port: number]: aws.apigateway.x.Endpoint; };
}
export abstract class ClusterService extends aws.ecs.Service {
public readonly clusterInstance: mod.Cluster;
public readonly taskDefinitionInstance: mod.ClusterTaskDefinition;
/**
* Optional auto-scaling group for the cluster. Can be created with
* [cluster.createAutoScalingGroup]
*/
public readonly autoScalingGroup?: mod.ClusterAutoScalingGroup;
public readonly endpoints: pulumi.Output;
public readonly defaultEndpoint: pulumi.Output;
public readonly getEndpoint: (containerName?: string, containerPort?: number) => Promise;
constructor(name: string, cluster: mod.Cluster,
args: ClusterServiceArgs, isFargate: boolean,
this.executionRole = args.taskRole === null ? undefined :
args.executionRole ? args.executionRole : TaskDefinition.createExecutionRole(
`${name}-execution`, /*assumeRolePolicy*/ undefined, /*policyArns*/ undefined, { parent: this });
this.containers = args.containers;
const containerDefinitions = computeContainerDefinitions(
this, name, args.vpc, this.containers, this.applicationListeners, this.networkListeners, this.logGroup);
this.listeners = {...this.applicationListeners, ...this.networkListeners };
const containerString = containerDefinitions.apply(d => JSON.stringify(d));
const defaultFamily = containerString.apply(s => name + "-" + utils.sha1hash(pulumi.getStack() + containerString));
const family = utils.ifUndefined(args.family, defaultFamily);
this.taskDefinition = new aws.ecs.TaskDefinition(name, {
...args,
family: family,
taskRoleArn: this.taskRole ? this.taskRole.arn : undefined,
executionRoleArn: this.executionRole ? this.executionRole.arn : undefined,
containerDefinitions: containerString,
}, { parent: this });
this.run = createRunFunction(isFargate, this.taskDefinition.arn);
}
* of containers in the ClusterTaskDefinition will be the one that is run.
*/
containerName?: string;
/**
* The OS to run. Defaults to 'linux' if unspecified.
*/
os?: HostOperatingSystem;
/**
* Optional environment variables to override those set in the container definition.
*/
environment?: Record;
}
export abstract class ClusterTaskDefinition extends aws.ecs.TaskDefinition {
public readonly cluster: module.Cluster;
public readonly logGroup: aws.cloudwatch.LogGroup;
public readonly containers: Record;
public readonly taskRole: aws.iam.Role;
public readonly executionRole: aws.iam.Role;
/**
* Information about the exposed port for the task definitions if it has one.
*/
public readonly exposedPort?: ExposedPort;
public readonly endpoints: pulumi.Output;
public readonly defaultEndpoint: pulumi.Output;
public readonly getEndpoint: (containerName?: string, containerPort?: number) => Promise;
function getOrCreateCluster(name: string, args: ClusterArgs, parent: Cluster) {
if (args.cluster === undefined) {
return new aws.ecs.Cluster(name, args, { parent });
}
if (pulumi.Resource.isInstance(args.cluster)) {
return args.cluster;
}
return aws.ecs.Cluster.get(name, args.cluster, undefined, { parent });
}