diff --git a/.changelog/4457.txt b/.changelog/4457.txt new file mode 100644 index 00000000000..b851968cce9 --- /dev/null +++ b/.changelog/4457.txt @@ -0,0 +1,3 @@ +```release-note:bug +plugin/aws-ecs: Fix bringing your own alb to ecs deployments. +``` diff --git a/builtin/aws/ecs/platform.go b/builtin/aws/ecs/platform.go index 97a33a4306c..852febde5ba 100644 --- a/builtin/aws/ecs/platform.go +++ b/builtin/aws/ecs/platform.go @@ -65,26 +65,27 @@ func (p *Platform) ConfigSet(config interface{}) error { if c.ALB != nil { alb := c.ALB err := utils.Error(validation.ValidateStruct(alb, - validation.Field(&alb.CertificateId, - validation.Empty.When(alb.ListenerARN != "").Error("certificate cannot be used with listener_arn"), - ), + // ZoneId and FQDN are both used to create a route53 record that points to an ALB. + // While we could still create this, if a user is managing their own ALB out of band, + // they probably also want to manage the route53 record themselves + // too. validation.Field(&alb.ZoneId, - validation.Empty.When(alb.ListenerARN != ""), + validation.Empty.When(alb.LoadBalancerArn != ""), validation.Required.When(alb.FQDN != ""), ), validation.Field(&alb.FQDN, - validation.Empty.When(alb.ListenerARN != ""), + validation.Empty.When(alb.LoadBalancerArn != ""), validation.Required.When(alb.ZoneId != "").Error("fqdn only valid with zone_id"), ), + validation.Field(&alb.InternalScheme, - validation.Nil.When(alb.ListenerARN != "").Error("internal cannot be used with listener_arn"), + validation.Nil.When(alb.LoadBalancerArn != "").Error("internal cannot be used with load_balancer_arn"), ), - validation.Field(&alb.ListenerARN, + validation.Field(&alb.LoadBalancerArn, validation.Empty.When( - alb.CertificateId != "" || - alb.ZoneId != "" || + alb.ZoneId != "" || alb.FQDN != "" || - len(alb.SecurityGroupIDs) >= 1).Error("listener_arn can not be used with other options"), + len(alb.SecurityGroupIDs) >= 1).Error("load_balancer_arn can not be used with other options"), ), validation.Field(&alb.SecurityGroupIDs), )) @@ -397,6 +398,9 @@ func (p *Platform) Deploy( albState := rm.Resource("application load balancer").State().(*Resource_Alb) result.LoadBalancerArn = albState.Arn + listenerState := rm.Resource("alb listener").State().(*Resource_Alb_Listener) + result.ListenerArn = listenerState.Arn + cState := rm.Resource("cluster").State().(*Resource_Cluster) result.Cluster = cState.Name @@ -687,7 +691,7 @@ func (p *Platform) resourceServiceCreate( deploymentId DeploymentId, state *Resource_Service, - // Outputs of other resource creation processes +// Outputs of other resource creation processes taskDefinition *Resource_TaskDefinition, cluster *Resource_Cluster, targetGroup *Resource_TargetGroup, @@ -1000,6 +1004,8 @@ func (p *Platform) resourceServiceDestroy( return nil } +// resourceAlbListenerCreate finds or creates an ALB listener, and ensures that the +// target group is added to it. func (p *Platform) resourceAlbListenerCreate( ctx context.Context, sg terminal.StepGroup, @@ -1016,7 +1022,7 @@ func (p *Platform) resourceAlbListenerCreate( return nil } - s := sg.Add("Initiating ALB creation") + s := sg.Add("Initiating ALB Listener") defer s.Abort() state.TargetGroup = targetGroup @@ -1031,9 +1037,8 @@ func (p *Platform) resourceAlbListenerCreate( } var ( - certs []*elbv2.Certificate - protocol = "HTTP" - newListener = false + certs []*elbv2.Certificate + protocol = "HTTP" ) if albConfig != nil && albConfig.CertificateId != "" { @@ -1045,75 +1050,31 @@ func (p *Platform) resourceAlbListenerCreate( elbsrv := elbv2.New(sess) - var listener *elbv2.Listener - - if albConfig != nil && albConfig.ListenerARN != "" { - s.Update("Describing requested ALB listener (ARN: %s)", albConfig.ListenerARN) - - state.Managed = false - - out, err := elbsrv.DescribeListenersWithContext(ctx, &elbv2.DescribeListenersInput{ - ListenerArns: []*string{aws.String(albConfig.ListenerARN)}, - }) - if err != nil { - return status.Errorf(codes.Internal, "failed to describe requested listener ARN %q: %s", albConfig.ListenerARN, err) - } - - listener = out.Listeners[0] - s.Update("Using configured ALB Listener: %s (load-balancer: %s)", - *listener.ListenerArn, *listener.LoadBalancerArn) - } else { - state.Managed = true - - if alb == nil || alb.Arn == "" { - return status.Errorf(codes.InvalidArgument, "cannot create ALB listener - no existing ALB defined.") - } - - s.Update("No ALB listener specified - looking for listeners for ALB %q", alb.Name) - listeners, err := elbsrv.DescribeListenersWithContext(ctx, &elbv2.DescribeListenersInput{ - LoadBalancerArn: &alb.Arn, - }) - if err != nil { - return status.Errorf(codes.Internal, "failed to describe listeners for alb (ARN %q): %s", alb.Arn, err) - } - - if len(listeners.Listeners) > 0 { - listener = listeners.Listeners[0] - s.Update("Using existing ALB Listener (ARN: %q)", *listener.ListenerArn) - } else { - s.Update("Creating new ALB Listener") - newListener = true - - log.Info("load-balancer defined", "dns-name", alb.DnsName) - - tgs[0].Weight = aws.Int64(100) - lo, err := elbsrv.CreateListenerWithContext(ctx, &elbv2.CreateListenerInput{ - LoadBalancerArn: &alb.Arn, - Port: aws.Int64(int64(externalIngressPort)), - Protocol: aws.String(protocol), - Certificates: certs, - DefaultActions: []*elbv2.Action{ - { - ForwardConfig: &elbv2.ForwardActionConfig{ - TargetGroups: tgs, - }, - Type: aws.String("forward"), - }, - }, - }) - if err != nil { - return status.Errorf(codes.Internal, "failed to create listener: %s", err) - } + if alb == nil || alb.Arn == "" { + return status.Errorf(codes.InvalidArgument, "cannot create ALB listener - no existing ALB defined.") + } + log.Info("load-balancer defined", "dns-name", alb.DnsName) - listener = lo.Listeners[0] + s.Update("Looking for listeners for ALB %q", alb.Arn) + listeners, err := elbsrv.DescribeListenersWithContext(ctx, &elbv2.DescribeListenersInput{ + LoadBalancerArn: &alb.Arn, + }) + if err != nil { + return status.Errorf(codes.Internal, "failed to describe listeners for alb (ARN %q): %s", alb.Arn, err) + } - s.Update("Created ALB Listener") - log.Debug("Created ALB Listener", "arn", *listener.ListenerArn) + // Check for existing listeners on our specified port + var listener *elbv2.Listener + for _, l := range listeners.Listeners { + if *l.Port == int64(externalIngressPort) { + listener = l } } - state.Arn = *listener.ListenerArn - if !newListener { + if listener != nil { + // Found an existing listener! + s.Update("Modifying existing ALB Listener to introduce target group") + def := listener.DefaultActions if len(def) > 0 && def[0].ForwardConfig != nil { @@ -1125,13 +1086,40 @@ func (p *Platform) resourceAlbListenerCreate( } } - s.Update("Modifying ALB Listener to introduce target group") + in := &elbv2.ModifyListenerInput{ + ListenerArn: listener.ListenerArn, + DefaultActions: []*elbv2.Action{ + { + ForwardConfig: &elbv2.ForwardActionConfig{ + TargetGroups: tgs, + }, + Type: aws.String("forward"), + }, + }, - _, err := elbsrv.ModifyListenerWithContext(ctx, &elbv2.ModifyListenerInput{ - ListenerArn: listener.ListenerArn, + // Setting these on every deployment so that we pick up any potential changes + // in the waypoint.hcl config Port: aws.Int64(int64(externalIngressPort)), Protocol: aws.String(protocol), Certificates: certs, + } + + _, err = elbsrv.ModifyListenerWithContext(ctx, in) + if err != nil { + return status.Errorf(codes.Internal, "failed to introduce new target group to existing ALB listener: %s", err) + } + + s.Update("Modified ALB Listener to introduce target group") + } else { + s.Update("Creating new ALB Listener") + state.Managed = true + + tgs[0].Weight = aws.Int64(100) + lo, err := elbsrv.CreateListenerWithContext(ctx, &elbv2.CreateListenerInput{ + LoadBalancerArn: &alb.Arn, + Port: aws.Int64(int64(externalIngressPort)), + Protocol: aws.String(protocol), + Certificates: certs, DefaultActions: []*elbv2.Action{ { ForwardConfig: &elbv2.ForwardActionConfig{ @@ -1142,12 +1130,17 @@ func (p *Platform) resourceAlbListenerCreate( }, }) if err != nil { - return status.Errorf(codes.Internal, "failed to introduce new target group to existing ALB listener: %s", err) + return status.Errorf(codes.Internal, "failed to create listener: %s", err) } - s.Update("Modified ALB Listener to introduce target group") + listener = lo.Listeners[0] + + s.Update("Created ALB Listener") + log.Debug("Created ALB Listener", "arn", *listener.ListenerArn) } + state.Arn = *listener.ListenerArn + s.Done() return nil } @@ -1375,7 +1368,7 @@ func (p *Platform) resourceTaskDefinitionCreate( deployConfig *component.DeploymentConfig, state *Resource_TaskDefinition, - // Outputs of other resource creation processes +// Outputs of other resource creation processes executionRole *Resource_ExecutionRole, taskRole *Resource_TaskRole, logGroup *Resource_LogGroup, @@ -1636,24 +1629,28 @@ func (p *Platform) resourceAlbCreate( subnets *Resource_AlbSubnets, // Required because we need to know which VPC we're in, and subnets discover it. state *Resource_Alb, ) error { + s := sg.Add("Initiating ALB creation") + defer s.Abort() + if p.config.DisableALB { - log.Debug("ALB disabled - skipping target group creation") + s.Update("ALB disabled - skipping ALB") + s.Done() return nil } albConfig := p.config.ALB - if albConfig != nil && albConfig.ListenerARN != "" { - log.Debug("Existing ALB listener specified - no need to create or discover an ALB") + if albConfig != nil && albConfig.LoadBalancerArn != "" { + s.Update("Existing ALB specified - no need to create or discover an ALB") + s.Done() + state.Managed = false + state.Arn = albConfig.LoadBalancerArn return nil } // If not using an existing listener, the load balancer is owned by waypoint state.Managed = true - s := sg.Add("Initiating ALB creation") - defer s.Abort() - var certs []*elbv2.Certificate if albConfig != nil && albConfig.CertificateId != "" { certs = append(certs, &elbv2.Certificate{ @@ -1709,6 +1706,16 @@ func (p *Platform) resourceAlbCreate( Subnets: subnetIds, SecurityGroups: securityGroupIds, Scheme: &scheme, + Tags: []*elbv2.Tag{ + { + Key: aws.String("waypoint_managed"), + Value: aws.String("true"), + }, + { + Key: aws.String("waypoint_app"), + Value: aws.String(src.App), + }, + }, }) if err != nil { return status.Errorf(codes.Internal, "failed to create ALB %q: %s", lbName, err) @@ -1720,7 +1727,6 @@ func (p *Platform) resourceAlbCreate( } state.Arn = *lb.LoadBalancerArn - state.Arn = *lb.LoadBalancerArn state.DnsName = *lb.DNSName state.CanonicalHostedZoneId = *lb.CanonicalHostedZoneId @@ -2506,34 +2512,29 @@ func (p *Platform) loadResourceManagerState( } rm.Resource("target group").SetState(&targetGroupResource) - // Restore state of ALB listener. Difficult because it may only be defined on the load balancer. + // Restore state of ALB listener by inspecting the load balancer var listenerResource Resource_Alb_Listener listenerResource.TargetGroup = &targetGroupResource - if p.config.ALB != nil && p.config.ALB.ListenerARN != "" { - listenerResource.Arn = p.config.ALB.ListenerARN - listenerResource.Managed = false - log.Debug("Using existing listener", "arn", listenerResource.Arn) - } else { - listenerResource.Managed = true - s.Update("Describing load balancer %s", deployment.LoadBalancerArn) - sess, err := p.getSession(log) - if err != nil { - return status.Errorf(codes.Internal, "failed to get aws session: %s", err) - } - elbsrv := elbv2.New(sess) - listeners, err := elbsrv.DescribeListenersWithContext(ctx, &elbv2.DescribeListenersInput{ - LoadBalancerArn: &deployment.LoadBalancerArn, - }) - if err != nil { - return status.Errorf(codes.Internal, "failed to describe listeners for ALB %q: %s", deployment.LoadBalancerArn, err) - } - if len(listeners.Listeners) == 0 { - s.Update("No listeners found for ALB %q", deployment.LoadBalancerArn) - } else { - listenerResource.Arn = *listeners.Listeners[0].ListenerArn - s.Update("Found existing listener (ARN: %q)", listenerResource.Arn) - } + listenerResource.Managed = false // Impossible to know now if we created this initially, so this is the safe choice + s.Update("Describing load balancer %s", deployment.LoadBalancerArn) + sess, err := p.getSession(log) + if err != nil { + return status.Errorf(codes.Internal, "failed to get aws session: %s", err) + } + elbsrv := elbv2.New(sess) + + listeners, err := elbsrv.DescribeListenersWithContext(ctx, &elbv2.DescribeListenersInput{ + LoadBalancerArn: &deployment.LoadBalancerArn, + }) + if err != nil { + return status.Errorf(codes.Internal, "failed to describe listeners for ALB %q: %s", deployment.LoadBalancerArn, err) + } + if len(listeners.Listeners) == 0 { + s.Update("No listeners found for ALB %q", deployment.LoadBalancerArn) + } else { + listenerResource.Arn = *listeners.Listeners[0].ListenerArn + s.Update("Found existing listener (ARN: %q)", listenerResource.Arn) } rm.Resource("alb listener").SetState(&listenerResource) @@ -2623,9 +2624,9 @@ type ALBConfig struct { // Fully qualified domain name of the record to create in the target zone id FQDN string `hcl:"domain_name,optional"` - // When set, waypoint will configure the target group into the specified - // ALB Listener ARN. This allows for usage of existing ALBs. - ListenerARN string `hcl:"listener_arn,optional"` + // When set, waypoint will configure the target group into the load balancer. + // This allows for usage of existing ALBs. + LoadBalancerArn string `hcl:"load_balancer_arn"` // Indicates, when creating an ALB, that it should be internal rather than // internet facing. @@ -2940,13 +2941,15 @@ deploy { ) doc.SetField( - "listener_arn", + "load_balancer_arn", "the ARN on an existing ALB to configure", docs.Summary( - "when this is set, no ALB or Listener is created. Instead the application is", - "configured by manipulating this existing Listener. This allows users to", - "configure their ALB outside waypoint but still have waypoint hook the application", - "to that ALB", + "when this is set, Waypoint will use this ALB instead of creating", + "its own. A target group will still be created for each deployment,", + "and will be added to a listener on the configured ALB port", + "(Waypoint will the listener if it doesn't exist).", + "This allows users to configure their ALB outside Waypoint but still ", + "have Waypoint hook the application to that ALB", ), ) diff --git a/builtin/aws/ecs/platform_test.go b/builtin/aws/ecs/platform_test.go index 1f0ca44849d..50e5c4a0e1f 100644 --- a/builtin/aws/ecs/platform_test.go +++ b/builtin/aws/ecs/platform_test.go @@ -31,13 +31,13 @@ func TestPlatformConfig(t *testing.T) { require.NoError(t, p.ConfigSet(cfg)) }) - t.Run("fine if only listener", func(t *testing.T) { + t.Run("fine if only lb", func(t *testing.T) { var p Platform cfg := &Config{ Memory: 512, ALB: &ALBConfig{ - ListenerARN: "xyz", + LoadBalancerArn: "xyz", }, } @@ -57,43 +57,29 @@ func TestPlatformConfig(t *testing.T) { require.NoError(t, p.ConfigSet(cfg)) }) - t.Run("errors if security_group_ids and listener are set", func(t *testing.T) { + t.Run("errors if security_group_ids and alb are set", func(t *testing.T) { var p Platform cfg := &Config{ Memory: 512, ALB: &ALBConfig{ SecurityGroupIDs: []string{"xyz", "lmnop"}, - ListenerARN: "abc", + LoadBalancerArn: "abc", }, } require.Error(t, p.ConfigSet(cfg)) }) - t.Run("errors if cert and listener are set", func(t *testing.T) { + t.Run("errors if zone_id and fqdn and load balancer are set", func(t *testing.T) { var p Platform cfg := &Config{ Memory: 512, ALB: &ALBConfig{ - CertificateId: "xyz", - ListenerARN: "abc", - }, - } - - require.Error(t, p.ConfigSet(cfg)) - }) - - t.Run("errors if zone_id and fqdn and listener are set", func(t *testing.T) { - var p Platform - - cfg := &Config{ - Memory: 512, - ALB: &ALBConfig{ - ZoneId: "xyz", - FQDN: "a.b", - ListenerARN: "abc", + ZoneId: "xyz", + FQDN: "a.b", + LoadBalancerArn: "abc", }, } @@ -140,15 +126,15 @@ func TestPlatformConfig(t *testing.T) { require.NoError(t, p.ConfigSet(cfg)) }) - t.Run("errors if internal and listener are set", func(t *testing.T) { + t.Run("errors if internal and alb are set", func(t *testing.T) { var p Platform i := true cfg := &Config{ Memory: 512, ALB: &ALBConfig{ - InternalScheme: &i, - ListenerARN: "abc", + InternalScheme: &i, + LoadBalancerArn: "abc", }, } diff --git a/builtin/aws/ecs/plugin.pb.go b/builtin/aws/ecs/plugin.pb.go index 351e75da000..1f66fcfd1c4 100644 --- a/builtin/aws/ecs/plugin.pb.go +++ b/builtin/aws/ecs/plugin.pb.go @@ -31,6 +31,7 @@ type Deployment struct { ServiceArn string `protobuf:"bytes,3,opt,name=service_arn,json=serviceArn,proto3" json:"service_arn,omitempty"` TargetGroupArn string `protobuf:"bytes,4,opt,name=target_group_arn,json=targetGroupArn,proto3" json:"target_group_arn,omitempty"` LoadBalancerArn string `protobuf:"bytes,5,opt,name=load_balancer_arn,json=loadBalancerArn,proto3" json:"load_balancer_arn,omitempty"` + ListenerArn string `protobuf:"bytes,8,opt,name=listener_arn,json=listenerArn,proto3" json:"listener_arn,omitempty"` Cluster string `protobuf:"bytes,6,opt,name=cluster,proto3" json:"cluster,omitempty"` ResourceState *opaqueany.Any `protobuf:"bytes,7,opt,name=resource_state,json=resourceState,proto3" json:"resource_state,omitempty"` } @@ -102,6 +103,13 @@ func (x *Deployment) GetLoadBalancerArn() string { return "" } +func (x *Deployment) GetListenerArn() string { + if x != nil { + return x.ListenerArn + } + return "" +} + func (x *Deployment) GetCluster() string { if x != nil { return x.Cluster @@ -1243,7 +1251,7 @@ var file_waypoint_builtin_aws_ecs_plugin_proto_rawDesc = []byte{ 0x69, 0x6e, 0x2f, 0x61, 0x77, 0x73, 0x2f, 0x65, 0x63, 0x73, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x65, 0x63, 0x73, 0x1a, 0x13, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x61, 0x6e, 0x79, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x22, 0x81, 0x02, 0x0a, 0x0a, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x6f, 0x22, 0xa4, 0x02, 0x0a, 0x0a, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x41, 0x72, 0x6e, 0x12, 0x1f, 0x0a, @@ -1254,104 +1262,106 @@ var file_waypoint_builtin_aws_ecs_plugin_proto_rawDesc = []byte{ 0x47, 0x72, 0x6f, 0x75, 0x70, 0x41, 0x72, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, - 0x72, 0x41, 0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x35, - 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x61, - 0x6e, 0x79, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x47, 0x0a, 0x07, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, - 0x72, 0x6c, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x65, 0x72, 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, - 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x41, 0x72, 0x6e, 0x22, 0xb1, - 0x0a, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0x2f, 0x0a, 0x07, 0x43, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x1a, 0x4f, 0x0a, 0x0d, - 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x61, 0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x1a, 0x4a, 0x0a, - 0x08, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, - 0x03, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, - 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x1a, 0x49, 0x0a, 0x07, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x1a, 0x47, 0x0a, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, - 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x30, 0x0a, - 0x08, 0x4c, 0x6f, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x72, 0x41, 0x72, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6c, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x65, 0x72, 0x41, 0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x12, 0x35, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6f, 0x70, 0x61, 0x71, + 0x75, 0x65, 0x61, 0x6e, 0x79, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x47, 0x0a, 0x07, 0x52, 0x65, 0x6c, 0x65, + 0x61, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x41, 0x72, + 0x6e, 0x22, 0xb1, 0x0a, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0x2f, + 0x0a, 0x07, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x1a, - 0x4d, 0x0a, 0x0d, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x4f, 0x0a, 0x0d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x1a, 0x5e, - 0x0a, 0x16, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, - 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x44, 0x0a, 0x0f, 0x73, 0x65, 0x63, 0x75, - 0x72, 0x69, 0x74, 0x79, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x63, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x0e, - 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x1a, 0x5e, - 0x0a, 0x16, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, - 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x44, 0x0a, 0x0f, 0x73, 0x65, 0x63, 0x75, - 0x72, 0x69, 0x74, 0x79, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x63, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x0e, - 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x1a, 0x3d, - 0x0a, 0x0a, 0x41, 0x6c, 0x62, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x2f, 0x0a, 0x07, - 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x65, 0x63, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, - 0x6e, 0x65, 0x74, 0x73, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x1a, 0x41, 0x0a, - 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, + 0x1a, 0x4a, 0x0a, 0x08, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, + 0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x1a, 0x49, 0x0a, 0x07, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, + 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x18, 0x0a, + 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x1a, 0x47, 0x0a, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, + 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, + 0x1a, 0x30, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, + 0x72, 0x6e, 0x1a, 0x4d, 0x0a, 0x0d, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x64, 0x1a, 0x5e, 0x0a, 0x16, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x63, + 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x44, 0x0a, 0x0f, 0x73, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x63, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x52, 0x0e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x73, 0x1a, 0x5e, 0x0a, 0x16, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x63, + 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x44, 0x0a, 0x0f, 0x73, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x63, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x52, 0x0e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x73, 0x1a, 0x3d, 0x0a, 0x0a, 0x41, 0x6c, 0x62, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x2f, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x65, 0x63, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, - 0x1a, 0x72, 0x0a, 0x07, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x07, 0x73, - 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x65, - 0x63, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x6e, - 0x65, 0x74, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6e, - 0x65, 0x74, 0x73, 0x12, 0x15, 0x0a, 0x06, 0x76, 0x70, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x70, 0x63, 0x49, 0x64, 0x1a, 0x18, 0x0a, 0x06, 0x53, 0x75, - 0x62, 0x6e, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x1a, 0x8f, 0x02, 0x0a, 0x03, 0x41, 0x6c, 0x62, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, - 0x72, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x6e, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6e, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, - 0x18, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x65, - 0x64, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x15, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x65, 0x64, - 0x5a, 0x6f, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, - 0x1a, 0x74, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, - 0x61, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x3c, - 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x65, 0x63, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, - 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, - 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x1a, 0x3c, 0x0a, 0x0d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x35, 0x33, 0x52, - 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x7a, 0x6f, 0x6e, - 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x7a, 0x6f, 0x6e, 0x65, - 0x49, 0x64, 0x22, 0x1a, 0x0a, 0x08, 0x54, 0x61, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x42, 0x1a, - 0x5a, 0x18, 0x77, 0x61, 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2f, 0x62, 0x75, 0x69, 0x6c, 0x74, - 0x69, 0x6e, 0x2f, 0x61, 0x77, 0x73, 0x2f, 0x65, 0x63, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x1a, 0x41, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, + 0x74, 0x73, 0x12, 0x2f, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x65, 0x63, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6e, + 0x65, 0x74, 0x73, 0x1a, 0x72, 0x0a, 0x07, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x36, + 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x65, 0x63, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, + 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x52, 0x07, 0x73, + 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x15, 0x0a, 0x06, 0x76, 0x70, 0x63, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x70, 0x63, 0x49, 0x64, 0x1a, 0x18, 0x0a, + 0x06, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x1a, 0x8f, 0x02, 0x0a, 0x03, 0x41, 0x6c, 0x62, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x6e, 0x73, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6e, 0x73, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x37, 0x0a, 0x18, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x68, 0x6f, + 0x73, 0x74, 0x65, 0x64, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x15, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x48, 0x6f, 0x73, + 0x74, 0x65, 0x64, 0x5a, 0x6f, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x61, 0x6e, 0x61, + 0x67, 0x65, 0x64, 0x1a, 0x74, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, + 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, + 0x6e, 0x12, 0x3c, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x65, 0x63, 0x73, 0x2e, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, + 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x61, 0x73, + 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x61, + 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x18, 0x0a, + 0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x1a, 0x3c, 0x0a, 0x0d, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x35, 0x33, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, + 0x7a, 0x6f, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x7a, + 0x6f, 0x6e, 0x65, 0x49, 0x64, 0x22, 0x1a, 0x0a, 0x08, 0x54, 0x61, 0x73, 0x6b, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x42, 0x1a, 0x5a, 0x18, 0x77, 0x61, 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2f, 0x62, 0x75, + 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x2f, 0x61, 0x77, 0x73, 0x2f, 0x65, 0x63, 0x73, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/builtin/aws/ecs/plugin.proto b/builtin/aws/ecs/plugin.proto index bca41f7ed2c..0d399b3e9b7 100644 --- a/builtin/aws/ecs/plugin.proto +++ b/builtin/aws/ecs/plugin.proto @@ -12,6 +12,8 @@ message Deployment { string service_arn = 3; string target_group_arn = 4; string load_balancer_arn = 5; + string listener_arn = 8; + string cluster = 6; opaqueany.Any resource_state = 7; } diff --git a/builtin/aws/ecs/releaser.go b/builtin/aws/ecs/releaser.go index bd7ce4c50f2..ae275d75d98 100644 --- a/builtin/aws/ecs/releaser.go +++ b/builtin/aws/ecs/releaser.go @@ -7,6 +7,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/elbv2" "github.com/hashicorp/go-hclog" + "github.com/pkg/errors" + "github.com/hashicorp/waypoint-plugin-sdk/component" "github.com/hashicorp/waypoint-plugin-sdk/docs" "github.com/hashicorp/waypoint-plugin-sdk/terminal" @@ -37,11 +39,27 @@ func (r *Releaser) Release( ui terminal.UI, target *Deployment, ) (*Release, error) { - if target.LoadBalancerArn == "" && target.TargetGroupArn == "" { - log.Info("No load-balancer configured") + sg := ui.StepGroup() + defer sg.Wait() + + s := sg.Add("Initializing release...") + defer s.Abort() + + if target.TargetGroupArn == "" { + // This should only happen if someone disables the ALB in the deploy config. + s.Update("Deployment did not define a target group - skipping release.") + s.Done() return &Release{}, nil } + if target.ListenerArn == "" { + // This should only happen if someone disables the ALB in the deploy config. + s.Update("Deployment did not define an ALB listener - skipping release.") + s.Done() + return &Release{}, nil + + } + sess, err := utils.GetSession(&utils.SessionConfig{ Region: r.p.config.Region, Logger: log, @@ -51,107 +69,90 @@ func (r *Releaser) Release( } elbsrv := elbv2.New(sess) - dlb, err := elbsrv.DescribeLoadBalancers(&elbv2.DescribeLoadBalancersInput{ - LoadBalancerArns: []*string{&target.LoadBalancerArn}, - }) - if err != nil { - return nil, err + var hostname string + if r.p.config.ALB != nil && r.p.config.ALB.FQDN != "" { + hostname = r.p.config.ALB.FQDN } - var lb *elbv2.LoadBalancer - - if len(dlb.LoadBalancers) == 0 { - return nil, fmt.Errorf("No load balancers returned by DescribeLoadBalancers") + tgs := []*elbv2.TargetGroupTuple{ + { + TargetGroupArn: &target.TargetGroupArn, + Weight: aws.Int64(100), + }, } - lb = dlb.LoadBalancers[0] - - listeners, err := elbsrv.DescribeListeners(&elbv2.DescribeListenersInput{ - LoadBalancerArn: lb.LoadBalancerArn, + lo, err := elbsrv.DescribeListeners(&elbv2.DescribeListenersInput{ + ListenerArns: []*string{aws.String(target.ListenerArn)}, }) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to describe listener %q", target.ListenerArn) } + if len(lo.Listeners) == 0 { + return nil, errors.Errorf("listener %q not found", target.ListenerArn) + } + listener := lo.Listeners[0] + + if hostname == "" { + + // We need to get the hostname from the existing alb + if target.LoadBalancerArn == "" { + s.Update("load balancer from deployment not specified - cannot determine hostname") + } else { + dlb, err := elbsrv.DescribeLoadBalancers(&elbv2.DescribeLoadBalancersInput{ + LoadBalancerArns: []*string{aws.String(target.LoadBalancerArn)}, + }) + if err != nil { + return nil, errors.Wrapf(err, "failed to describe load balancer %q", target.LoadBalancerArn) + } - var listener *elbv2.Listener + if len(dlb.LoadBalancers) == 0 { + return nil, fmt.Errorf("no load balancers returned by DescribeLoadBalancers") + } - tgs := []*elbv2.TargetGroupTuple{ - { - TargetGroupArn: &target.TargetGroupArn, - Weight: aws.Int64(100), - }, + hostname = *dlb.LoadBalancers[0].DNSName + } } log.Debug("configuring weight 100 for target group", "arn", target.TargetGroupArn) - if len(listeners.Listeners) > 0 { - listener = listeners.Listeners[0] - - def := listener.DefaultActions - - if len(def) > 0 && def[0].ForwardConfig != nil { - for _, tg := range def[0].ForwardConfig.TargetGroups { - // Drain any target groups to 0 but leave them registered. - // This loop also inherently removes any target groups already - // set to 0 that ARE NOT the one we're releasing. - if *tg.Weight > 0 && *tg.TargetGroupArn != target.TargetGroupArn { - tg.Weight = aws.Int64(0) - tgs = append(tgs, tg) - log.Debug("previous target group", "arn", *tg.TargetGroupArn) - } + def := listener.DefaultActions + + if len(def) > 0 && def[0].ForwardConfig != nil { + for _, tg := range def[0].ForwardConfig.TargetGroups { + // Drain any target groups to 0 but leave them registered. + // This loop also inherently removes any target groups already + // set to 0 that ARE NOT the one we're releasing. + if *tg.Weight > 0 && *tg.TargetGroupArn != target.TargetGroupArn { + tg.Weight = aws.Int64(0) + tgs = append(tgs, tg) + log.Debug("previous target group", "arn", *tg.TargetGroupArn) } } + } - log.Debug("modifying load balancer", "tgs", len(tgs)) - _, err = elbsrv.ModifyListener(&elbv2.ModifyListenerInput{ - ListenerArn: listener.ListenerArn, - Port: listener.Port, - Protocol: listener.Protocol, - DefaultActions: []*elbv2.Action{ - { - ForwardConfig: &elbv2.ForwardActionConfig{ - TargetGroups: tgs, - }, - Type: aws.String("forward"), - }, - }, - }) - if err != nil { - return nil, err - } - } else { - log.Info("load-balancer defined", "dns-name", *lb.DNSName) - - lo, err := elbsrv.CreateListener(&elbv2.CreateListenerInput{ - LoadBalancerArn: lb.LoadBalancerArn, - Port: aws.Int64(80), - Protocol: aws.String("HTTP"), - DefaultActions: []*elbv2.Action{ - { - ForwardConfig: &elbv2.ForwardActionConfig{ - TargetGroups: tgs, - }, - Type: aws.String("forward"), + s.Update("Modifying load balancer to introduce new target group %q", target.TargetGroupArn) + log.Debug("modifying load balancer", "tgs", len(tgs)) + _, err = elbsrv.ModifyListener(&elbv2.ModifyListenerInput{ + ListenerArn: aws.String(target.ListenerArn), + DefaultActions: []*elbv2.Action{ + { + ForwardConfig: &elbv2.ForwardActionConfig{ + TargetGroups: tgs, }, + Type: aws.String("forward"), }, - }) - - if err != nil { - return nil, err - } - - listener = lo.Listeners[0] + }, + }) + if err != nil { + return nil, errors.Wrapf(err, "failed to modify listener %q to introduce new target group", target.ListenerArn) } - hostname := *lb.DNSName - - if r.p.config.ALB != nil && r.p.config.ALB.FQDN != "" { - hostname = r.p.config.ALB.FQDN - } + s.Update("Finished ECS release") + s.Done() return &Release{ Url: "http://" + hostname, - LoadBalancerArn: *lb.LoadBalancerArn, + LoadBalancerArn: target.LoadBalancerArn, }, nil } diff --git a/embedJson/gen/platform-aws-ecs.json b/embedJson/gen/platform-aws-ecs.json index f9a3eed81cc..a5482321fe8 100644 --- a/embedJson/gen/platform-aws-ecs.json +++ b/embedJson/gen/platform-aws-ecs.json @@ -5,115 +5,6 @@ "mappers": null, "name": "aws-ecs", "optionalFields": [ - { - "Field": "alb", - "Type": "ecs.ALBConfig", - "Synopsis": "Provides additional configuration for using an ALB with ECS", - "Summary": "", - "Optional": true, - "Default": "", - "EnvVar": "", - "Category": true, - "Example": "", - "SubFields": [ - { - "Field": "certificate", - "Type": "string", - "Synopsis": "the ARN of an AWS Certificate Manager cert to associate with the ALB", - "Summary": "", - "Optional": true, - "Default": "", - "EnvVar": "", - "Category": false, - "Example": "", - "SubFields": null - }, - { - "Field": "domain_name", - "Type": "string", - "Synopsis": "Fully qualified domain name to set for the ALB", - "Summary": "set along with zone_id to have DNS automatically setup for the ALB. this value should include the full hostname and domain name, for instance app.example.com", - "Optional": true, - "Default": "", - "EnvVar": "", - "Category": false, - "Example": "", - "SubFields": null - }, - { - "Field": "ingress_port", - "Type": "int64", - "Synopsis": "Internet-facing traffic port. Defaults to 80 if 'certificate' is unset, 443 if set.", - "Summary": "used to set the ALB listener port, and the ALB security group ingress port", - "Optional": true, - "Default": "", - "EnvVar": "", - "Category": false, - "Example": "", - "SubFields": null - }, - { - "Field": "internal", - "Type": "bool", - "Synopsis": "Whether or not the created ALB should be internal", - "Summary": "used when listener_arn is not set. If set, the created ALB will have a scheme of `internal`, otherwise by default it has a scheme of `internet-facing`.", - "Optional": true, - "Default": "", - "EnvVar": "", - "Category": false, - "Example": "", - "SubFields": null - }, - { - "Field": "listener_arn", - "Type": "string", - "Synopsis": "the ARN on an existing ALB to configure", - "Summary": "when this is set, no ALB or Listener is created. Instead the application is configured by manipulating this existing Listener. This allows users to configure their ALB outside waypoint but still have waypoint hook the application to that ALB", - "Optional": true, - "Default": "", - "EnvVar": "", - "Category": false, - "Example": "", - "SubFields": null - }, - { - "Field": "security_group_ids", - "Type": "list of string", - "Synopsis": "", - "Summary": "", - "Optional": true, - "Default": "", - "EnvVar": "", - "Category": false, - "Example": "", - "SubFields": null - }, - { - "Field": "subnets", - "Type": "list of string", - "Synopsis": "the VPC subnets to use for the ALB", - "Summary": "", - "Optional": true, - "Default": "public subnets in the default VPC", - "EnvVar": "", - "Category": false, - "Example": "", - "SubFields": null - }, - { - "Field": "zone_id", - "Type": "string", - "Synopsis": "Route53 ZoneID to create a DNS record into", - "Summary": "set along with alb.domain_name to have DNS automatically setup for the ALB", - "Optional": true, - "Default": "", - "EnvVar": "", - "Category": false, - "Example": "", - "SubFields": null - } - ] - }, { "Field": "architecture", "Type": "string", @@ -333,6 +224,18 @@ "Example": "", "SubFields": null }, + { + "Field": "listener_arn", + "Type": "string", + "Synopsis": "", + "Summary": "", + "Optional": false, + "Default": "", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + }, { "Field": "load_balancer_arn", "Type": "string", @@ -408,6 +311,115 @@ ], "outputAttrsHelp": "Output attributes can be used in your `waypoint.hcl` as [variables](/waypoint/docs/waypoint-hcl/variables) via [`artifact`](/waypoint/docs/waypoint-hcl/variables/artifact) or [`deploy`](/waypoint/docs/waypoint-hcl/variables/deploy).", "requiredFields": [ + { + "Field": "alb", + "Type": "ecs.ALBConfig", + "Synopsis": "Provides additional configuration for using an ALB with ECS", + "Summary": "", + "Optional": false, + "Default": "", + "EnvVar": "", + "Category": true, + "Example": "", + "SubFields": [ + { + "Field": "certificate", + "Type": "string", + "Synopsis": "the ARN of an AWS Certificate Manager cert to associate with the ALB", + "Summary": "", + "Optional": true, + "Default": "", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + }, + { + "Field": "domain_name", + "Type": "string", + "Synopsis": "Fully qualified domain name to set for the ALB", + "Summary": "set along with zone_id to have DNS automatically setup for the ALB. this value should include the full hostname and domain name, for instance app.example.com", + "Optional": true, + "Default": "", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + }, + { + "Field": "ingress_port", + "Type": "int64", + "Synopsis": "Internet-facing traffic port. Defaults to 80 if 'certificate' is unset, 443 if set.", + "Summary": "used to set the ALB listener port, and the ALB security group ingress port", + "Optional": true, + "Default": "", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + }, + { + "Field": "internal", + "Type": "bool", + "Synopsis": "Whether or not the created ALB should be internal", + "Summary": "used when listener_arn is not set. If set, the created ALB will have a scheme of `internal`, otherwise by default it has a scheme of `internet-facing`.", + "Optional": true, + "Default": "", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + }, + { + "Field": "load_balancer_arn", + "Type": "string", + "Synopsis": "the ARN on an existing ALB to configure", + "Summary": "when this is set, Waypoint will use this ALB instead of creating its own. A target group will still be created for each deployment, and will be added to a listener on the configured ALB port (Waypoint will the listener if it doesn't exist). This allows users to configure their ALB outside Waypoint but still have Waypoint hook the application to that ALB", + "Optional": false, + "Default": "", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + }, + { + "Field": "security_group_ids", + "Type": "list of string", + "Synopsis": "", + "Summary": "", + "Optional": true, + "Default": "", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + }, + { + "Field": "subnets", + "Type": "list of string", + "Synopsis": "the VPC subnets to use for the ALB", + "Summary": "", + "Optional": true, + "Default": "public subnets in the default VPC", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + }, + { + "Field": "zone_id", + "Type": "string", + "Synopsis": "Route53 ZoneID to create a DNS record into", + "Summary": "set along with alb.domain_name to have DNS automatically setup for the ALB", + "Optional": true, + "Default": "", + "EnvVar": "", + "Category": false, + "Example": "", + "SubFields": null + } + ] + }, { "Field": "logging", "Type": "ecs.Logging", diff --git a/website/content/partials/components/platform-aws-ecs.mdx b/website/content/partials/components/platform-aws-ecs.mdx index bc1961437fc..7058f5e5528 100644 --- a/website/content/partials/components/platform-aws-ecs.mdx +++ b/website/content/partials/components/platform-aws-ecs.mdx @@ -22,6 +22,74 @@ deploy { These parameters are used in the [`use` stanza](/waypoint/docs/waypoint-hcl/use) for this plugin. +#### alb (category) + +Provides additional configuration for using an ALB with ECS. + +##### alb.certificate + +The ARN of an AWS Certificate Manager cert to associate with the ALB. + +- Type: **string** +- **Optional** + +##### alb.domain_name + +Fully qualified domain name to set for the ALB. + +Set along with zone_id to have DNS automatically setup for the ALB. this value should include the full hostname and domain name, for instance app.example.com. + +- Type: **string** +- **Optional** + +##### alb.ingress_port + +Internet-facing traffic port. Defaults to 80 if 'certificate' is unset, 443 if set. + +Used to set the ALB listener port, and the ALB security group ingress port. + +- Type: **int64** +- **Optional** + +##### alb.internal + +Whether or not the created ALB should be internal. + +Used when listener_arn is not set. If set, the created ALB will have a scheme of `internal`, otherwise by default it has a scheme of `internet-facing`. + +- Type: **bool** +- **Optional** + +##### alb.load_balancer_arn + +The ARN on an existing ALB to configure. + +When this is set, Waypoint will use this ALB instead of creating its own. A target group will still be created for each deployment, and will be added to a listener on the configured ALB port (Waypoint will the listener if it doesn't exist). This allows users to configure their ALB outside Waypoint but still have Waypoint hook the application to that ALB. + +- Type: **string** + +##### alb.security_group_ids + +- Type: **list of string** +- **Optional** + +##### alb.subnets + +The VPC subnets to use for the ALB. + +- Type: **list of string** +- **Optional** +- Default: public subnets in the default VPC + +##### alb.zone_id + +Route53 ZoneID to create a DNS record into. + +Set along with alb.domain_name to have DNS automatically setup for the ALB. + +- Type: **string** +- **Optional** + #### logging (category) Provides additional configuration for logging flags for ECS. @@ -166,77 +234,6 @@ Environment variables to expose to this container. These parameters are used in the [`use` stanza](/waypoint/docs/waypoint-hcl/use) for this plugin. -#### alb (category) - -Provides additional configuration for using an ALB with ECS. - -- **Optional** - -##### alb.certificate - -The ARN of an AWS Certificate Manager cert to associate with the ALB. - -- Type: **string** -- **Optional** - -##### alb.domain_name - -Fully qualified domain name to set for the ALB. - -Set along with zone_id to have DNS automatically setup for the ALB. this value should include the full hostname and domain name, for instance app.example.com. - -- Type: **string** -- **Optional** - -##### alb.ingress_port - -Internet-facing traffic port. Defaults to 80 if 'certificate' is unset, 443 if set. - -Used to set the ALB listener port, and the ALB security group ingress port. - -- Type: **int64** -- **Optional** - -##### alb.internal - -Whether or not the created ALB should be internal. - -Used when listener_arn is not set. If set, the created ALB will have a scheme of `internal`, otherwise by default it has a scheme of `internet-facing`. - -- Type: **bool** -- **Optional** - -##### alb.listener_arn - -The ARN on an existing ALB to configure. - -When this is set, no ALB or Listener is created. Instead the application is configured by manipulating this existing Listener. This allows users to configure their ALB outside waypoint but still have waypoint hook the application to that ALB. - -- Type: **string** -- **Optional** - -##### alb.security_group_ids - -- Type: **list of string** -- **Optional** - -##### alb.subnets - -The VPC subnets to use for the ALB. - -- Type: **list of string** -- **Optional** -- Default: public subnets in the default VPC - -##### alb.zone_id - -Route53 ZoneID to create a DNS record into. - -Set along with alb.domain_name to have DNS automatically setup for the ALB. - -- Type: **string** -- **Optional** - #### architecture The instruction set CPU architecture that the Amazon ECS supports. Valid values are: "x86_64", "arm64". @@ -391,6 +388,10 @@ Output attributes can be used in your `waypoint.hcl` as [variables](/waypoint/do - Type: **string** +#### listener_arn + +- Type: **string** + #### load_balancer_arn - Type: **string**