Skip to content

Commit

Permalink
Merge pull request #773 from kayac/vpc-lattice
Browse files Browse the repository at this point in the history
Supports VPC Lattice integration.
  • Loading branch information
fujiwara authored Nov 19, 2024
2 parents 93928fc + 6a60f2a commit 2cf655e
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 21 deletions.
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,51 @@ $ ecspresso run --no-ebs-delete-on-termination

For tasks run by ECS services, EBS volumes are always deleted when the task stops. This is an ECS specification that ecspresso cannot override.


### VPC Lattice support

ecspresso supports [VPC Lattice](https://aws.amazon.com/vpc/lattice/) integration.

1. Define `portMappings` in the task definition. The `name` field is required.
```json
{
"containerDefinitions": [
{
"name": "webserver",
"portMappings": [
{
"name": "web-80-tcp",
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp",
"appProtocol": "http"
}
],
```

2. Define `vpcLatticeConfigurations` in the service definition. The `portName`, `roleArn`, and `targetGroupArn` fields are required.`

- The `portName` must match the `name` field of the `portMappings` in the task definition.
- The `roleArn` is the IAM role that the ECS service assumes to call the VPC Lattice API.
- The role must have the `ecs.amazonaws.com` service principal.
- The role should have the `AmazonECSInfrastructureRolePolicyForVpcLattice` policy or equivalent permissions.
- The `targetGroupArn` is the ARN of the VPC Lattice target group.

```json
{
"vpcLatticeConfigurations": [
{
"portName": "web-80-tcp",
"roleArn": "arn:aws:iam::123456789012:role/ecsInfrastructureRole",
"targetGroupArn": "arn:aws:vpc-lattice:ap-northeast-1:123456789012:targetgroup/tg-009147df264a0bacb"
}
],
```

ecspresso doesn't create or modify any VPC Lattice resources. You must create and associate a VPC Lattice target group with the ECS service.

See also [Use Amazon VPC Lattice to connect, observe, and secure your Amazon ECS services](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-vpc-lattice.html).

### How to check diff and verify service/task definitions before deploy.

ecspresso supports `diff` and `verify` commands.
Expand Down
1 change: 1 addition & 0 deletions create.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func (d *App) createService(ctx context.Context, opt DeployOption) error {
Tags: svd.Tags,
TaskDefinition: aws.String(tdArn),
VolumeConfigurations: svd.VolumeConfigurations,
VpcLatticeConfigurations: svd.VpcLatticeConfigurations,
}
if _, err := d.ecs.CreateService(ctx, createServiceInput); err != nil {
return fmt.Errorf("failed to create service: %w", err)
Expand Down
9 changes: 9 additions & 0 deletions deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,19 @@ func svToUpdateServiceInput(sv *Service) *ecs.UpdateServiceInput {
ServiceConnectConfiguration: sv.ServiceConnectConfiguration,
ServiceRegistries: sv.ServiceRegistries,
VolumeConfigurations: sv.VolumeConfigurations,
VpcLatticeConfigurations: sv.VpcLatticeConfigurations,
}
if sv.SchedulingStrategy == types.SchedulingStrategyDaemon {
in.PlacementStrategy = nil
}

// explicitly set empty slice (to remove the attribute)
if len(sv.VolumeConfigurations) == 0 {
in.VolumeConfigurations = []types.ServiceVolumeConfiguration{}
}
if len(sv.VpcLatticeConfigurations) == 0 {
in.VpcLatticeConfigurations = []types.VpcLatticeConfiguration{}
}
return in
}

Expand Down
7 changes: 7 additions & 0 deletions diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,13 @@ func ServiceDefinitionForDiff(sv *Service) *ServiceForDiff {
sort.SliceStable(sv.Tags, func(i, j int) bool {
return aws.ToString(sv.Tags[i].Key) < aws.ToString(sv.Tags[j].Key)
})
sort.SliceStable(sv.VolumeConfigurations, func(i, j int) bool {
return aws.ToString(sv.VolumeConfigurations[i].Name) < aws.ToString(sv.VolumeConfigurations[j].Name)
})
sort.SliceStable(sv.VpcLatticeConfigurations, func(i, j int) bool {
return aws.ToString(sv.VpcLatticeConfigurations[i].PortName) < aws.ToString(sv.VpcLatticeConfigurations[j].PortName)
})

if sv.LaunchType == types.LaunchTypeFargate && sv.PlatformVersion == nil {
sv.PlatformVersion = aws.String("LATEST")
}
Expand Down
10 changes: 10 additions & 0 deletions ecspresso.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
"github.com/aws/aws-sdk-go-v2/service/iam"
"github.com/aws/aws-sdk-go-v2/service/servicediscovery"
"github.com/aws/aws-sdk-go-v2/service/vpclattice"
"github.com/aws/smithy-go"
"github.com/goccy/go-yaml"
"github.com/samber/lo"
Expand Down Expand Up @@ -57,6 +58,7 @@ type Service struct {
types.Service
ServiceConnectConfiguration *types.ServiceConnectConfiguration
VolumeConfigurations []types.ServiceVolumeConfiguration
VpcLatticeConfigurations []types.VpcLatticeConfiguration
DesiredCount *int32
}

Expand Down Expand Up @@ -105,6 +107,12 @@ func (d *App) newServiceFromTypes(ctx context.Context, in types.Service) (*Servi
sv.VolumeConfigurations = dp.VolumeConfigurations
}

// VPC Lattice
if dp.VpcLatticeConfigurations != nil {
d.Log("[DEBUG] VpcLatticeConfigurations: %#v", dp.VpcLatticeConfigurations)
sv.VpcLatticeConfigurations = dp.VpcLatticeConfigurations
}

return &sv, nil
}

Expand All @@ -123,6 +131,7 @@ type App struct {
iam *iam.Client
elbv2 *elasticloadbalancingv2.Client
sd *servicediscovery.Client
lattice *vpclattice.Client
verifier *verifier

config *Config
Expand Down Expand Up @@ -199,6 +208,7 @@ func New(ctx context.Context, opt *CLIOptions, newAppOptions ...AppOption) (*App
iam: iam.NewFromConfig(conf.awsv2Config),
elbv2: elasticloadbalancingv2.NewFromConfig(conf.awsv2Config),
sd: servicediscovery.NewFromConfig(conf.awsv2Config),
lattice: vpclattice.NewFromConfig(conf.awsv2Config),
loader: appOpts.loader,
config: appOpts.config,
logger: appOpts.logger,
Expand Down
11 changes: 6 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ go 1.21
require (
github.com/Songmu/prompter v0.5.1
github.com/alecthomas/kong v0.8.1
github.com/aws/aws-sdk-go-v2 v1.32.2
github.com/aws/aws-sdk-go-v2 v1.32.5
github.com/aws/aws-sdk-go-v2/config v1.27.27
github.com/aws/aws-sdk-go-v2/credentials v1.17.27
github.com/aws/aws-sdk-go-v2/service/applicationautoscaling v1.31.0
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.37.3
github.com/aws/aws-sdk-go-v2/service/codedeploy v1.27.3
github.com/aws/aws-sdk-go-v2/service/ecr v1.31.0
github.com/aws/aws-sdk-go-v2/service/ecs v1.47.4
github.com/aws/aws-sdk-go-v2/service/ecs v1.50.0
github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.34.0
github.com/aws/aws-sdk-go-v2/service/iam v1.34.3
github.com/aws/aws-sdk-go-v2/service/s3 v1.58.3
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.4
github.com/aws/aws-sdk-go-v2/service/servicediscovery v1.31.3
github.com/aws/aws-sdk-go-v2/service/ssm v1.52.3
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3
github.com/aws/smithy-go v1.22.0
github.com/aws/smithy-go v1.22.1
github.com/fatih/color v1.16.0
github.com/fujiwara/cfn-lookup v1.1.0
github.com/fujiwara/ecsta v0.4.5
Expand Down Expand Up @@ -70,8 +70,8 @@ require (
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 // indirect
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.24 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.15 // indirect
github.com/aws/aws-sdk-go-v2/service/cloudformation v1.42.3 // indirect
Expand All @@ -82,6 +82,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/sns v1.26.7 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 // indirect
github.com/aws/aws-sdk-go-v2/service/vpclattice v1.12.7 // indirect
github.com/creack/pty v1.1.20 // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
Expand Down
22 changes: 12 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ github.com/alecthomas/kong v0.8.1/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqr
github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE=
github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
github.com/aws/aws-sdk-go-v2 v1.16.15/go.mod h1:SwiyXi/1zTUZ6KIAmLK5V5ll8SiURNUYOqTerZPaF9k=
github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI=
github.com/aws/aws-sdk-go-v2 v1.32.2/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo=
github.com/aws/aws-sdk-go-v2 v1.32.5 h1:U8vdWJuY7ruAkzaOdD7guwJjD06YSKmnKCJs7s3IkIo=
github.com/aws/aws-sdk-go-v2 v1.32.5/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 h1:tW1/Rkad38LA15X4UQtjXZXNKsCgkshC3EbmcUmghTg=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3/go.mod h1:UbnqO+zjqk3uIt9yCACHJ9IVNhyhOCnYk8yA19SAWrM=
github.com/aws/aws-sdk-go-v2/config v1.17.6/go.mod h1:CrxsoI/AcKUoWyL9Zo0YaDxRlBfSnDZKBYKDdkNYDQ0=
Expand All @@ -71,11 +71,11 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11/go.mod h1:SeSUYBLsMYFoRvH
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.24 h1:FzNwpVTZDCvm597Ty6mGYvxTolyC1oup0waaKntZI4E=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.24/go.mod h1:wM9NElT/Wn6n3CT1eyVcXtfCy8lSVjjQXfdawQbSShc=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.22/go.mod h1:/vNv5Al0bpiF8YdX2Ov6Xy05VTiXsql94yUqJMYaj0w=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 h1:UAsR3xA31QGf79WzpG/ixT9FZvQlh5HY1NRqSHBNOCk=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21/go.mod h1:JNr43NFf5L9YaG3eKTm7HQzls9J+A9YYcGI5Quh1r2Y=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 h1:4usbeaes3yJnCFC7kfeyhkdkPtoRYPa/hTmCqMpKpLI=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24/go.mod h1:5CI1JemjVwde8m2WG3cz23qHKPOxbpkq0HaoreEgLIY=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.16/go.mod h1:62dsXI0BqTIGomDl8Hpm33dv0OntGaVblri3ZRParVQ=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 h1:6jZVETqmYCadGFvrYEQfC5fAQmlo80CeL5psbno6r0s=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21/go.mod h1:1SR0GbLlnN3QUmYaflZNiH1ql+1qrSiB2vwcJ+4UM60=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 h1:N1zsICrQglfzaBnrfM0Ys00860C+QFwu6u/5+LomP+o=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24/go.mod h1:dCn9HbJ8+K31i8IQ8EWmWj0EiIk0+vKiHNMxTTYveAg=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.23/go.mod h1:XtEkQMmxls+Tb5dZLmpa1QAk0OzSIFDAXanC9Jkf81E=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
Expand All @@ -92,8 +92,8 @@ github.com/aws/aws-sdk-go-v2/service/codedeploy v1.27.3 h1:MSA1lrc/3I1rDQtLKmCe0
github.com/aws/aws-sdk-go-v2/service/codedeploy v1.27.3/go.mod h1:Zqk3aokH+BfnsAfJl10gz9zWU3TC28e5rR5N/U7yYDk=
github.com/aws/aws-sdk-go-v2/service/ecr v1.31.0 h1:vi/MwojjLGATEEUFn2GEdLiom7CFlB+qCIx4tDWqKfQ=
github.com/aws/aws-sdk-go-v2/service/ecr v1.31.0/go.mod h1:RhaP7Wil0+uuuhiE4FzOOEFZwkmFAk1ZflXzK+O3ptU=
github.com/aws/aws-sdk-go-v2/service/ecs v1.47.4 h1:CTkPGE8fiElvLtYWl/U+Eu5+1fVXiZbJUjyVCRSRgxk=
github.com/aws/aws-sdk-go-v2/service/ecs v1.47.4/go.mod h1:sMFLFhL27cKYa/eQYZp4asvIwHsnJWrAzTUpy9AQdnU=
github.com/aws/aws-sdk-go-v2/service/ecs v1.50.0 h1:NW+6/MPclDxOWcuZZxIJSMt6cVPWVojmJ4R3HsICCsI=
github.com/aws/aws-sdk-go-v2/service/ecs v1.50.0/go.mod h1:dPTOvmjJQ1T7Q+2+Xs2KSPrMvx+p0rpyV+HsQVnUK4o=
github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.34.0 h1:8rDRtPOu3ax8jEctw7G926JQlnFdhZZA4KJzQ+4ks3Q=
github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.34.0/go.mod h1:L5bVuO4PeXuDuMYZfL3IW69E6mz6PDCYpp6IKDlcLMA=
github.com/aws/aws-sdk-go-v2/service/iam v1.34.3 h1:p4L/tixJ3JUIxCteMGT6oMlqCbEv/EzSZoVwdiib8sU=
Expand Down Expand Up @@ -126,9 +126,11 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4/go.mod h1:0oxfLkpz3rQ/CHlx5
github.com/aws/aws-sdk-go-v2/service/sts v1.16.18/go.mod h1:AE4zMc8qCw1JnDvy0ZrDVb/OXRuuweG3BcT2Nv7Qh3E=
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudrvuKpDKgMVRlepGE=
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3/go.mod h1:zwySh8fpFyXp9yOr/KVzxOl8SRqgf/IDw5aUt9UKFcQ=
github.com/aws/aws-sdk-go-v2/service/vpclattice v1.12.7 h1:UnKWGVI1ZeCaUZDOE/UhLLy8i9ggmT2WcZ9AFhssDA8=
github.com/aws/aws-sdk-go-v2/service/vpclattice v1.12.7/go.mod h1:X0X0qZ4S3qpAm8NfTdW4lacTf2VusIV3sbwF+CN3d4k=
github.com/aws/smithy-go v1.13.3/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM=
github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro=
github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
Expand Down
7 changes: 7 additions & 0 deletions tests/ci/ecs-service-def.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,11 @@ local isCodeDeploy = env('DEPLOYMENT_CONTROLLER', 'ECS') == 'CODE_DEPLOY';
name: 'ebs',
},
],
vpcLatticeConfigurations: [
{
portName: 'nginx-http',
roleArn: 'arn:aws:iam::%s:role/ecsInfrastructureRole' % must_env('AWS_ACCOUNT_ID'),
targetGroupArn: 'arn:aws:vpc-lattice:ap-northeast-1:%s:targetgroup/tg-009147df264a0bacb' % must_env('AWS_ACCOUNT_ID'),
},
],
}
10 changes: 9 additions & 1 deletion tests/ci/ecs-task-def.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ local isCodeDeploy = env('DEPLOYMENT_CONTROLLER', 'ECS') == 'CODE_DEPLOY';
name: 'nginx',
portMappings: [
{
name: 'nginx-http',
containerPort: 80,
hostPort: 80,
protocol: 'tcp',
Expand Down Expand Up @@ -78,6 +79,13 @@ local isCodeDeploy = env('DEPLOYMENT_CONTROLLER', 'ECS') == 'CODE_DEPLOY';
},
},
name: 'bash',
portMappings: [
{
name: 'bash-http-proxy',
containerPort: 8080,
protocol: 'tcp',
},
],
secrets: [
{
name: 'FOO',
Expand Down Expand Up @@ -120,7 +128,7 @@ local isCodeDeploy = env('DEPLOYMENT_CONTROLLER', 'ECS') == 'CODE_DEPLOY';
ephemeralStorage: {
sizeInGiB: 50,
},
executionRoleArn: 'arn:aws:iam::{{must_env `AWS_ACCOUNT_ID`}}:role/ecsTaskRole',
executionRoleArn: 'arn:aws:iam::{{must_env `AWS_ACCOUNT_ID`}}:role/ecsTaskExecutionRole',
family: 'ecspresso-test',
memory: '512',
networkMode: 'awsvpc',
Expand Down
64 changes: 59 additions & 5 deletions verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ import (
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
"github.com/aws/aws-sdk-go-v2/service/ssm"
"github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/aws/aws-sdk-go-v2/service/vpclattice"
"github.com/fatih/color"
"github.com/kayac/ecspresso/v2/registry"
"github.com/samber/lo"
)

type verifier struct {
Expand Down Expand Up @@ -362,6 +364,58 @@ func (d *App) verifyServiceDefinition(ctx context.Context) error {
if len(ebs.TagSpecifications) > 1 {
d.Log("[WARNING] %s has more than one tag specifications. Only the first tag specification is used.", name)
}
roleArn := aws.ToString(ebs.RoleArn)
if err := verifyResource(ctx, fmt.Sprintf("RoleArn[%s]", roleArn), func(ctx context.Context) error {
return d.verifyRole(ctx, roleArn, "ecs.amazonaws.com")
}); err != nil {
return err
}
}
return nil
})
if err != nil {
return err
}
}

// VPC Lattice
for i, lc := range sv.VpcLatticeConfigurations {
name := fmt.Sprintf("VpcLatticeConfiguration[%d]", i)
err := verifyResource(ctx, name, func(context.Context) error {
roleArn := aws.ToString(lc.RoleArn)
if err := verifyResource(ctx, fmt.Sprintf("RoleArn[%s]", roleArn), func(ctx context.Context) error {
return d.verifyRole(ctx, roleArn, "ecs.amazonaws.com")
}); err != nil {
return err
}

tgArn := aws.ToString(lc.TargetGroupArn)
if err := verifyResource(ctx, fmt.Sprintf("TargetGroup[%s]", tgArn), func(ctx context.Context) error {
_, err := d.lattice.GetTargetGroup(ctx, &vpclattice.GetTargetGroupInput{
TargetGroupIdentifier: lc.TargetGroupArn,
})
return err
}); err != nil {
return err
}

portName := aws.ToString(lc.PortName)
if err := verifyResource(ctx, fmt.Sprintf("PortName[%s]", portName), func(ctx context.Context) error {
if portName == "" {
return fmt.Errorf("portName is required for vpcLatticeConfiguration")
}
var portMappings []types.PortMapping
for _, cd := range td.ContainerDefinitions {
portMappings = append(portMappings, cd.PortMappings...)
}
if _, found := lo.Find(portMappings, func(pm types.PortMapping) bool {
return portName == aws.ToString(pm.Name)
}); !found {
return fmt.Errorf("portName %s is not found in any containerDefinitions", portName)
}
return nil
}); err != nil {
return err
}
return nil
})
Expand All @@ -382,7 +436,7 @@ func (d *App) verifyTaskDefinition(ctx context.Context) error {
if execRole := td.ExecutionRoleArn; execRole != nil {
name := fmt.Sprintf("ExecutionRole[%s]", *execRole)
err := verifyResource(ctx, name, func(ctx context.Context) error {
return d.verifyRole(ctx, *execRole)
return d.verifyRole(ctx, *execRole, "ecs-tasks.amazonaws.com")
})
if err != nil {
return err
Expand All @@ -391,7 +445,7 @@ func (d *App) verifyTaskDefinition(ctx context.Context) error {
if taskRole := td.TaskRoleArn; taskRole != nil {
name := fmt.Sprintf("TaskRole[%s]", *taskRole)
err := verifyResource(ctx, name, func(ctx context.Context) error {
return d.verifyRole(ctx, *taskRole)
return d.verifyRole(ctx, *taskRole, "ecs-tasks.amazonaws.com")
})
if err != nil {
return err
Expand Down Expand Up @@ -666,7 +720,7 @@ func extractRoleName(roleArn string) (string, error) {
}
}

func (d *App) verifyRole(ctx context.Context, roleArn string) error {
func (d *App) verifyRole(ctx context.Context, roleArn, principalService string) error {
roleName, err := extractRoleName(roleArn)
if err != nil {
return err
Expand All @@ -682,11 +736,11 @@ func (d *App) verifyRole(ctx context.Context, roleArn string) error {
return fmt.Errorf("failed to parse IAM policy document: %w", err)
}
for _, st := range doc.Statement {
if st.Principal.Service == "ecs-tasks.amazonaws.com" && st.Action == "sts:AssumeRole" {
if st.Principal.Service == principalService && st.Action == "sts:AssumeRole" {
return nil
}
}
return fmt.Errorf("executionRole %s has not a valid policy document: %w", roleName, err)
return fmt.Errorf("role %s has not a valid policy document", roleName)
}

type iamPolicyDocument struct {
Expand Down

0 comments on commit 2cf655e

Please sign in to comment.