Skip to content
Merged
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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file.
The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- AWS ownership tagging support via `IaCProviderOwnership`, using the
`workflow-owner` tag key for ARN-backed resources.
- Manifest parity coverage for root and embedded `iacServices` declarations.

### Changed

- `minEngineVersion` now requires workflow `0.69.1+`, matching the
ownership-service contract.

## [2.0.0-rc1] — 2026-05-17

### Breaking changes (workflow#699)
Expand Down
4 changes: 3 additions & 1 deletion cmd/workflow-plugin-aws/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"license": "MIT",
"type": "external",
"tier": "community",
"minEngineVersion": "0.68.2",
"minEngineVersion": "0.69.1",
"iacServices": [
"workflow.plugin.external.iac.IaCProviderRequired",
"workflow.plugin.external.iac.IaCProviderEnumerator",
Expand All @@ -16,6 +16,8 @@
"workflow.plugin.external.iac.IaCProviderValidator",
"workflow.plugin.external.iac.IaCProviderDriftConfigDetector",
"workflow.plugin.external.iac.IaCProviderRequirementMapper",
"workflow.plugin.external.iac.IaCProviderRegionLister",
"workflow.plugin.external.iac.IaCProviderOwnership",
"workflow.plugin.external.iac.ResourceDriver",
"workflow.plugin.external.iac.IaCStateBackend"
],
Expand Down
11 changes: 6 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module github.com/GoCodeAlone/workflow-plugin-aws
go 1.26.0

