custom extension to select existing VPC and SecurityGroups

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2020-06-03 14:31:19 +02:00
parent 1bf4bc9d46
commit b702065075
No known key found for this signature in database
GPG Key ID: 9858809D6F8F6E7E
6 changed files with 35 additions and 29 deletions

View File

@ -57,11 +57,11 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err
*/ */
template.Parameters[ParameterSubnet1Id] = cloudformation.Parameter{ template.Parameters[ParameterSubnet1Id] = cloudformation.Parameter{
Type: "AWS::EC2::Subnet::Id", Type: "AWS::EC2::Subnet::Id",
Description: "SubnetId,for Availability Zone 1 in the region in your VPC", Description: "SubnetId, for Availability Zone 1 in the region in your VPC",
} }
template.Parameters[ParameterSubnet2Id] = cloudformation.Parameter{ template.Parameters[ParameterSubnet2Id] = cloudformation.Parameter{
Type: "AWS::EC2::Subnet::Id", Type: "AWS::EC2::Subnet::Id",
Description: "SubnetId,for Availability Zone 1 in the region in your VPC", Description: "SubnetId, for Availability Zone 2 in the region in your VPC",
} }
// Create Cluster is `ParameterClusterName` parameter is not set // Create Cluster is `ParameterClusterName` parameter is not set
@ -79,10 +79,9 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err
} }
cluster := cloudformation.If("CreateCluster", cloudformation.Ref("Cluster"), cloudformation.Ref(ParameterClusterName)) cluster := cloudformation.If("CreateCluster", cloudformation.Ref("Cluster"), cloudformation.Ref(ParameterClusterName))
networks := map[string]string{}
for _, net := range project.Networks { for _, net := range project.Networks {
for k, v := range convertNetwork(project, net, cloudformation.Ref(ParameterVPCId)) { networks[net.Name] = convertNetwork(project, net, cloudformation.Ref(ParameterVPCId), template)
template.Resources[k] = v
}
} }
logGroup := fmt.Sprintf("/docker-compose/%s", project.Name) logGroup := fmt.Sprintf("/docker-compose/%s", project.Name)
@ -166,8 +165,7 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err
serviceSecurityGroups := []string{} serviceSecurityGroups := []string{}
for net := range service.Networks { for net := range service.Networks {
logicalName := networkResourceName(project, net) serviceSecurityGroups = append(serviceSecurityGroups, networks[net])
serviceSecurityGroups = append(serviceSecurityGroups, cloudformation.Ref(logicalName))
} }
desiredCount := 1 desiredCount := 1
@ -213,8 +211,12 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err
return template, nil return template, nil
} }
func convertNetwork(project *compose.Project, net types.NetworkConfig, vpc string) map[string]cloudformation.Resource { func convertNetwork(project *compose.Project, net types.NetworkConfig, vpc string, template *cloudformation.Template) string {
resources := map[string]cloudformation.Resource{} if sg, ok := net.Extras[ExtensionSecurityGroup]; ok {
logrus.Debugf("Security Group for network %q set by user to %q", net.Name, sg)
return sg.(string)
}
var ingresses []ec2.SecurityGroup_Ingress var ingresses []ec2.SecurityGroup_Ingress
if !net.Internal { if !net.Internal {
for _, service := range project.Services { for _, service := range project.Services {
@ -233,7 +235,7 @@ func convertNetwork(project *compose.Project, net types.NetworkConfig, vpc strin
} }
securityGroup := networkResourceName(project, net.Name) securityGroup := networkResourceName(project, net.Name)
resources[securityGroup] = &ec2.SecurityGroup{ template.Resources[securityGroup] = &ec2.SecurityGroup{
GroupDescription: fmt.Sprintf("%s %s Security Group", project.Name, net.Name), GroupDescription: fmt.Sprintf("%s %s Security Group", project.Name, net.Name),
GroupName: securityGroup, GroupName: securityGroup,
SecurityGroupIngress: ingresses, SecurityGroupIngress: ingresses,
@ -251,14 +253,14 @@ func convertNetwork(project *compose.Project, net types.NetworkConfig, vpc strin
} }
ingress := securityGroup + "Ingress" ingress := securityGroup + "Ingress"
resources[ingress] = &ec2.SecurityGroupIngress{ template.Resources[ingress] = &ec2.SecurityGroupIngress{
Description: fmt.Sprintf("Allow communication within network %s", net.Name), Description: fmt.Sprintf("Allow communication within network %s", net.Name),
IpProtocol: "-1", // all protocols IpProtocol: "-1", // all protocols
GroupId: cloudformation.Ref(securityGroup), GroupId: cloudformation.Ref(securityGroup),
SourceSecurityGroupId: cloudformation.Ref(securityGroup), SourceSecurityGroupId: cloudformation.Ref(securityGroup),
} }
return resources return cloudformation.Ref(securityGroup)
} }
func networkResourceName(project *compose.Project, network string) string { func networkResourceName(project *compose.Project, network string) string {

View File

@ -318,7 +318,7 @@ func getImage(image string) string {
func getRepoCredentials(service types.ServiceConfig) *ecs.TaskDefinition_RepositoryCredentials { func getRepoCredentials(service types.ServiceConfig) *ecs.TaskDefinition_RepositoryCredentials {
// extract registry and namespace string from image name // extract registry and namespace string from image name
for key, value := range service.Extras { for key, value := range service.Extras {
if key == "x-aws-pull_credentials" { if key == ExtensionPullCredentials {
return &ecs.TaskDefinition_RepositoryCredentials{CredentialsParameter: value.(string)} return &ecs.TaskDefinition_RepositoryCredentials{CredentialsParameter: value.(string)}
} }
} }

View File

@ -16,11 +16,11 @@
"Type": "String" "Type": "String"
}, },
"ParameterSubnet1Id": { "ParameterSubnet1Id": {
"Description": "SubnetId,for Availability Zone 1 in the region in your VPC", "Description": "SubnetId, for Availability Zone 1 in the region in your VPC",
"Type": "AWS::EC2::Subnet::Id" "Type": "AWS::EC2::Subnet::Id"
}, },
"ParameterSubnet2Id": { "ParameterSubnet2Id": {
"Description": "SubnetId,for Availability Zone 1 in the region in your VPC", "Description": "SubnetId, for Availability Zone 2 in the region in your VPC",
"Type": "AWS::EC2::Subnet::Id" "Type": "AWS::EC2::Subnet::Id"
}, },
"ParameterVPCId": { "ParameterVPCId": {

View File

@ -16,11 +16,11 @@
"Type": "String" "Type": "String"
}, },
"ParameterSubnet1Id": { "ParameterSubnet1Id": {
"Description": "SubnetId,for Availability Zone 1 in the region in your VPC", "Description": "SubnetId, for Availability Zone 1 in the region in your VPC",
"Type": "AWS::EC2::Subnet::Id" "Type": "AWS::EC2::Subnet::Id"
}, },
"ParameterSubnet2Id": { "ParameterSubnet2Id": {
"Description": "SubnetId,for Availability Zone 1 in the region in your VPC", "Description": "SubnetId, for Availability Zone 2 in the region in your VPC",
"Type": "AWS::EC2::Subnet::Id" "Type": "AWS::EC2::Subnet::Id"
}, },
"ParameterVPCId": { "ParameterVPCId": {

View File

@ -59,18 +59,15 @@ func (c *client) ComposeUp(ctx context.Context, project *compose.Project) error
} }
func (c client) GetVPC(ctx context.Context, project *compose.Project) (string, error) { func (c client) GetVPC(ctx context.Context, project *compose.Project) (string, error) {
//check compose file for the default external network //check compose file for custom VPC selected
if net, ok := project.Networks["default"]; ok { if vpc, ok := project.Extras[ExtensionVPC]; ok {
if net.External.External { vpcID := vpc.(string)
vpc := net.Name ok, err := c.api.VpcExists(ctx, vpcID)
ok, err := c.api.VpcExists(ctx, vpc) if err != nil {
if err != nil { return "", err
return "", err }
} if !ok {
if !ok { return "", fmt.Errorf("VPC does not exist: %s", vpc)
return "", fmt.Errorf("VPC does not exist: %s", vpc)
}
return vpc, nil
} }
} }
defaultVPC, err := c.api.GetDefaultVPC(ctx) defaultVPC, err := c.api.GetDefaultVPC(ctx)

7
ecs/pkg/amazon/x.go Normal file
View File

@ -0,0 +1,7 @@
package amazon
const (
ExtensionSecurityGroup = "x-aws-securitygroup"
ExtensionVPC = "x-aws-vpc"
ExtensionPullCredentials = "x-aws-pull_credentials"
)