diff --git a/internal/pkg/deploy/cloudformation/stack/backend_svc.go b/internal/pkg/deploy/cloudformation/stack/backend_svc.go index fd67ef40405..2ff34f6c896 100644 --- a/internal/pkg/deploy/cloudformation/stack/backend_svc.go +++ b/internal/pkg/deploy/cloudformation/stack/backend_svc.go @@ -97,6 +97,7 @@ func (s *BackendService) Template() (string, error) { LogConfig: convertLogging(s.manifest.Logging), DesiredCountLambda: desiredCountLambda.String(), Storage: storage, + Network: convertNetworkConfig(s.manifest.Network), }) if err != nil { return "", fmt.Errorf("parse backend service template: %w", err) diff --git a/internal/pkg/deploy/cloudformation/stack/backend_svc_test.go b/internal/pkg/deploy/cloudformation/stack/backend_svc_test.go index c4def720bf7..13f607aaf90 100644 --- a/internal/pkg/deploy/cloudformation/stack/backend_svc_test.go +++ b/internal/pkg/deploy/cloudformation/stack/backend_svc_test.go @@ -161,6 +161,11 @@ Outputs: StackName: addon.StackName, VariableOutputs: []string{"MyTable"}, }, + Network: &template.NetworkOpts{ + AssignPublicIP: template.DisablePublicIP, + SubnetsType: template.PrivateSubnetsPlacement, + SecurityGroups: []string{"sg-1234"}, + }, }).Return(&template.Content{Buffer: bytes.NewBufferString("template")}, nil) svc.parser = m svc.addons = mockTemplater{ @@ -196,6 +201,10 @@ Outputs: }, manifest: tc.manifest, } + if tc.manifest != nil { + conf.manifest.Network.VPC.Placement = aws.String(manifest.PrivateSubnetPlacement) + conf.manifest.Network.VPC.SecurityGroups = []string{"sg-1234"} + } tc.mockDependencies(t, ctrl, conf) // WHEN diff --git a/internal/pkg/deploy/cloudformation/stack/lb_web_svc.go b/internal/pkg/deploy/cloudformation/stack/lb_web_svc.go index bd149066d02..45d19f7e7d3 100644 --- a/internal/pkg/deploy/cloudformation/stack/lb_web_svc.go +++ b/internal/pkg/deploy/cloudformation/stack/lb_web_svc.go @@ -131,6 +131,7 @@ func (s *LoadBalancedWebService) Template() (string, error) { DesiredCountLambda: desiredCountLambda.String(), EnvControllerLambda: envControllerLambda.String(), Storage: storage, + Network: convertNetworkConfig(s.manifest.Network), }) if err != nil { return "", err diff --git a/internal/pkg/deploy/cloudformation/stack/lb_web_svc_test.go b/internal/pkg/deploy/cloudformation/stack/lb_web_svc_test.go index 54a26ee5974..d0fba95b8df 100644 --- a/internal/pkg/deploy/cloudformation/stack/lb_web_svc_test.go +++ b/internal/pkg/deploy/cloudformation/stack/lb_web_svc_test.go @@ -177,6 +177,10 @@ Outputs: RulePriorityLambda: "lambda", DesiredCountLambda: "something", EnvControllerLambda: "something", + Network: &template.NetworkOpts{ + AssignPublicIP: template.EnablePublicIP, + SubnetsType: template.PublicSubnetsPlacement, + }, }).Return(&template.Content{Buffer: bytes.NewBufferString("template")}, nil) addons := mockTemplater{err: &addon.ErrAddonsDirNotExist{}} @@ -205,6 +209,10 @@ Outputs: RulePriorityLambda: "lambda", DesiredCountLambda: "something", EnvControllerLambda: "something", + Network: &template.NetworkOpts{ + AssignPublicIP: template.EnablePublicIP, + SubnetsType: template.PublicSubnetsPlacement, + }, }).Return(&template.Content{Buffer: bytes.NewBufferString("template")}, nil) addons := mockTemplater{ tpl: `Resources: diff --git a/internal/pkg/deploy/cloudformation/stack/scheduled_job.go b/internal/pkg/deploy/cloudformation/stack/scheduled_job.go index 21c995b2457..7ed57d32263 100644 --- a/internal/pkg/deploy/cloudformation/stack/scheduled_job.go +++ b/internal/pkg/deploy/cloudformation/stack/scheduled_job.go @@ -151,6 +151,7 @@ func (j *ScheduledJob) Template() (string, error) { StateMachine: stateMachine, LogConfig: convertLogging(j.manifest.Logging), Storage: storage, + Network: convertNetworkConfig(j.manifest.Network), }) if err != nil { return "", fmt.Errorf("parse scheduled job template: %w", err) diff --git a/internal/pkg/deploy/cloudformation/stack/scheduled_job_test.go b/internal/pkg/deploy/cloudformation/stack/scheduled_job_test.go index 0179de59f34..029a86a212b 100644 --- a/internal/pkg/deploy/cloudformation/stack/scheduled_job_test.go +++ b/internal/pkg/deploy/cloudformation/stack/scheduled_job_test.go @@ -53,6 +53,10 @@ func TestScheduledJob_Template(t *testing.T) { Timeout: aws.Int(5400), Retries: aws.Int(3), }, + Network: &template.NetworkOpts{ + AssignPublicIP: template.EnablePublicIP, + SubnetsType: template.PublicSubnetsPlacement, + }, })).Return(&template.Content{Buffer: bytes.NewBufferString("template")}, nil) addons := mockTemplater{err: &addon.ErrAddonsDirNotExist{}} j.parser = m @@ -75,6 +79,10 @@ func TestScheduledJob_Template(t *testing.T) { Timeout: aws.Int(5400), Retries: aws.Int(3), }, + Network: &template.NetworkOpts{ + AssignPublicIP: template.EnablePublicIP, + SubnetsType: template.PublicSubnetsPlacement, + }, })).Return(&template.Content{Buffer: bytes.NewBufferString("template")}, nil) addons := mockTemplater{ tpl: `Resources: diff --git a/internal/pkg/deploy/cloudformation/stack/transformers.go b/internal/pkg/deploy/cloudformation/stack/transformers.go index df406e4d7b1..0983db92db4 100644 --- a/internal/pkg/deploy/cloudformation/stack/transformers.go +++ b/internal/pkg/deploy/cloudformation/stack/transformers.go @@ -53,7 +53,7 @@ func convertSidecar(s map[string]*manifest.SidecarConfig) ([]*template.SidecarOp if err != nil { return nil, err } - mp, err := renderSidecarMountPoints(config.MountPoints) + mp, err := convertSidecarMountPoints(config.MountPoints) if err != nil { return nil, err } @@ -161,15 +161,15 @@ func convertStorageOpts(in *manifest.Storage) (*template.StorageOpts, error) { if in == nil { return nil, nil } - v, err := renderVolumes(in.Volumes) + v, err := convertVolumes(in.Volumes) if err != nil { return nil, err } - mp, err := renderMountPoints(in.Volumes) + mp, err := convertMountPoints(in.Volumes) if err != nil { return nil, err } - perms, err := renderStoragePermissions(in.Volumes) + perms, err := convertEFSPermissions(in.Volumes) if err != nil { return nil, err } @@ -180,14 +180,14 @@ func convertStorageOpts(in *manifest.Storage) (*template.StorageOpts, error) { }, nil } -// renderSidecarMountPoints is used to convert from manifest to template objects. -func renderSidecarMountPoints(in []manifest.SidecarMountPoint) ([]*template.MountPoint, error) { +// convertSidecarMountPoints is used to convert from manifest to template objects. +func convertSidecarMountPoints(in []manifest.SidecarMountPoint) ([]*template.MountPoint, error) { if len(in) == 0 { return nil, nil } var output []*template.MountPoint for _, smp := range in { - mp, err := renderMountPoint(smp.SourceVolume, smp.ContainerPath, smp.ReadOnly) + mp, err := convertMountPoint(smp.SourceVolume, smp.ContainerPath, smp.ReadOnly) if err != nil { return nil, err } @@ -196,7 +196,7 @@ func renderSidecarMountPoints(in []manifest.SidecarMountPoint) ([]*template.Moun return output, nil } -func renderMountPoint(sourceVolume, containerPath *string, readOnly *bool) (*template.MountPoint, error) { +func convertMountPoint(sourceVolume, containerPath *string, readOnly *bool) (*template.MountPoint, error) { // containerPath must be specified. if aws.StringValue(containerPath) == "" { return nil, errNoContainerPath @@ -221,13 +221,13 @@ func renderMountPoint(sourceVolume, containerPath *string, readOnly *bool) (*tem }, nil } -func renderMountPoints(input map[string]manifest.Volume) ([]*template.MountPoint, error) { +func convertMountPoints(input map[string]manifest.Volume) ([]*template.MountPoint, error) { if len(input) == 0 { return nil, nil } var output []*template.MountPoint for name, volume := range input { - mp, err := renderMountPoint(aws.String(name), volume.ContainerPath, volume.ReadOnly) + mp, err := convertMountPoint(aws.String(name), volume.ContainerPath, volume.ReadOnly) if err != nil { return nil, err } @@ -236,7 +236,7 @@ func renderMountPoints(input map[string]manifest.Volume) ([]*template.MountPoint return output, nil } -func renderStoragePermissions(input map[string]manifest.Volume) ([]*template.EFSPermission, error) { +func convertEFSPermissions(input map[string]manifest.Volume) ([]*template.EFSPermission, error) { if len(input) == 0 { return nil, nil } @@ -260,7 +260,7 @@ func renderStoragePermissions(input map[string]manifest.Volume) ([]*template.EFS return output, nil } -func renderVolumes(input map[string]manifest.Volume) ([]*template.Volume, error) { +func convertVolumes(input map[string]manifest.Volume) ([]*template.Volume, error) { if len(input) == 0 { return nil, nil } @@ -317,3 +317,16 @@ func renderVolumes(input map[string]manifest.Volume) ([]*template.Volume, error) } return output, nil } + +func convertNetworkConfig(network manifest.NetworkConfig) *template.NetworkOpts { + opts := &template.NetworkOpts{ + AssignPublicIP: template.EnablePublicIP, + SubnetsType: template.PublicSubnetsPlacement, + SecurityGroups: network.VPC.SecurityGroups, + } + if aws.StringValue(network.VPC.Placement) != manifest.PublicSubnetPlacement { + opts.AssignPublicIP = template.DisablePublicIP + opts.SubnetsType = template.PrivateSubnetsPlacement + } + return opts +} diff --git a/internal/pkg/deploy/cloudformation/stack/transformers_test.go b/internal/pkg/deploy/cloudformation/stack/transformers_test.go index afa8a864c3d..93d34932878 100644 --- a/internal/pkg/deploy/cloudformation/stack/transformers_test.go +++ b/internal/pkg/deploy/cloudformation/stack/transformers_test.go @@ -512,7 +512,7 @@ func Test_convertSidecarMountPoints(t *testing.T) { } for name, tc := range testCases { t.Run(name, func(t *testing.T) { - got, err := renderSidecarMountPoints(tc.inMountPoints) + got, err := convertSidecarMountPoints(tc.inMountPoints) if tc.wantErr != "" { require.EqualError(t, err, tc.wantErr) } else { diff --git a/internal/pkg/manifest/backend_svc.go b/internal/pkg/manifest/backend_svc.go index c1fe53df186..2f04481f197 100644 --- a/internal/pkg/manifest/backend_svc.go +++ b/internal/pkg/manifest/backend_svc.go @@ -39,6 +39,7 @@ type BackendServiceConfig struct { TaskConfig `yaml:",inline"` *Logging `yaml:"logging,flow"` Sidecars map[string]*SidecarConfig `yaml:"sidecars"` + Network NetworkConfig `yaml:"network"` } type imageWithPortAndHealthcheck struct { @@ -133,6 +134,11 @@ func newDefaultBackendService() *BackendService { Value: aws.Int(1), }, }, + Network: NetworkConfig{ + VPC: vpcConfig{ + Placement: stringP(PublicSubnetPlacement), + }, + }, }, } } diff --git a/internal/pkg/manifest/backend_svc_test.go b/internal/pkg/manifest/backend_svc_test.go index 24356b7339f..43f22f5df32 100644 --- a/internal/pkg/manifest/backend_svc_test.go +++ b/internal/pkg/manifest/backend_svc_test.go @@ -51,6 +51,11 @@ func TestNewBackendSvc(t *testing.T) { Value: aws.Int(1), }, }, + Network: NetworkConfig{ + VPC: vpcConfig{ + Placement: stringP("public"), + }, + }, }, }, }, @@ -93,6 +98,11 @@ func TestNewBackendSvc(t *testing.T) { Value: aws.Int(1), }, }, + Network: NetworkConfig{ + VPC: vpcConfig{ + Placement: stringP("public"), + }, + }, }, }, }, diff --git a/internal/pkg/manifest/job.go b/internal/pkg/manifest/job.go index b256273cc8c..fc9c30bd3d9 100644 --- a/internal/pkg/manifest/job.go +++ b/internal/pkg/manifest/job.go @@ -42,6 +42,7 @@ type ScheduledJobConfig struct { Sidecars map[string]*SidecarConfig `yaml:"sidecars"` On JobTriggerConfig `yaml:"on,flow"` JobFailureHandlerConfig `yaml:",inline"` + Network NetworkConfig `yaml:"network"` } // JobTriggerConfig represents the configuration for the event that triggers the job. @@ -78,6 +79,11 @@ func newDefaultScheduledJob() *ScheduledJob { Value: aws.Int(1), }, }, + Network: NetworkConfig{ + VPC: vpcConfig{ + Placement: stringP(PublicSubnetPlacement), + }, + }, }, } } diff --git a/internal/pkg/manifest/lb_web_svc.go b/internal/pkg/manifest/lb_web_svc.go index bdb5435417e..b1f5507cf6f 100644 --- a/internal/pkg/manifest/lb_web_svc.go +++ b/internal/pkg/manifest/lb_web_svc.go @@ -20,8 +20,6 @@ const ( // Default values for HTTPHealthCheck for a load balanced web service. const ( - // LogRetentionInDays is the default log retention time in days. - LogRetentionInDays = 30 DefaultHealthCheckPath = "/" ) @@ -53,6 +51,7 @@ type LoadBalancedWebServiceConfig struct { TaskConfig `yaml:",inline"` *Logging `yaml:"logging,flow"` Sidecars map[string]*SidecarConfig `yaml:"sidecars"` + Network NetworkConfig `yaml:"network"` } // HTTPHealthCheckArgs holds the configuration to determine if the load balanced web service is healthy. @@ -150,6 +149,11 @@ func newDefaultLoadBalancedWebService() *LoadBalancedWebService { Value: aws.Int(1), }, }, + Network: NetworkConfig{ + VPC: vpcConfig{ + Placement: stringP(PublicSubnetPlacement), + }, + }, }, } } diff --git a/internal/pkg/manifest/lb_web_svc_test.go b/internal/pkg/manifest/lb_web_svc_test.go index 74de8d3a3e1..2226b23553b 100644 --- a/internal/pkg/manifest/lb_web_svc_test.go +++ b/internal/pkg/manifest/lb_web_svc_test.go @@ -18,6 +18,74 @@ import ( "gopkg.in/yaml.v3" ) +func TestNewLoadBalancedWebService(t *testing.T) { + testCases := map[string]struct { + props LoadBalancedWebServiceProps + + wanted *LoadBalancedWebService + }{ + "translates to default load balanced web service": { + props: LoadBalancedWebServiceProps{ + WorkloadProps: &WorkloadProps{ + Name: "frontend", + Dockerfile: "./Dockerfile", + }, + Path: "/", + Port: 80, + }, + + wanted: &LoadBalancedWebService{ + Workload: Workload{ + Name: stringP("frontend"), + Type: stringP("Load Balanced Web Service"), + }, + LoadBalancedWebServiceConfig: LoadBalancedWebServiceConfig{ + ImageConfig: ServiceImageWithPort{ + Image: Image{ + Build: BuildArgsOrString{ + BuildArgs: DockerBuildArgs{ + Dockerfile: stringP("./Dockerfile"), + }, + }, + }, + Port: aws.Uint16(80), + }, + RoutingRule: RoutingRule{ + Path: stringP("/"), + HealthCheck: HealthCheckArgsOrString{ + HealthCheckPath: stringP("/"), + }, + }, + TaskConfig: TaskConfig{ + CPU: aws.Int(256), + Memory: aws.Int(512), + Count: Count{ + Value: aws.Int(1), + }, + }, + Network: NetworkConfig{ + VPC: vpcConfig{ + Placement: stringP("public"), + }, + }, + }, + }, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + // WHEN + manifest := NewLoadBalancedWebService(&tc.props) + + // THEN + require.Equal(t, tc.wanted.Workload, manifest.Workload) + require.Equal(t, tc.wanted.LoadBalancedWebServiceConfig, manifest.LoadBalancedWebServiceConfig) + require.Equal(t, tc.wanted.Environments, manifest.Environments) + }) + } +} + func TestNewLoadBalancedWebService_UnmarshalYaml(t *testing.T) { testCases := map[string]struct { inContent []byte @@ -287,6 +355,12 @@ func TestLoadBalancedWebService_ApplyEnv(t *testing.T) { Logging: &Logging{ ConfigFile: aws.String("mockConfigFile"), }, + Network: NetworkConfig{ + VPC: vpcConfig{ + Placement: stringP("public"), + SecurityGroups: []string{"sg-123"}, + }, + }, }, Environments: map[string]*LoadBalancedWebServiceConfig{ "prod-iad": { @@ -343,6 +417,11 @@ func TestLoadBalancedWebService_ApplyEnv(t *testing.T) { "FOO": "BAR", }, }, + Network: NetworkConfig{ + VPC: vpcConfig{ + SecurityGroups: []string{"sg-456", "sg-789"}, + }, + }, }, }, }, @@ -425,6 +504,12 @@ func TestLoadBalancedWebService_ApplyEnv(t *testing.T) { "FOO": "BAR", }, }, + Network: NetworkConfig{ + VPC: vpcConfig{ + Placement: stringP("public"), + SecurityGroups: []string{"sg-456", "sg-789"}, + }, + }, }, }, }, diff --git a/internal/pkg/manifest/svc_test.go b/internal/pkg/manifest/svc_test.go index d2f76f52180..6a507f08a35 100644 --- a/internal/pkg/manifest/svc_test.go +++ b/internal/pkg/manifest/svc_test.go @@ -109,6 +109,11 @@ environments: "LOG_TOKEN": "LOG_TOKEN", }, }, + Network: NetworkConfig{ + VPC: vpcConfig{ + Placement: stringP("public"), + }, + }, }, Environments: map[string]*LoadBalancedWebServiceConfig{ "test": { @@ -182,6 +187,11 @@ secrets: "API_TOKEN": "SUBS_API_TOKEN", }, }, + Network: NetworkConfig{ + VPC: vpcConfig{ + Placement: stringP("public"), + }, + }, }, } require.Equal(t, wantedManifest, actualManifest) diff --git a/internal/pkg/manifest/workload.go b/internal/pkg/manifest/workload.go index 8fc9719ae8d..1a9d7b153e7 100644 --- a/internal/pkg/manifest/workload.go +++ b/internal/pkg/manifest/workload.go @@ -14,17 +14,33 @@ import ( "gopkg.in/yaml.v3" ) +const ( + defaultFluentbitImage = "amazon/aws-for-fluent-bit:latest" + defaultDockerfileName = "Dockerfile" + + // AWS VPC subnet placement options. + PublicSubnetPlacement = "public" + PrivateSubnetPlacement = "private" +) + var ( + // WorkloadTypes holds all workload manifest types. + WorkloadTypes = append(ServiceTypes, JobTypes...) + + // All placement options. + subnetPlacements = []string{PublicSubnetPlacement, PrivateSubnetPlacement} + + // Error definitions. errUnmarshalBuildOpts = errors.New("can't unmarshal build field into string or compose-style map") errUnmarshalCountOpts = errors.New(`can't unmarshal "count" field to an integer or autoscaling configuration`) ) -const defaultFluentbitImage = "amazon/aws-for-fluent-bit:latest" - -var dockerfileDefaultName = "Dockerfile" - -// WorkloadTypes holds all workload manifest types. -var WorkloadTypes = append(ServiceTypes, JobTypes...) +// WorkloadProps contains properties for creating a new workload manifest. +type WorkloadProps struct { + Name string + Dockerfile string + Image string +} // Workload holds the basic data that every workload manifest file needs to have. type Workload struct { @@ -52,7 +68,7 @@ func (i Image) GetLocation() string { func (i *Image) BuildConfig(rootDirectory string) *DockerBuildArgs { df := i.dockerfile() ctx := i.context() - dockerfile := aws.String(filepath.Join(rootDirectory, dockerfileDefaultName)) + dockerfile := aws.String(filepath.Join(rootDirectory, defaultDockerfileName)) context := aws.String(rootDirectory) if df != "" && ctx != "" { @@ -64,7 +80,7 @@ func (i *Image) BuildConfig(rootDirectory string) *DockerBuildArgs { context = aws.String(filepath.Join(rootDirectory, filepath.Dir(df))) } if df == "" && ctx != "" { - dockerfile = aws.String(filepath.Join(rootDirectory, ctx, dockerfileDefaultName)) + dockerfile = aws.String(filepath.Join(rootDirectory, ctx, defaultDockerfileName)) context = aws.String(filepath.Join(rootDirectory, ctx)) } return &DockerBuildArgs{ @@ -218,11 +234,46 @@ type TaskConfig struct { Storage *Storage `yaml:"storage"` } -// WorkloadProps contains properties for creating a new workload manifest. -type WorkloadProps struct { - Name string - Dockerfile string - Image string +// NetworkConfig represents options for network connection to AWS resources within a VPC. +type NetworkConfig struct { + VPC vpcConfig `yaml:"vpc"` +} + +// UnmarshalYAML ensures that a NetworkConfig always defaults to public subnets. +// If the user specified a placement that's not valid then throw an error. +func (c *NetworkConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { + type networkWithDefaults NetworkConfig + conf := networkWithDefaults{ + VPC: vpcConfig{ + Placement: stringP(PublicSubnetPlacement), + }, + } + if err := unmarshal(&conf); err != nil { + return err + } + if !conf.VPC.isValidPlacement() { + return fmt.Errorf("field '%s' is '%v' must be one of %#v", "network.vpc.placement", aws.StringValue(conf.VPC.Placement), subnetPlacements) + } + *c = NetworkConfig(conf) + return nil +} + +// vpcConfig represents the security groups and subnets attached to a task. +type vpcConfig struct { + Placement *string `yaml:"placement"` + SecurityGroups []string `yaml:"security_groups"` +} + +func (c vpcConfig) isValidPlacement() bool { + if c.Placement == nil { + return false + } + for _, allowed := range subnetPlacements { + if *c.Placement == allowed { + return true + } + } + return false } // UnmarshalWorkload deserializes the YAML input stream into a workload manifest object. diff --git a/internal/pkg/manifest/workload_test.go b/internal/pkg/manifest/workload_test.go index 68212e54982..f0174c94d39 100644 --- a/internal/pkg/manifest/workload_test.go +++ b/internal/pkg/manifest/workload_test.go @@ -4,6 +4,7 @@ package manifest import ( + "errors" "path/filepath" "testing" @@ -265,3 +266,69 @@ func TestLogging_GetEnableMetadata(t *testing.T) { }) } } + +func TestNetworkConfig_UnmarshalYAML(t *testing.T) { + testCases := map[string]struct { + data string + + wantedConfig NetworkConfig + wantedErr error + }{ + "defaults to public placement if vpc is empty": { + data: ` +network: + vpc: +`, + wantedConfig: NetworkConfig{ + VPC: vpcConfig{ + Placement: stringP(PublicSubnetPlacement), + }, + }, + }, + "returns error if placement option is invalid": { + data: ` +network: + vpc: + placement: 'tartarus' +`, + wantedErr: errors.New(`field 'network.vpc.placement' is 'tartarus' must be one of []string{"public", "private"}`), + }, + "unmarshals successfully for public placement with security groups": { + data: ` +network: + vpc: + placement: 'public' + security_groups: + - 'sg-1234' + - 'sg-4567' +`, + wantedConfig: NetworkConfig{ + VPC: vpcConfig{ + Placement: stringP(PublicSubnetPlacement), + SecurityGroups: []string{"sg-1234", "sg-4567"}, + }, + }, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + // GIVEN + type manifest struct { + Network NetworkConfig `yaml:"network"` + } + var m manifest + + // WHEN + err := yaml.Unmarshal([]byte(tc.data), &m) + + // THEN + if tc.wantedErr != nil { + require.EqualError(t, err, tc.wantedErr.Error()) + } else { + require.NoError(t, err) + require.Equal(t, tc.wantedConfig, m.Network) + } + }) + } +} diff --git a/internal/pkg/template/workload.go b/internal/pkg/template/workload.go index 055264d4023..ea60a315eb6 100644 --- a/internal/pkg/template/workload.go +++ b/internal/pkg/template/workload.go @@ -28,6 +28,15 @@ const ( scheduledJobTplName = "scheduled-job" ) +// Constants for workload options. +const ( + // AWS VPC networking configuration. + EnablePublicIP = "ENABLED" + DisablePublicIP = "DISABLED" + PublicSubnetsPlacement = "PublicSubnets" + PrivateSubnetsPlacement = "PrivateSubnets" +) + var ( // Template names under "workloads/partials/cf/". partialsWorkloadCFTemplateNames = []string{ @@ -151,8 +160,8 @@ type NetworkOpts struct { func defaultNetworkOpts() *NetworkOpts { return &NetworkOpts{ - AssignPublicIP: "ENABLED", - SubnetsType: "PublicSubnets", + AssignPublicIP: EnablePublicIP, + SubnetsType: PublicSubnetsPlacement, } }