Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blue green strategy: add delay before deleting venerable app #569

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions cloudfoundry/managers/v3appdeployers/appsdef.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@ import (
)

type AppDeploy struct {
App resources.Application
EnableSSH types.NullBool
AppPackage resources.Package
Process resources.Process
Mappings []resources.Route
ServiceBindings []resources.ServiceCredentialBinding
EnvVars map[string]interface{}
Path string
BindTimeout time.Duration
StageTimeout time.Duration
StartTimeout time.Duration
Ports []int
App resources.Application
EnableSSH types.NullBool
AppPackage resources.Package
Process resources.Process
Mappings []resources.Route
ServiceBindings []resources.ServiceCredentialBinding
EnvVars map[string]interface{}
Path string
BindTimeout time.Duration
StageTimeout time.Duration
StartTimeout time.Duration
BlueGreenPostStartupWaitTime time.Duration
Ports []int
}

func (a AppDeploy) IsDockerImage() bool {
Expand Down
12 changes: 12 additions & 0 deletions cloudfoundry/managers/v3appdeployers/bluegreen_strategy_v3.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ func (s BlueGreen) Deploy(appDeploy AppDeploy) (AppDeployResponse, error) {
return err
},
},
{
Forward: func(ctx Context) (Context, error) {
time.Sleep(appDeploy.BlueGreenPostStartupWaitTime)
return ctx, nil
},
},
{
Forward: func(ctx Context) (Context, error) {
// Ask CF to stop application (desired state)
Expand Down Expand Up @@ -291,6 +297,12 @@ func (s BlueGreen) Restage(appDeploy AppDeploy) (AppDeployResponse, error) {
return ctx, nil
},
},
{
Forward: func(ctx Context) (Context, error) {
time.Sleep(appDeploy.BlueGreenPostStartupWaitTime)
return ctx, nil
},
},
{
Forward: func(ctx Context) (Context, error) {
return ctx, SafeAppDeletion(*s.client, appDeploy.App.GUID, 5)
Expand Down
14 changes: 10 additions & 4 deletions cloudfoundry/resource_cf_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ import (
// schema.BasicMapReader
// DefaultAppTimeout - Timeout (in seconds) when pushing apps to CF
const (
DefaultAppTimeout = 60
DefaultBindTimeout = 5 * time.Minute
DefaultStageTimeout = 15 * time.Minute
DefaultAppPort = 8080
DefaultAppTimeout = 60
DefaultBindTimeout = 5 * time.Minute
DefaultStageTimeout = 15 * time.Minute
DefaultAppPort = 8080
DefaultBlueGreenPostStartupWaitTime = 10
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should set it to 0 by default in order for it to not impact people who don't want it

)

func resourceApp() *schema.Resource {
Expand Down Expand Up @@ -121,6 +122,11 @@ func resourceApp() *schema.Resource {
Description: "Deployment strategy, default to none but accept blue-green strategy",
ValidateFunc: validateV3Strategy,
},
"bg_post_startup_wait_time": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: DefaultBlueGreenPostStartupWaitTime,
},
"path": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Expand Down
25 changes: 13 additions & 12 deletions cloudfoundry/structures_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,18 +328,19 @@ func ResourceDataToAppDeployV3(d *schema.ResourceData) (v3appdeployers.AppDeploy
}

appDeploy := v3appdeployers.AppDeploy{
App: app,
AppPackage: appPackage,
Process: process,
EnableSSH: enableSSH,
Mappings: mappings,
ServiceBindings: bindings,
Path: d.Get("path").(string),
BindTimeout: DefaultBindTimeout,
StageTimeout: DefaultStageTimeout,
StartTimeout: time.Duration(d.Get("timeout").(int)) * time.Second,
EnvVars: envVars,
Ports: ports,
App: app,
AppPackage: appPackage,
Process: process,
EnableSSH: enableSSH,
Mappings: mappings,
ServiceBindings: bindings,
Path: d.Get("path").(string),
BindTimeout: DefaultBindTimeout,
StageTimeout: DefaultStageTimeout,
StartTimeout: time.Duration(d.Get("timeout").(int)) * time.Second,
BlueGreenPostStartupWaitTime: time.Duration(d.Get("bg_post_startup_wait_time").(int)) * time.Second,
EnvVars: envVars,
Ports: ports,
}

return appDeploy, nil
Expand Down
10 changes: 8 additions & 2 deletions docs/resources/app.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Supported options:
* Description: perform restage/create/restart **with** interruption
* `blue-green`:
* Alias: `blue-green-v2`
* Description: perform restage and create app **without** interruption and rollback if an error occurred (using the "venerable" blue-green pattern commonly used with CAPI v2, requires double the overall app memory available in quota)
* Description: perform restage and create app **without** interruption and rollback if an error occurred (using the "venerable" blue-green pattern commonly used with CAPI v2, requires double the overall app memory available in quota). More details [here](#blue-green-deployment-strategy).
* `rolling`:
* Description: perform restage and create app **without** interruption and rollback if an error occurred (using the `rolling` strategy provided in CAPI v3, requires memory for a single app instance available in quota)

Expand Down Expand Up @@ -166,7 +166,9 @@ The current App can be imported using the `app` GUID, e.g.
terraform import cloudfoundry_app.spring-music a-guid
```

## Update resource using blue-green app id
## blue-green deployment strategy

### Update resource using blue-green app id

This is an example of usage of `id_bg` attribute to update your resource on a changing app id by blue-green:

Expand Down Expand Up @@ -204,3 +206,7 @@ resource "cloudfoundry_network_policy" "my-policy" {

# When you change either test-app-bg or test-app-bg2 this will affect my-policy to be updated because it use `id_bg` instead of id
```

### Known issues and workarounds

* `bg_post_startup_wait_time`: Some apps can take a few moments to be fully up even after Cloudfoundry declared them "started" : database schema migrations, establishing connections to clients... This can cause performance issues if the venerable app is deleted when the new app was not fully "started" (even if Cloudfoundry was showing it started). This adds a preconfigured delay in seconds before killing the venerable app, to let time to the new instance to warmup.