Skip to content

Commit 7186279

Browse files
authored
initialize scaffolding of the ecs plugin (#6557)
Signed-off-by: Hoang Ngo <adlehoang118@gmail.com>
1 parent 8ac9041 commit 7186279

File tree

9 files changed

+1002
-0
lines changed

9 files changed

+1002
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# AWS ECS plugin
2+
3+
## Overview
4+
5+
ECS plugin supports the Deployment for AWS ECS.
6+
7+
> [!CAUTION]
8+
> Currently, this is alpha status.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2026 The PipeCD Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package config
16+
17+
// ECSApplicationSpec defines the application specification for ECS plugin.
18+
type ECSApplicationSpec struct {
19+
Input ECSDeploymentInput `json:"input"`
20+
}
21+
22+
// ECSDeploymentInput defines the input for ECS deployment.
23+
type ECSDeploymentInput struct {
24+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2026 The PipeCD Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package config
16+
17+
// ECSDeployTargetConfig represents the deployment target configuration for ECS plugin.
18+
type ECSDeployTargetConfig struct {
19+
// Region is the AWS region where the ECS cluster is located
20+
// (e.g., "us-west-2").
21+
Region string `json:"region"`
22+
23+
// Profile is the AWS profile to use from the credentials file
24+
// If empty, uses the default profile or "default" if AWS_PROFILE env var is not set
25+
Profile string `json:"profile,omitempty"`
26+
27+
// CredentialsFile is the path to the AWS shared credentials file
28+
// (e.g., "~/.aws/credentials")
29+
// If empty, uses the default location
30+
CredentialsFile string `json:"credentialsFile,omitempty"`
31+
32+
// RoleARN is the IAM role ARN to assume when accessing AWS resources
33+
// (e.g., "arn:aws:iam::123456789:role/ecs-deployment-role").
34+
// Required when assuming a role across accounts
35+
RoleARN string `json:"roleARN,omitempty"`
36+
37+
// TokenFile is the path to the OIDC token file for web identity federation.
38+
// Required when RoleARN is set for OIDC-based authentication
39+
TokenFile string `json:"tokenFile,omitempty"`
40+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2026 The PipeCD Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package config
16+
17+
// ECSPluginConfig holds the configuration for the ECS deployment plugin.
18+
type ECSPluginConfig struct {
19+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2026 The PipeCD Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package deployment
16+
17+
import (
18+
sdk "github.com/pipe-cd/piped-plugin-sdk-go"
19+
)
20+
21+
const (
22+
// StageECSSync represents the ECS sync stage.
23+
StageECSSync = "ECS_SYNC"
24+
25+
// StageECSPrimaryRollout represents the ECS primary rollout stage.
26+
StageECSPrimaryRollout = "ECS_PRIMARY_ROLLOUT"
27+
28+
// StageECSCanaryRollout represents the ECS canary rollout stage.
29+
StageECSCanaryRollout = "ECS_CANARY_ROLLOUT"
30+
31+
// StageECSCanaryClean represents the ECS canary clean stage.
32+
StageECSCanaryClean = "ECS_CANARY_CLEAN"
33+
34+
// StageECSTrafficRouting represents the ECS traffic routing stage.
35+
StageECSTrafficRouting = "ECS_TRAFFIC_ROUTING"
36+
37+
// StageECSRollback represents the ECS rollback stage.
38+
StageECSRollback = "ECS_ROLLBACK"
39+
)
40+
41+
var allStages = []string{
42+
StageECSSync,
43+
StageECSPrimaryRollout,
44+
StageECSCanaryRollout,
45+
StageECSCanaryClean,
46+
StageECSTrafficRouting,
47+
StageECSRollback,
48+
}
49+
50+
const (
51+
StageECSSyncDescription = "Sync ECS service with given task definition"
52+
StageECSPrimaryRolloutDescription = "Roll out new task set as primary"
53+
StageECSCanaryRolloutDescription = "Roll out new task set as canary"
54+
StageECSCanaryCleanDescription = "Clean up canary task set"
55+
StageECSTrafficRoutingDescription = "Route traffic between primary and canary task sets"
56+
StageECSRollbackDescription = "Rollback to previous task set"
57+
)
58+
59+
func buildQuickSyncPipeline(autoRollback bool) []sdk.QuickSyncStage {
60+
out := []sdk.QuickSyncStage{
61+
{
62+
Name: StageECSSync,
63+
Description: StageECSSyncDescription,
64+
Rollback: false,
65+
},
66+
}
67+
68+
if autoRollback {
69+
out = append(out, sdk.QuickSyncStage{
70+
Name: StageECSRollback,
71+
Description: StageECSRollbackDescription,
72+
Rollback: true,
73+
})
74+
}
75+
76+
return out
77+
}
78+
79+
func buildPipelineStages(input *sdk.BuildPipelineSyncStagesInput) []sdk.PipelineStage {
80+
stages := input.Request.Stages
81+
82+
out := make([]sdk.PipelineStage, 0, len(stages)+1)
83+
84+
for _, s := range stages {
85+
out = append(out, sdk.PipelineStage{
86+
Name: s.Name,
87+
Index: s.Index,
88+
Rollback: false,
89+
})
90+
}
91+
92+
if input.Request.Rollback {
93+
out = append(out, sdk.PipelineStage{
94+
Name: StageECSRollback,
95+
Index: len(stages) + 1,
96+
Rollback: true,
97+
})
98+
}
99+
100+
return out
101+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Copyright 2026 The PipeCD Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package deployment
16+
17+
import (
18+
"context"
19+
"errors"
20+
21+
ecsconfig "github.com/pipe-cd/pipecd/pkg/app/pipedv1/plugin/ecs/config"
22+
sdk "github.com/pipe-cd/piped-plugin-sdk-go"
23+
)
24+
25+
var _ sdk.DeploymentPlugin[ecsconfig.ECSPluginConfig, ecsconfig.ECSDeployTargetConfig, ecsconfig.ECSApplicationSpec] = (*ECSPlugin)(nil)
26+
27+
var ErrUnsupportedStage = errors.New("unsupported stage")
28+
29+
type ECSPlugin struct {
30+
}
31+
32+
// FetchDefinedStages returns the list of stages that the plugin can execute.
33+
func (p *ECSPlugin) FetchDefinedStages() []string {
34+
return allStages
35+
}
36+
37+
// BuildQuickSyncStages builds the stages that will be executed during the quick sync process.
38+
func (p *ECSPlugin) BuildQuickSyncStages(
39+
ctx context.Context,
40+
cfg *ecsconfig.ECSPluginConfig,
41+
input *sdk.BuildQuickSyncStagesInput,
42+
) (*sdk.BuildQuickSyncStagesResponse, error) {
43+
return &sdk.BuildQuickSyncStagesResponse{
44+
Stages: buildQuickSyncPipeline(input.Request.Rollback),
45+
}, nil
46+
}
47+
48+
// BuildPipelineSyncStages builds the stages that will be executed by the plugin.
49+
func (p *ECSPlugin) BuildPipelineSyncStages(
50+
_ context.Context,
51+
_ *ecsconfig.ECSPluginConfig,
52+
input *sdk.BuildPipelineSyncStagesInput,
53+
) (*sdk.BuildPipelineSyncStagesResponse, error) {
54+
return &sdk.BuildPipelineSyncStagesResponse{
55+
Stages: buildPipelineStages(input),
56+
}, nil
57+
}
58+
59+
// ExecuteStage executes the given stage.
60+
func (p *ECSPlugin) ExecuteStage(
61+
ctx context.Context,
62+
cfg *ecsconfig.ECSPluginConfig,
63+
deployTargets []*sdk.DeployTarget[ecsconfig.ECSDeployTargetConfig],
64+
input *sdk.ExecuteStageInput[ecsconfig.ECSApplicationSpec],
65+
) (*sdk.ExecuteStageResponse, error) {
66+
switch input.Request.StageName {
67+
default:
68+
return nil, ErrUnsupportedStage
69+
}
70+
}
71+
72+
// DetermineVersions determines the versions of the resources that will be deployed.
73+
func (p *ECSPlugin) DetermineVersions(
74+
ctx context.Context,
75+
cfg *ecsconfig.ECSPluginConfig,
76+
input *sdk.DetermineVersionsInput[ecsconfig.ECSApplicationSpec],
77+
) (*sdk.DetermineVersionsResponse, error) {
78+
return &sdk.DetermineVersionsResponse{
79+
// TODO: Implement the logic to determine the versions of the resources that will be deployed.
80+
// This is just a placeholder
81+
Versions: []sdk.ArtifactVersion{
82+
{
83+
Version: "latest",
84+
Name: "ecs-task",
85+
URL: "",
86+
},
87+
},
88+
}, nil
89+
}
90+
91+
// DetermineStrategy determines the strategy to deploy the resources.
92+
func (p *ECSPlugin) DetermineStrategy(
93+
ctx context.Context,
94+
cfg *ecsconfig.ECSPluginConfig,
95+
input *sdk.DetermineStrategyInput[ecsconfig.ECSApplicationSpec],
96+
) (*sdk.DetermineStrategyResponse, error) {
97+
// Use quick sync as the default strategy for ECS deployment.
98+
return &sdk.DetermineStrategyResponse{
99+
Strategy: sdk.SyncStrategyQuickSync,
100+
Summary: "Use quick sync strategy for ECS deployment (work as ECS_SYNC stage)",
101+
}, nil
102+
}

pkg/app/pipedv1/plugin/ecs/go.mod

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
module github.com/pipe-cd/pipecd/pkg/app/pipedv1/plugin/ecs
2+
3+
go 1.25.0
4+
5+
require github.com/pipe-cd/piped-plugin-sdk-go v0.3.0
6+
7+
require (
8+
cloud.google.com/go v0.112.1 // indirect
9+
cloud.google.com/go/compute/metadata v0.3.0 // indirect
10+
cloud.google.com/go/profiler v0.3.1 // indirect
11+
github.com/beorn7/perks v1.0.1 // indirect
12+
github.com/cespare/xxhash/v2 v2.2.0 // indirect
13+
github.com/coreos/go-oidc/v3 v3.11.0 // indirect
14+
github.com/creasty/defaults v1.6.0 // indirect
15+
github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect
16+
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
17+
github.com/go-logr/logr v1.4.2 // indirect
18+
github.com/go-logr/stdr v1.2.2 // indirect
19+
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
20+
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
21+
github.com/golang/protobuf v1.5.4 // indirect
22+
github.com/google/pprof v0.0.0-20221103000818-d260c55eee4c // indirect
23+
github.com/google/s2a-go v0.1.7 // indirect
24+
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
25+
github.com/googleapis/gax-go/v2 v2.12.2 // indirect
26+
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
27+
github.com/inconshreveable/mousetrap v1.1.0 // indirect
28+
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
29+
github.com/pipe-cd/pipecd v0.54.0-rc1.0.20250912082650-0b949bb7aac9 // indirect
30+
github.com/prometheus/client_golang v1.12.1 // indirect
31+
github.com/prometheus/client_model v0.5.0 // indirect
32+
github.com/prometheus/common v0.32.1 // indirect
33+
github.com/prometheus/procfs v0.7.3 // indirect
34+
github.com/spf13/cobra v1.9.1 // indirect
35+
github.com/spf13/pflag v1.0.6 // indirect
36+
go.opencensus.io v0.24.0 // indirect
37+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
38+
go.opentelemetry.io/otel v1.28.0 // indirect
39+
go.opentelemetry.io/otel/metric v1.28.0 // indirect
40+
go.opentelemetry.io/otel/trace v1.28.0 // indirect
41+
go.uber.org/atomic v1.11.0 // indirect
42+
go.uber.org/multierr v1.6.0 // indirect
43+
go.uber.org/zap v1.19.1 // indirect
44+
go.yaml.in/yaml/v2 v2.4.2 // indirect
45+
golang.org/x/crypto v0.36.0 // indirect
46+
golang.org/x/net v0.38.0 // indirect
47+
golang.org/x/oauth2 v0.30.0 // indirect
48+
golang.org/x/sync v0.16.0 // indirect
49+
golang.org/x/sys v0.31.0 // indirect
50+
golang.org/x/text v0.23.0 // indirect
51+
golang.org/x/time v0.5.0 // indirect
52+
google.golang.org/api v0.169.0 // indirect
53+
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
54+
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
55+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
56+
google.golang.org/grpc v1.64.1 // indirect
57+
google.golang.org/protobuf v1.34.2 // indirect
58+
sigs.k8s.io/yaml v1.5.0 // indirect
59+
)

0 commit comments

Comments
 (0)