Skip to content

Commit 14b5acb

Browse files
committed
Adds optional Fargate-based build tasks
Allows switching build tasks between EC2 and Fargate to enhance flexibility.
1 parent b5f444a commit 14b5acb

File tree

2 files changed

+117
-19
lines changed

2 files changed

+117
-19
lines changed

provider/aws/builds.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,11 +864,73 @@ func (p *Provider) runBuild(build *structs.Build, burl string, opts structs.Buil
864864
}
865865
}
866866

867+
stackFargateBuild, err := p.stackParameter(p.Rack, "FargateBuild")
868+
if err != nil {
869+
return err
870+
}
871+
872+
launchType := aws.String("EC2")
873+
nc := &ecs.NetworkConfiguration{}
874+
if stackFargateBuild == "Yes" {
875+
secGroups, subnets := []*string{}, []*string{}
876+
snet0, err := p.stackResource(p.Rack, "Subnet0")
877+
if err != nil {
878+
log.Error(err)
879+
return err
880+
}
881+
if snet0 != nil && snet0.PhysicalResourceId != nil {
882+
subnets = append(subnets, snet0.PhysicalResourceId)
883+
}
884+
885+
snet1, err := p.stackResource(p.Rack, "Subnet1")
886+
if err != nil {
887+
log.Error(err)
888+
return err
889+
}
890+
if snet1 != nil && snet1.PhysicalResourceId != nil {
891+
subnets = append(subnets, snet1.PhysicalResourceId)
892+
}
893+
894+
pnet0, err := p.stackResource(p.Rack, "SubnetPrivate0")
895+
if err != nil {
896+
log.Error(err)
897+
return err
898+
}
899+
if pnet0 != nil && pnet0.PhysicalResourceId != nil {
900+
subnets = append(subnets, pnet0.PhysicalResourceId)
901+
}
902+
903+
pnet1, err := p.stackResource(p.Rack, "SubnetPrivate1")
904+
if err != nil {
905+
log.Error(err)
906+
return err
907+
}
908+
if pnet1 != nil && pnet1.PhysicalResourceId != nil {
909+
subnets = append(subnets, pnet1.PhysicalResourceId)
910+
}
911+
912+
biSecGroup, err := p.stackResource(p.Rack, "BuildInstanceSecurityGroup")
913+
if err != nil {
914+
log.Error(err)
915+
return err
916+
}
917+
if biSecGroup != nil && biSecGroup.PhysicalResourceId != nil {
918+
secGroups = append(secGroups, biSecGroup.PhysicalResourceId)
919+
}
920+
921+
launchType = aws.String("FARGATE")
922+
nc.AwsvpcConfiguration = &ecs.AwsVpcConfiguration{
923+
Subnets: subnets,
924+
SecurityGroups: secGroups,
925+
}
926+
}
927+
867928
req := &ecs.RunTaskInput{
868929
Cluster: aws.String(p.BuildCluster),
869930
Count: aws.Int64(1),
870931
StartedBy: aws.String(fmt.Sprintf("convox.%s", build.App)),
871932
TaskDefinition: aws.String(td),
933+
LaunchType: launchType,
872934
Overrides: &ecs.TaskOverride{
873935
ContainerOverrides: []*ecs.ContainerOverride{
874936
{
@@ -928,6 +990,9 @@ func (p *Provider) runBuild(build *structs.Build, burl string, opts structs.Buil
928990
},
929991
},
930992
}
993+
if nc.AwsvpcConfiguration != nil {
994+
req.NetworkConfiguration = nc
995+
}
931996

932997
task, err := p.runTask(req)
933998
if err != nil {

provider/aws/formation/rack.json

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,17 @@
4646
"ExistingVpcAndInternetGateway": {
4747
"Fn::And": [ { "Condition": "ExistingVpc" }, { "Condition": "InternetGateway" } ]
4848
},
49+
"BuildUsingFargate": {
50+
"Fn::And": [
51+
{
52+
"Fn::Equals": [
53+
{ "Fn::FindInMap": [ "RegionConfig", { "Ref": "AWS::Region" }, "Fargate" ] },
54+
"Yes"
55+
]
56+
},
57+
{ "Fn::Equals": [ { "Ref": "FargateBuild" }, "Yes" ] }
58+
]
59+
},
4960
"HighAvailability": { "Fn::Equals": [ { "Ref": "HighAvailability" }, "true" ] },
5061
"HttpProxy": { "Fn::Not": [ { "Fn::Equals": [ { "Ref": "HttpProxy" }, "" ] } ] },
5162
"InstanceARM": {
@@ -433,7 +444,7 @@
433444
"Value": { "Ref": "AWS::StackName" }
434445
},
435446
"RackDomain": {
436-
"Value": {
447+
"Value": {
437448
"Fn::Join": [ ".", [
438449
"rack",
439450
{ "Fn::Select": [ 0, { "Fn::Split": [ ".", { "Fn::GetAtt": [ "ApiBalancer", "DNSName" ] } ] } ] },
@@ -765,6 +776,12 @@
765776
"Default": "false",
766777
"AllowedValues": [ "true", "false" ]
767778
},
779+
"FargateBuild": {
780+
"Type": "String",
781+
"Description": "Use Fargate for build instances",
782+
"Default": "No",
783+
"AllowedValues": [ "Yes", "No" ]
784+
},
768785
"NoHaInstanceCount": {
769786
"Default": "1",
770787
"Description": "The number of instances in the runtime cluster for no HighAvailable racks",
@@ -3000,7 +3017,7 @@
30003017
{ "Key": "Name", "Value": { "Ref": "AWS::StackName" }},
30013018
{ "Key": "Rack", "Value": { "Ref": "AWS::StackName" }},
30023019
{ "Key": "GatewayAttachment", "Value": { "Fn::If": [ "ExistingVpc", "existing",{ "Ref": "GatewayAttachment"}]}},
3003-
{ "Key": "NatGateways", "Value": { "Fn::If":
3020+
{ "Key": "NatGateways", "Value": { "Fn::If":
30043021
[ "PrivateInstances",
30053022
{
30063023
"Fn::Join": [
@@ -3262,7 +3279,7 @@
32623279
{ "Key": "Name", "Value": { "Ref": "AWS::StackName" }},
32633280
{ "Key": "Rack", "Value": { "Ref": "AWS::StackName" }},
32643281
{ "Key": "GatewayAttachment", "Value": { "Fn::If": [ "ExistingVpc", "existing",{ "Ref": "GatewayAttachment"}]}},
3265-
{ "Key": "NatGateways", "Value": { "Fn::If":
3282+
{ "Key": "NatGateways", "Value": { "Fn::If":
32663283
[ "PrivateInstances",
32673284
{
32683285
"Fn::Join": [
@@ -3968,17 +3985,22 @@
39683985
"DeploymentConfiguration": { "MinimumHealthyPercent": { "Fn::If": [ "HighAvailability", "50", "0" ] }, "MaximumPercent": "200" },
39693986
"DesiredCount": { "Fn::If": [ "HighAvailability", { "Ref": "ApiCount" }, 1 ] },
39703987
"LoadBalancers": [ { "ContainerName": "web", "ContainerPort": "5443", "TargetGroupArn": { "Ref": "ApiBalancerTargetGroup" } }],
3971-
"PlacementConstraints": [ { "Fn::If": ["SpotFleet", { "Type": "memberOf", "Expression": "attribute:asg == primary" }, { "Ref": "AWS::NoValue" }] } ],
3988+
"PlacementConstraints": [ { "Fn::If": ["SpotFleet", { "Type": "memberOf", "Expression": "attribute:asg == primary" }, { "Ref": "AWS::NoValue" }] } ],
39723989
"Role": { "Fn::GetAtt": [ "ServiceRole", "Arn" ] },
39733990
"TaskDefinition": { "Ref": "ApiWebTasks" }
39743991
}
39753992
},
39763993
"ApiBuildTasks": {
39773994
"Type": "AWS::ECS::TaskDefinition",
39783995
"Properties": {
3996+
"RequiresCompatibilities": [
3997+
{ "Fn::If": [ "BuildUsingFargate", "FARGATE", "EC2" ] }
3998+
],
3999+
"NetworkMode": { "Fn::If": [ "BuildUsingFargate", "awsvpc", "bridge" ] },
4000+
"Cpu": { "Ref": "BuildCpu" },
4001+
"Memory": { "Ref": "BuildMemory" },
39794002
"ContainerDefinitions": [
39804003
{
3981-
"Cpu": { "Ref": "BuildCpu" },
39824004
"DockerLabels": {
39834005
"convox.release": { "Ref": "Version" },
39844006
"rack.ApiBalancerSecurity": { "Ref": "ApiBalancerSecurity" },
@@ -4079,14 +4101,19 @@
40794101
"LinuxParameters": {
40804102
"InitProcessEnabled": "true"
40814103
},
4082-
"Memory": { "Ref": "BuildMemory" },
40834104
"ReadonlyRootFilesystem": { "Fn::If": [ "EnableContainerReadonlyRootFilesystem", "true", "false" ] },
4084-
"MountPoints": [
4085-
{ "SourceVolume": "config", "ContainerPath": "/etc/sysconfig/docker" },
4086-
{ "SourceVolume": "docker", "ContainerPath": "/var/run/docker.sock" },
4087-
{ "SourceVolume": "home", "ContainerPath": "/root/" },
4088-
{ "SourceVolume": "temp", "ContainerPath": "/tmp/" }
4089-
],
4105+
"MountPoints": {
4106+
"Fn::If": [
4107+
"BuildUsingFargate",
4108+
{ "Ref": "AWS::NoValue" },
4109+
[
4110+
{ "SourceVolume": "config", "ContainerPath": "/etc/sysconfig/docker" },
4111+
{ "SourceVolume": "docker", "ContainerPath": "/var/run/docker.sock" },
4112+
{ "SourceVolume": "home", "ContainerPath": "/root/" },
4113+
{ "SourceVolume": "temp", "ContainerPath": "/tmp/" }
4114+
]
4115+
]
4116+
},
40904117
"Name": "build",
40914118
"Secrets": [{
40924119
"Name": "PASSWORD",
@@ -4097,12 +4124,18 @@
40974124
"ExecutionRoleArn": { "Fn::GetAtt": [ "ApiRole", "Arn" ] },
40984125
"Family": { "Fn::Sub": "${AWS::StackName}-build" },
40994126
"TaskRoleArn": { "Fn::GetAtt": [ "ApiRole", "Arn" ] },
4100-
"Volumes": [
4101-
{ "Name": "config", "Host": { "SourcePath": "/etc/sysconfig/docker" } },
4102-
{ "Name": "docker", "Host": { "SourcePath": "/var/run/docker.sock" } },
4103-
{ "Name": "home" },
4104-
{ "Name": "temp" }
4105-
]
4127+
"Volumes": {
4128+
"Fn::If": [
4129+
"BuildUsingFargate",
4130+
{ "Ref": "AWS::NoValue" },
4131+
[
4132+
{ "Name": "config", "Host": { "SourcePath": "/etc/sysconfig/docker" } },
4133+
{ "Name": "docker", "Host": { "SourcePath": "/var/run/docker.sock" } },
4134+
{ "Name": "home" },
4135+
{ "Name": "temp" }
4136+
]
4137+
]
4138+
}
41064139
}
41074140
},
41084141
"ApiMonitorTasks": {
@@ -4515,7 +4548,7 @@
45154548
"VersioningConfiguration": { "Status" : {"Ref": "EnableS3Versioning" } },
45164549
"LifecycleConfiguration": { "Fn::If": [ "BlankLogRetention",
45174550
{ "Rules": [ { "NoncurrentVersionExpiration": { "NewerNoncurrentVersions" : 1, "NoncurrentDays" : 365 }, "Status": "Enabled" } ] },
4518-
{ "Rules": [
4551+
{ "Rules": [
45194552
{ "ExpirationInDays": { "Ref": "LogRetention" }, "Status": "Enabled" },
45204553
{ "NoncurrentVersionExpiration": { "NewerNoncurrentVersions" : 1, "NoncurrentDays" : 365 }, "Status": "Enabled" }
45214554
] }

0 commit comments

Comments
 (0)