require (
github.com/GoCodeAlone/workflow v0.68.2
github.com/aws/aws-sdk-go-v2 v1.41.7
github.com/GoCodeAlone/workflow v0.69.7
github.com/aws/aws-sdk-go-v2 v1.41.9
github.com/aws/aws-sdk-go-v2/config v1.32.16
github.com/aws/aws-sdk-go-v2/credentials v1.19.15
github.com/aws/aws-sdk-go-v2/service/acm v1.32.1
Expand All @@ -19,6 +19,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.54.6
github.com/aws/aws-sdk-go-v2/service/iam v1.53.7
github.com/aws/aws-sdk-go-v2/service/rds v1.115.0
github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.32.2
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.5
github.com/aws/aws-sdk-go-v2/service/s3 v1.97.2
github.com/aws/aws-sdk-go-v2/service/sts v1.42.0
Expand Down Expand Up @@ -46,8 +47,8 @@ require (
github.com/armon/go-metrics v0.4.1 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.25 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.25 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.12 // indirect
Expand All @@ -57,7 +58,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/signin v1.0.10 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.30.16 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20 // indirect
github.com/aws/smithy-go v1.25.1 // indirect
github.com/aws/smithy-go v1.26.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.24.4 // indirect
github.com/bytedance/gopkg v0.1.4 // indirect
Expand Down
22 changes: 12 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ github.com/GoCodeAlone/modular/modules/jsonschema v1.17.0 h1:zoWioqUvuNNDfnjHA1s
github.com/GoCodeAlone/modular/modules/jsonschema v1.17.0/go.mod h1:GDU/jsD6AddmXKedj0wZwieUIaQsTBSGMzuj+XHXMrw=
github.com/GoCodeAlone/modular/modules/reverseproxy/v2 v2.10.0 h1:+2M/ecyCxDiXfJM4ibcERuu/BBeIbLTQNcVgRsllR64=
github.com/GoCodeAlone/modular/modules/reverseproxy/v2 v2.10.0/go.mod h1:tlVH1mA5yuU8CB7R7+HXIRaBixZoNid6h+5tew5u3FU=
github.com/GoCodeAlone/workflow v0.68.2 h1:U0ksQOkIwDReuw+nz4kRoCeYwahoBaItqLzwYIRm758=
github.com/GoCodeAlone/workflow v0.68.2/go.mod h1:4UwFYm1cM8a/AvGNb1CZAuob0b0gq7552sxcNMdDALA=
github.com/GoCodeAlone/workflow v0.69.7 h1:LgRTJtbicyOeucyQmHw/F7rjfYP8T15C01p7jNm6kP0=
github.com/GoCodeAlone/workflow v0.69.7/go.mod h1:nWB662ILBUUjL2NBlj7RchyiI4CZ2+UxnpQcbIA2tWE=
github.com/GoCodeAlone/yaegi v0.17.2 h1:WK6Y6e0t1a6U7r+S2dN3CGWW1PizYD3zO0zneToZPxM=
github.com/GoCodeAlone/yaegi v0.17.2/go.mod h1:z5Pr6Wse6QJcQvpgxTxzMAevFarH0N37TG88Y9dprx0=
github.com/IBM/sarama v1.47.0 h1:GcQFEd12+KzfPYeLgN69Fh7vLCtYRhVIx0rO4TZO318=
Expand All @@ -48,8 +48,8 @@ github.com/antithesishq/antithesis-sdk-go v0.7.0 h1:uWDG8BqLD1lI2ps38WDz2vXflrTX
github.com/antithesishq/antithesis-sdk-go v0.7.0/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
github.com/aws/aws-sdk-go-v2 v1.41.7 h1:DWpAJt66FmnnaRIOT/8ASTucrvuDPZASqhhLey6tLY8=
github.com/aws/aws-sdk-go-v2 v1.41.7/go.mod h1:4LAfZOPHNVNQEckOACQx60Y8pSRjIkNZQz1w92xpMJc=
github.com/aws/aws-sdk-go-v2 v1.41.9 h1:/rYeyO2+HrMztAmxAq9++XJtFMqSIpSsNA0yDGALYq4=
github.com/aws/aws-sdk-go-v2 v1.41.9/go.mod h1:+HsoOEX80qAVUitj1A2DhCNTjmb3edVyuDypb6LNEeo=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 h1:eBMB84YGghSocM7PsjmmPffTa+1FBUeNvGvFou6V/4o=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8/go.mod h1:lyw7GFp3qENLh7kwzf7iMzAxDn+NzjXEAGjKS2UOKqI=
github.com/aws/aws-sdk-go-v2/config v1.32.16 h1:Q0iQ7quUgJP0F/SCRTieScnaMdXr9h/2+wze1u3cNeM=
Expand All @@ -58,10 +58,10 @@ github.com/aws/aws-sdk-go-v2/credentials v1.19.15 h1:fyvgWTszojq8hEnMi8PPBTvZdTt
github.com/aws/aws-sdk-go-v2/credentials v1.19.15/go.mod h1:gJiYyMOjNg8OEdRWOf3CrFQxM2a98qmrtjx1zuiQfB8=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22 h1:IOGsJ1xVWhsi+ZO7/NW8OuZZBtMJLZbk4P5HDjJO0jQ=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22/go.mod h1:b+hYdbU+jGKfXE8kKM6g1+h+L/Go3vMvzlxBsiuGsxg=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23 h1:GpT/TrnBYuE5gan2cZbTtvP+JlHsutdmlV2YfEyNde0=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23/go.mod h1:xYWD6BS9ywC5bS3sz9Xh04whO/hzK2plt2Zkyrp4JuA=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23 h1:bpd8vxhlQi2r1hiueOw02f/duEPTMK59Q4QMAoTTtTo=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23/go.mod h1:15DfR2nw+CRHIk0tqNyifu3G1YdAOy68RftkhMDDwYk=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.25 h1:Uii3frf9ztec/ABM2/FSH9/z7PLzxfpG8h4RpkUFflQ=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.25/go.mod h1:G6kntsA2GorAxDPbap6xgB2F+amSLUF8GJTi7PUoX44=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.25 h1:r1+/l6m+WaUJF9HISEsNOLHSNj5EXYQxK8VX6Cz9NlA=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.25/go.mod h1:cKf+D+NMDK1LndD7BowHbBZPgR9V0/5HubH0PFWvA+c=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23 h1:FPXsW9+gMuIeKmz7j6ENWcWtBGTe1kH8r9thNt5Uxx4=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23/go.mod h1:7J8iGMdRKk6lw2C+cMIphgAnT8uTwBwNOsGkyOCm80U=
github.com/aws/aws-sdk-go-v2/service/acm v1.32.1 h1:KAK08un+8LhHlG6OEUmDTqFpQth2tYA+6EX0NNocgl4=
Expand Down Expand Up @@ -98,6 +98,8 @@ github.com/aws/aws-sdk-go-v2/service/kinesis v1.43.5 h1:LxgRVyuY+5DEPSX7kmin/V7t
github.com/aws/aws-sdk-go-v2/service/kinesis v1.43.5/go.mod h1:eUebEBEqVfOwEyDDDbGauH4PNqDCuepRvTaNbJeWr5w=
github.com/aws/aws-sdk-go-v2/service/rds v1.115.0 h1:oNl6YghOtxu3MiFk1tQ86QlrYMIEJazGUDbBCg9nxLA=
github.com/aws/aws-sdk-go-v2/service/rds v1.115.0/go.mod h1:JBRYWpz5oXQtHgQC+X8LX9lh0FBCwRHJlWEIT+TTLaE=
github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.32.2 h1:LC3ALu3cQVkh7umM+x8zE0UxVWS/gllEt5VuNchyUW8=
github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.32.2/go.mod h1:gBZ5iZqcOsvR8pIZS0CsbGfoUUEyiS8qjxQXRjdsxZA=
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.5 h1:Z+/OLsb85Kpq7TVLCspskqePaf68Tdv6GfmJP4kH6i0=
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.5/go.mod h1:TmxGowuBYwjmHFOsEDxaZdsQE62JJzOmtiWafTi/czg=
github.com/aws/aws-sdk-go-v2/service/s3 v1.97.2 h1:MRNiP6nqa20aEl8fQ6PJpEq11b2d40b16sm4WD7QgMU=
Expand All @@ -110,8 +112,8 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20 h1:oK/njaL8GtyEihkWMD4k3Vg
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20/go.mod h1:JHs8/y1f3zY7U5WcuzoJ/yAYGYtNIVPKLIbp61euvmg=
github.com/aws/aws-sdk-go-v2/service/sts v1.42.0 h1:ks8KBcZPh3PYISr5dAiXCM5/Thcuxk8l+PG4+A0exds=
github.com/aws/aws-sdk-go-v2/service/sts v1.42.0/go.mod h1:pFw33T0WLvXU3rw1WBkpMlkgIn54eCB5FYLhjDc9Foo=
github.com/aws/smithy-go v1.25.1 h1:J8ERsGSU7d+aCmdQur5Txg6bVoYelvQJgtZehD12GkI=
github.com/aws/smithy-go v1.25.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
github.com/aws/smithy-go v1.26.0 h1:9ouqbi+NyKP7fV3Te7UElCwdAb6Y8uk7LGwPE5tVe/s=
github.com/aws/smithy-go v1.26.0/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down
28 changes: 28 additions & 0 deletions internal/host_conformance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"os"
"os/exec"
"path/filepath"
"reflect"
"runtime"
"sort"
"testing"
"time"

Expand Down Expand Up @@ -139,6 +141,32 @@ func capabilitiesHasResource(capabilities *pb.CapabilitiesResponse, resourceType
return false
}

func TestEmbeddedManifestIaCServicesMatchRootManifest(t *testing.T) {
repoRoot := hostConformanceRepoRoot(t)
rootServices := readManifestIaCServices(t, filepath.Join(repoRoot, "plugin.json"))
embeddedServices := readManifestIaCServices(t, filepath.Join(repoRoot, "cmd", "workflow-plugin-aws", "plugin.json"))
sort.Strings(rootServices)
sort.Strings(embeddedServices)
if !reflect.DeepEqual(rootServices, embeddedServices) {
t.Fatalf("embedded manifest iacServices = %v, want root manifest services %v", embeddedServices, rootServices)
}
}

func readManifestIaCServices(t *testing.T, path string) []string {
t.Helper()
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read %s: %v", path, err)
}
var manifest struct {
IaCServices []string `json:"iacServices"`
}
if err := json.Unmarshal(data, &manifest); err != nil {
t.Fatalf("parse %s: %v", path, err)
}
return append([]string(nil), manifest.IaCServices...)
}

// TestCapabilityParity_IaCStateBackends asserts that every iac.state backend
// name declared in plugin.json capabilities.iacStateBackends is actually
// served by the plugin — i.e. returned by NewIaCServer().ListBackendNames.
Expand Down
38 changes: 38 additions & 0 deletions internal/iacserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type awsIaCServer struct {
pb.UnimplementedIaCProviderDriftConfigDetectorServer
pb.UnimplementedIaCProviderRequirementMapperServer
pb.UnimplementedIaCProviderRegionListerServer
pb.UnimplementedIaCProviderOwnershipServer
pb.UnimplementedResourceDriverServer
pb.UnimplementedIaCStateBackendServer

Expand Down Expand Up @@ -89,6 +90,7 @@ var (
_ pb.ResourceDriverServer = (*awsIaCServer)(nil)
_ pb.IaCProviderRequirementMapperServer = (*awsIaCServer)(nil)
_ pb.IaCProviderRegionListerServer = (*awsIaCServer)(nil)
_ pb.IaCProviderOwnershipServer = (*awsIaCServer)(nil)
// awsIaCServer also SERVES the typed IaC state-backend contract (s3
// backend). The SDK serve hook auto-registers this via type-assertion at
// plugin startup — see cmd/workflow-plugin-aws/main.go.
Expand Down Expand Up @@ -250,6 +252,42 @@ func (s *awsIaCServer) DetectDriftWithSpecs(ctx context.Context, req *pb.DetectD
return &pb.DetectDriftWithSpecsResponse{Drifts: pbDrifts}, nil
}

// ── Optional: Ownership ───────────────────────────────────────────────────

func (s *awsIaCServer) GetOwner(ctx context.Context, req *pb.GetOwnerRequest) (*pb.GetOwnerResponse, error) {
owner, err := s.provider.GetOwner(ctx, refFromPB(req.GetRef()))
if err != nil {
return nil, err
}
return &pb.GetOwnerResponse{Owner: owner.Owner, Source: owner.Source}, nil
}

func (s *awsIaCServer) SetOwner(ctx context.Context, req *pb.SetOwnerRequest) (*pb.SetOwnerResponse, error) {
if err := s.provider.SetOwner(ctx, refFromPB(req.GetRef()), req.GetOwner()); err != nil {
return nil, err
}
return &pb.SetOwnerResponse{}, nil
}

func (s *awsIaCServer) ListOwners(ctx context.Context, req *pb.ListOwnersRequest) (*pb.ListOwnersResponse, error) {
owners, err := s.provider.ListOwners(ctx, interfaces.OwnerFilter{
Owner: req.GetOwner(),
ResourceType: req.GetResourceType(),
})
if err != nil {
return nil, err
}
out := make([]*pb.OwnedResource, 0, len(owners))
for _, owner := range owners {
out = append(out, &pb.OwnedResource{
Ref: refToPB(owner.Ref),
Owner: owner.Owner,
Source: owner.Source,
})
}
return &pb.ListOwnersResponse{Resources: out}, nil
}

// ── Marshalling helpers (pb ↔ Go) ───────────────────────────────────────────
//
// These mirror the inverse-direction helpers in cmd/wfctl/iac_typed_adapter.go
Expand Down
24 changes: 16 additions & 8 deletions internal/iacserver_mapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,16 +185,24 @@ func TestPluginManifestAdvertisesRequirementMapper(t *testing.T) {
if err := json.Unmarshal(data, &manifest); err != nil {
t.Fatalf("parse plugin.json: %v", err)
}
if manifest.MinEngineVersion != "0.68.2" {
t.Fatalf("minEngineVersion = %q, want 0.68.2", manifest.MinEngineVersion)
}
const mapperService = "workflow.plugin.external.iac.IaCProviderRequirementMapper"
for _, svc := range manifest.IaCServices {
if svc == mapperService {
return
if manifest.MinEngineVersion != "0.69.1" {
t.Fatalf("minEngineVersion = %q, want 0.69.1", manifest.MinEngineVersion)
}
for _, want := range []string{
"workflow.plugin.external.iac.IaCProviderRequirementMapper",
"workflow.plugin.external.iac.IaCProviderOwnership",
} {
found := false
for _, svc := range manifest.IaCServices {
if svc == want {
found = true
break
}
}
if !found {
t.Fatalf("iacServices missing %s: %v", want, manifest.IaCServices)
}
}
t.Fatalf("iacServices missing %s: %v", mapperService, manifest.IaCServices)
}

func newMapperTestConn(t *testing.T) *grpc.ClientConn {
Expand Down
1 change: 1 addition & 0 deletions internal/iacserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func TestIaCServer_CompileTimeGuards(t *testing.T) {
// If any of the interface assertions below fail to compile, this file will not build.
var _ pb.IaCProviderRequiredServer = (*awsIaCServer)(nil)
var _ pb.IaCProviderDriftDetectorServer = (*awsIaCServer)(nil)
var _ pb.IaCProviderOwnershipServer = (*awsIaCServer)(nil)
var _ pb.ResourceDriverServer = (*awsIaCServer)(nil)
}

Expand Down
3 changes: 2 additions & 1 deletion plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"license": "MIT",
"type": "external",
"tier": "community",
"minEngineVersion": "0.68.2",
"minEngineVersion": "0.69.1",
"required_secrets": [
{
"name": "AWS_ACCESS_KEY_ID",
Expand All @@ -31,6 +31,7 @@
"workflow.plugin.external.iac.IaCProviderDriftConfigDetector",
"workflow.plugin.external.iac.IaCProviderRequirementMapper",
"workflow.plugin.external.iac.IaCProviderRegionLister",
"workflow.plugin.external.iac.IaCProviderOwnership",
"workflow.plugin.external.iac.ResourceDriver",
"workflow.plugin.external.iac.IaCStateBackend"
],
Expand Down
Loading
Loading