in packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts [150:219]
constructor(scope: Construct, id: string, props: Ec2ServiceProps) {
if (props.daemon && props.desiredCount !== undefined) {
throw new Error('Daemon mode launches one task on every instance. Don\'t supply desiredCount.');
}
if (props.daemon && props.maxHealthyPercent !== undefined && props.maxHealthyPercent !== 100) {
throw new Error('Maximum percent must be 100 for daemon mode.');
}
if (props.minHealthyPercent !== undefined && props.maxHealthyPercent !== undefined && props.minHealthyPercent >= props.maxHealthyPercent) {
throw new Error('Minimum healthy percent must be less than maximum healthy percent.');
}
if (!props.taskDefinition.isEc2Compatible) {
throw new Error('Supplied TaskDefinition is not configured for compatibility with EC2');
}
if (props.securityGroup !== undefined && props.securityGroups !== undefined) {
throw new Error('Only one of SecurityGroup or SecurityGroups can be populated.');
}
super(scope, id, {
...props,
desiredCount: props.desiredCount,
maxHealthyPercent: props.daemon && props.maxHealthyPercent === undefined ? 100 : props.maxHealthyPercent,
minHealthyPercent: props.daemon && props.minHealthyPercent === undefined ? 0 : props.minHealthyPercent,
launchType: LaunchType.EC2,
enableECSManagedTags: props.enableECSManagedTags,
},
{
cluster: props.cluster.clusterName,
taskDefinition: props.deploymentController?.type === DeploymentControllerType.EXTERNAL ? undefined : props.taskDefinition.taskDefinitionArn,
placementConstraints: Lazy.any({ produce: () => this.constraints }, { omitEmptyArray: true }),
placementStrategies: Lazy.any({ produce: () => this.strategies }, { omitEmptyArray: true }),
schedulingStrategy: props.daemon ? 'DAEMON' : 'REPLICA',
}, props.taskDefinition);
this.constraints = [];
this.strategies = [];
this.daemon = props.daemon || false;
let securityGroups;
if (props.securityGroup !== undefined) {
securityGroups = [props.securityGroup];
} else if (props.securityGroups !== undefined) {
securityGroups = props.securityGroups;
}
if (props.taskDefinition.networkMode === NetworkMode.AWS_VPC) {
this.configureAwsVpcNetworkingWithSecurityGroups(props.cluster.vpc, props.assignPublicIp, props.vpcSubnets, securityGroups);
} else {
// Either None, Bridge or Host networking. Copy SecurityGroups from ASG.
// We have to be smart here -- by default future Security Group rules would be created
// in the Cluster stack. However, if the Cluster is in a different stack than us,
// that will lead to a cyclic reference (we point to that stack for the cluster name,
// but that stack will point to the ALB probably created right next to us).
//
// In that case, reference the same security groups but make sure new rules are
// created in the current scope (i.e., this stack)
validateNoNetworkingProps(props);
this.connections.addSecurityGroup(...securityGroupsInThisStack(this, props.cluster.connections.securityGroups));
}
this.addPlacementConstraints(...props.placementConstraints || []);
this.addPlacementStrategies(...props.placementStrategies || []);
this.node.addValidation({
validate: () => !this.taskDefinition.defaultContainer ? ['A TaskDefinition must have at least one essential container'] : [],
});
}