diff --git a/pkg/engine/testdata/ecs_rds.expect.yaml b/pkg/engine/testdata/ecs_rds.expect.yaml index 15eff0df9..868352c1f 100755 --- a/pkg/engine/testdata/ecs_rds.expect.yaml +++ b/pkg/engine/testdata/ecs_rds.expect.yaml @@ -67,8 +67,6 @@ resources: ExecutionRole: aws:iam_role:ecs_service_0-execution-role Memory: "512" NetworkMode: awsvpc - RequiresCompatibilities: - - FARGATE Tags: GLOBAL_KLOTHO_TAG: "" RESOURCE_NAME: ecs_service_0 diff --git a/pkg/engine/view_operational.go b/pkg/engine/view_operational.go index 04bb51865..e4c7a73f6 100644 --- a/pkg/engine/view_operational.go +++ b/pkg/engine/view_operational.go @@ -101,6 +101,10 @@ func (view MakeOperationalView) AddEdge(source, target construct.ResourceId, opt return fmt.Errorf("cannot add edge %s -> %s: %w", source, target, err) } } + // If both resources are imported we dont need to evaluate the edge vertex since we cannot modify the resources properties + if dep.Source.Imported && dep.Target.Imported { + return nil + } return view.propertyEval.AddEdges(graph.Edge[construct.ResourceId]{Source: source, Target: target}) } diff --git a/pkg/infra/iac/resource.go b/pkg/infra/iac/resource.go index c48e8f6b4..8a5eb6f0d 100644 --- a/pkg/infra/iac/resource.go +++ b/pkg/infra/iac/resource.go @@ -42,6 +42,9 @@ func (tc *TemplatesCompiler) RenderResource(out io.Writer, rid construct.Resourc } } if r.Imported { + if resTmpl.ImportResource == nil { + return fmt.Errorf("resource %s is imported but has no import resource template", rid) + } err = resTmpl.ImportResource.Execute(out, inputs) if err != nil { return fmt.Errorf("could not render resource %s: %w", rid, err) diff --git a/pkg/infra/iac/templates/aws/ami/factory.ts b/pkg/infra/iac/templates/aws/ami/factory.ts index 4368168b5..b637b5739 100644 --- a/pkg/infra/iac/templates/aws/ami/factory.ts +++ b/pkg/infra/iac/templates/aws/ami/factory.ts @@ -3,13 +3,35 @@ import { ModelCaseWrapper } from '../../wrappers' interface Args { Name: string + Architecture: string + ImageLocation: string + RootDeviceName: string + VirtualizationType: string Tags: ModelCaseWrapper> } function create(args: Args): aws.ec2.Ami { return new aws.ec2.Ami(args.Name, { + //TMPL {{- if .Architecture }} + architecture: args.Architecture, + //TMPL {{- end }} + //TMPL {{- if .ImageLocation }} + imageLocation: args.ImageLocation, + //TMPL {{- end }} + //TMPL {{- if .RootDeviceName }} + rootDeviceName: args.RootDeviceName, + //TMPL {{- end }} + //TMPL {{- if .VirtualizationType }} + virtualizationType: args.VirtualizationType, + //TMPL {{- end }} //TMPL {{- if .Tags }} tags: args.Tags, //TMPL {{- end }} }) } + +function properties(object: aws.ec2.Ami, args: Args) { + return { + Id: object.id, + } +} diff --git a/pkg/infra/iac/templates/aws/auto_scaling_group/factory.ts b/pkg/infra/iac/templates/aws/auto_scaling_group/factory.ts new file mode 100644 index 000000000..026068e87 --- /dev/null +++ b/pkg/infra/iac/templates/aws/auto_scaling_group/factory.ts @@ -0,0 +1,75 @@ +import * as aws from '@pulumi/aws' +import { ModelCaseWrapper } from '../../wrappers' + +interface Args { + Name: string + AvailabilityZones: string[] + CapacityRebalance: boolean + Cooldown: string + DesiredCapacity: string + DesiredCapacityType: string + HealthCheckGracePeriod: number + InstanceId: string + LaunchTemplate: ModelCaseWrapper>> + MaxSize: string + MinSize: string + VPCZoneIdentifier: string[] + Tags: ModelCaseWrapper> +} + +// noinspection JSUnusedLocalSymbols +function create(args: Args): aws.autoscaling.Group { + return new aws.autoscaling.Group(args.Name, { + //TMPL {{- if .AvailabilityZones }} + availabilityZones: args.AvailabilityZones, + //TMPL {{- end }} + //TMPL {{- if .CapacityRebalance }} + capacityRebalance: args.CapacityRebalance, + //TMPL {{- end }} + //TMPL {{- if .Cooldown }} + defaultCooldown: args.Cooldown, + //TMPL {{- end }} + //TMPL {{- if .DesiredCapacity }} + desiredCapacity: args.DesiredCapacity, + //TMPL {{- end }} + //TMPL {{- if .DesiredCapacityType }} + desiredCapacityType: args.DesiredCapacityType, + //TMPL {{- end }} + //TMPL {{- if .HealthCheckGracePeriod }} + healthCheckGracePeriod: args.HealthCheckGracePeriod, + //TMPL {{- end }} + //TMPL {{- if .InstanceId }} + instanceId: args.InstanceId, + //TMPL {{- end }} + launchTemplate: { + //TMPL {{- if .LaunchTemplate.LaunchTemplateId }} + //TMPL id: {{ .LaunchTemplate.LaunchTemplateId }}, + //TMPL {{- end }} + //TMPL {{- if .LaunchTemplate.LaunchTemplateName }} + //TMPL name: {{ .LaunchTemplate.LaunchTemplateName }}, + //TMPL {{- end }} + //TMPL {{- if .LaunchTemplate.Version }} + //TMPL version: {{ .LaunchTemplate.Version }}, + //TMPL {{- end }} + }, + tags: [ + //TMPL {{- range $key, $value := .Tags }} + //TMPL { + //TMPL key: "{{ $key }}", + //TMPL value: {{ $value }}, + //TMPL propagateAtLaunch: true, + //TMPL }, + //TMPL{{- end }} + ], + maxSize: args.MaxSize, + minSize: args.MinSize, + vpcZoneIdentifiers: args.VPCZoneIdentifier, + }) +} + +function properties(object: aws.autoscaling.Group, args: Args) { + return { + Arn: object.arn, + Id: object.id, + } +} diff --git a/pkg/infra/iac/templates/aws/auto_scaling_group/package.json b/pkg/infra/iac/templates/aws/auto_scaling_group/package.json new file mode 100644 index 000000000..88f7b953d --- /dev/null +++ b/pkg/infra/iac/templates/aws/auto_scaling_group/package.json @@ -0,0 +1,6 @@ +{ + "name": "auto_scaling_group", + "dependencies": { + "@pulumi/aws": "^5.37.0" + } +} diff --git a/pkg/infra/iac/templates/aws/availability_zone/factory.ts b/pkg/infra/iac/templates/aws/availability_zone/factory.ts index 0f6917210..14099110f 100644 --- a/pkg/infra/iac/templates/aws/availability_zone/factory.ts +++ b/pkg/infra/iac/templates/aws/availability_zone/factory.ts @@ -14,3 +14,13 @@ function create(args: Args): pulumi.Output> { + return pulumi.output( + aws.getAvailabilityZones({ + state: 'available', + }) + ).names[args.Index] +} diff --git a/pkg/infra/iac/templates/aws/ec2_launch_template/factory.ts b/pkg/infra/iac/templates/aws/ec2_launch_template/factory.ts new file mode 100644 index 000000000..ed698bf1a --- /dev/null +++ b/pkg/infra/iac/templates/aws/ec2_launch_template/factory.ts @@ -0,0 +1,53 @@ +import * as aws from '@pulumi/aws' +import { ModelCaseWrapper } from '../../wrappers' + +interface Args { + Name: string + LaunchTemplateData: Record> + Tags: ModelCaseWrapper> +} + +// noinspection JSUnusedLocalSymbols +function create(args: Args): aws.ec2.LaunchTemplate { + return new aws.ec2.LaunchTemplate(args.Name, { + //TMPL {{- if .LaunchTemplateData.iamInstanceProfile }} + //TMPL iamInstanceProfile: {{ .LaunchTemplateData.iamInstanceProfile }}, + //TMPL {{- end }} + //TMPL {{- if .LaunchTemplateData.imageId }} + //TMPL imageId: {{ .LaunchTemplateData.imageId }}, + //TMPL {{- else }} + //TMPL imageId: aws.ec2.getAmi({ + //TMPL filters: [ + //TMPL { + //TMPL name: "name", + //TMPL values: ["amzn2-ami-ecs-hvm-*-x86_64-ebs"], + //TMPL }, + //TMPL ], + //TMPL owners: ["amazon"], // AWS account ID for Amazon AMIs + //TMPL mostRecent: true, + //TMPL }).then(ami => ami.id), + //TMPL {{- end }} + //TMPL {{- if .LaunchTemplateData.instanceRequirements }} + //TMPL instanceRequirements: {{ .LaunchTemplateData.instanceRequirements }}, + //TMPL {{- end }} + //TMPL {{- if .LaunchTemplateData.instanceType }} + //TMPL instanceType: {{ .LaunchTemplateData.instanceType}}, + //TMPL {{- end }} + //TMPL {{- if .LaunchTemplateData.securityGroupIds }} + //TMPL securityGroupIds: {{ .LaunchTemplateData.securityGroupIds }}, + //TMPL {{- end }} + //TMPL {{- if .LaunchTemplateData.userData }} + //TMPL userData: {{ .LaunchTemplateData.userData }}, + //TMPL {{- end }} + //TMPL {{- if .Tags }} + tags: args.Tags, + //TMPL {{- end }} + }) +} + +function properties(object: aws.ec2.LaunchTemplate, args: Args) { + return { + Arn: object.arn, + Id: object.id, + } +} diff --git a/pkg/infra/iac/templates/aws/ec2_launch_template/package.json b/pkg/infra/iac/templates/aws/ec2_launch_template/package.json new file mode 100644 index 000000000..b8714ad47 --- /dev/null +++ b/pkg/infra/iac/templates/aws/ec2_launch_template/package.json @@ -0,0 +1,6 @@ +{ + "name": "ec2_launch_template", + "dependencies": { + "@pulumi/aws": "^5.37.0" + } +} diff --git a/pkg/infra/iac/templates/aws/ecs_capacity_provider/factory.ts b/pkg/infra/iac/templates/aws/ecs_capacity_provider/factory.ts new file mode 100644 index 000000000..0061533e3 --- /dev/null +++ b/pkg/infra/iac/templates/aws/ecs_capacity_provider/factory.ts @@ -0,0 +1,30 @@ +import * as aws from '@pulumi/aws' +import { ModelCaseWrapper } from '../../wrappers' +import * as awsInputs from '@pulumi/aws/types/input' + +interface Args { + Name: string + AutoScalingGroupProvider: awsInputs.ecs.CapacityProviderAutoScalingGroupProvider + Tags: ModelCaseWrapper> +} + +// noinspection JSUnusedLocalSymbols +function create(args: Args): aws.ecs.CapacityProvider { + return new aws.ecs.CapacityProvider(args.Name, { + autoScalingGroupProvider: args.AutoScalingGroupProvider, + //TMPL {{- if .Tags }} + tags: args.Tags, + //TMPL {{- end }} + }) +} + +function properties(object: aws.ecs.CapacityProvider, args: Args) { + return { + Arn: object.arn, + Id: object.name, + } +} + +function importResource(args: Args): aws.ecs.CapacityProvider { + return aws.ecs.CapacityProvider.get(args.Name, args.Id) +} diff --git a/pkg/infra/iac/templates/aws/ecs_capacity_provider/package.json b/pkg/infra/iac/templates/aws/ecs_capacity_provider/package.json new file mode 100644 index 000000000..92af0f80b --- /dev/null +++ b/pkg/infra/iac/templates/aws/ecs_capacity_provider/package.json @@ -0,0 +1,6 @@ +{ + "name": "ecs_capacity_provider", + "dependencies": { + "@pulumi/aws": "^5.37.0" + } +} diff --git a/pkg/infra/iac/templates/aws/ecs_cluster/factory.ts b/pkg/infra/iac/templates/aws/ecs_cluster/factory.ts index 7bd4afab6..cfa6732e3 100644 --- a/pkg/infra/iac/templates/aws/ecs_cluster/factory.ts +++ b/pkg/infra/iac/templates/aws/ecs_cluster/factory.ts @@ -16,6 +16,15 @@ function create(args: Args): aws.ecs.Cluster { }) } +function properties(object: aws.ecs.Cluster, args: Args) { + return { + Id: object.name, + UserDataScript: pulumi.interpolate`#!/bin/bash +echo ECS_CLUSTER=${object.name} >> /etc/ecs/ecs.config +`.apply((userData) => Buffer.from(userData).toString('base64')), + } +} + function importResource(args: Args): aws.ecs.Cluster { return aws.ecs.Cluster.get(args.Name, args.Id) } diff --git a/pkg/infra/iac/templates/aws/ecs_cluster_capacity_provider/factory.ts b/pkg/infra/iac/templates/aws/ecs_cluster_capacity_provider/factory.ts new file mode 100644 index 000000000..7b36b9b74 --- /dev/null +++ b/pkg/infra/iac/templates/aws/ecs_cluster_capacity_provider/factory.ts @@ -0,0 +1,29 @@ +import * as aws from '@pulumi/aws' +import { ModelCaseWrapper } from '../../wrappers' +import * as awsInputs from '@pulumi/aws/types/input' + +interface Args { + Name: string + Cluster: string + CapacityProviders: string[] + DefaultCapacityProviderStrategy: awsInputs.ecs.ClusterCapacityProvidersDefaultCapacityProviderStrategy[] +} + +// noinspection JSUnusedLocalSymbols +function create(args: Args): aws.ecs.ClusterCapacityProviders { + return new aws.ecs.ClusterCapacityProviders(args.Name, { + clusterName: args.Cluster, + capacityProviders: args.CapacityProviders, + defaultCapacityProviderStrategies: args.DefaultCapacityProviderStrategy, + }) +} + +function properties(object: aws.ecs.ClusterCapacityProviders, args: Args) { + return { + Id: object.id, + } +} + +function importResource(args: Args): aws.ecs.ClusterCapacityProviders { + return aws.ecs.ClusterCapacityProviders.get(args.Name, args.Id) +} diff --git a/pkg/infra/iac/templates/aws/ecs_cluster_capacity_provider/package.json b/pkg/infra/iac/templates/aws/ecs_cluster_capacity_provider/package.json new file mode 100644 index 000000000..70f23a07e --- /dev/null +++ b/pkg/infra/iac/templates/aws/ecs_cluster_capacity_provider/package.json @@ -0,0 +1,6 @@ +{ + "name": "ecs_cluster_capacity_provider", + "dependencies": { + "@pulumi/aws": "^5.37.0" + } +} diff --git a/pkg/infra/iac/templates/aws/ecs_service/factory.ts b/pkg/infra/iac/templates/aws/ecs_service/factory.ts index 3e572fd61..0b2bcff20 100644 --- a/pkg/infra/iac/templates/aws/ecs_service/factory.ts +++ b/pkg/infra/iac/templates/aws/ecs_service/factory.ts @@ -21,6 +21,7 @@ interface Args { dependsOn?: pulumi.Input[]> | pulumi.Input ServiceRegistries: pulumi.Input ServiceConnectConfiguration: pulumi.Input + CapacityProviderStrategies: pulumi.Input Tags: ModelCaseWrapper> } @@ -29,7 +30,12 @@ function create(args: Args): aws.ecs.Service { return new aws.ecs.Service( args.Name, { + //TMPL {{- if .LaunchType }} launchType: args.LaunchType, + //TMPL {{- end }} + //TMPL {{- if .CapacityProviderStrategies }} + capacityProviderStrategies: args.CapacityProviderStrategies, + //TMPL {{- end }} cluster: args.Cluster.arn, //TMPL {{- if .DeploymentCircuitBreaker }} //TMPL deploymentCircuitBreaker: { diff --git a/pkg/infra/iac/templates/aws/iam_instance_profile/factory.ts b/pkg/infra/iac/templates/aws/iam_instance_profile/factory.ts index 14d56d727..cf307830a 100644 --- a/pkg/infra/iac/templates/aws/iam_instance_profile/factory.ts +++ b/pkg/infra/iac/templates/aws/iam_instance_profile/factory.ts @@ -15,3 +15,9 @@ function create(args: Args): aws.iam.InstanceProfile { //TMPL {{- end }} }) } + +function properties(object: aws.ecs.Cluster, args: Args) { + return { + Arn: object.arn, + } +} diff --git a/pkg/infra/iac/templates/aws/subnet/factory.ts b/pkg/infra/iac/templates/aws/subnet/factory.ts index a7795c053..5dfb79320 100644 --- a/pkg/infra/iac/templates/aws/subnet/factory.ts +++ b/pkg/infra/iac/templates/aws/subnet/factory.ts @@ -25,6 +25,12 @@ function create(args: Args): aws.ec2.Subnet { }) } +function properties(object: aws.ec2.Subnet, args: Args) { + return { + Id: object.id, + } +} + function importResource(args: Args): aws.ec2.Subnet { return aws.ec2.Subnet.get(args.Name, args.Id) } diff --git a/pkg/infra/state_reader/state_template/mappings/pulumi/ecs_capacity_provider.yaml b/pkg/infra/state_reader/state_template/mappings/pulumi/ecs_capacity_provider.yaml new file mode 100644 index 000000000..cf7dbc792 --- /dev/null +++ b/pkg/infra/state_reader/state_template/mappings/pulumi/ecs_capacity_provider.yaml @@ -0,0 +1,7 @@ +qualified_type_name: aws:ecs_capacity_provider +iac_qualified_type: aws:ecs/capacityProvider:CapacityProvider + +property_mappings: + arn: Arn + name: Id + tags: Tags \ No newline at end of file diff --git a/pkg/infra/state_reader/state_template/mappings/pulumi/ecs_cluster_capacity_provider.yaml b/pkg/infra/state_reader/state_template/mappings/pulumi/ecs_cluster_capacity_provider.yaml new file mode 100644 index 000000000..2e8d1b571 --- /dev/null +++ b/pkg/infra/state_reader/state_template/mappings/pulumi/ecs_cluster_capacity_provider.yaml @@ -0,0 +1,5 @@ +qualified_type_name: aws:ecs_cluster_capacity_provider +iac_qualified_type: aws:ecs/clusterCapacityProviders:ClusterCapacityProviders + +property_mappings: + id: Id diff --git a/pkg/provider/aws/aws_resource_test.go b/pkg/provider/aws/aws_resource_test.go index 682f240a9..77ef0b02e 100644 --- a/pkg/provider/aws/aws_resource_test.go +++ b/pkg/provider/aws/aws_resource_test.go @@ -30,6 +30,7 @@ var ( "aws:api_method", "aws:api_resource", "aws:ses_email_identity", + "aws:ecs_cluster_capacity_provider", } ) diff --git a/pkg/templates/aws/edges/auto_scaling_group-ec2_launch_template.yaml b/pkg/templates/aws/edges/auto_scaling_group-ec2_launch_template.yaml new file mode 100644 index 000000000..aae8037c3 --- /dev/null +++ b/pkg/templates/aws/edges/auto_scaling_group-ec2_launch_template.yaml @@ -0,0 +1,2 @@ +source: aws:auto_scaling_group +target: aws:ec2_launch_template \ No newline at end of file diff --git a/pkg/templates/aws/edges/auto_scaling_group-subnet.yaml b/pkg/templates/aws/edges/auto_scaling_group-subnet.yaml new file mode 100644 index 000000000..15b40a528 --- /dev/null +++ b/pkg/templates/aws/edges/auto_scaling_group-subnet.yaml @@ -0,0 +1,2 @@ +source: aws:auto_scaling_group +target: aws:subnet \ No newline at end of file diff --git a/pkg/templates/aws/edges/ec2_launch_template-ami.yaml b/pkg/templates/aws/edges/ec2_launch_template-ami.yaml new file mode 100644 index 000000000..883f47a0a --- /dev/null +++ b/pkg/templates/aws/edges/ec2_launch_template-ami.yaml @@ -0,0 +1,9 @@ +source: aws:ec2_launch_template +target: aws:ami + +operational_rules: + - configuration_rules: + - resource: '{{.Source}}' + configuration: + field: LaunchTemplateData.ImageId + value: '{{ fieldRef "Id" .Target}}' \ No newline at end of file diff --git a/pkg/templates/aws/edges/ec2_launch_template-iam_instance_profile.yaml b/pkg/templates/aws/edges/ec2_launch_template-iam_instance_profile.yaml new file mode 100644 index 000000000..c303520c2 --- /dev/null +++ b/pkg/templates/aws/edges/ec2_launch_template-iam_instance_profile.yaml @@ -0,0 +1,2 @@ +source: aws:ec2_launch_template +target: aws:iam_instance_profile \ No newline at end of file diff --git a/pkg/templates/aws/edges/ecs_capacity_provider-auto_scaling_group.yaml b/pkg/templates/aws/edges/ecs_capacity_provider-auto_scaling_group.yaml new file mode 100644 index 000000000..74a0ec15f --- /dev/null +++ b/pkg/templates/aws/edges/ecs_capacity_provider-auto_scaling_group.yaml @@ -0,0 +1,29 @@ +source: aws:ecs_capacity_provider +target: aws:auto_scaling_group + +operational_rules: + - if: '{{ hasDownstream "aws:iam_role" .Target }}' + configuration_rules: + - resource: '{{ downstream "aws:iam_role" .Target }}' + configuration: + field: ManagedPolicies + value: + - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role + - resource: '{{ downstream "aws:iam_role" .Target }}' + configuration: + field: AssumeRolePolicyDoc + value: + Version: '2012-10-17' + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + - if: '{{ hasDownstream "aws:ec2_launch_template" .Target }}' + configuration_rules: + - resource: '{{ downstream "aws:ec2_launch_template" .Target }}' + configuration: + field: LaunchTemplateData.UserData + value: '{{ fieldRef "UserDataScript" (downstream "aws:ecs_cluster" .Source)}}' \ No newline at end of file diff --git a/pkg/templates/aws/edges/ecs_capacity_provider-ecs_cluster_capacity_provider.yaml b/pkg/templates/aws/edges/ecs_capacity_provider-ecs_cluster_capacity_provider.yaml new file mode 100644 index 000000000..21a4e969a --- /dev/null +++ b/pkg/templates/aws/edges/ecs_capacity_provider-ecs_cluster_capacity_provider.yaml @@ -0,0 +1,16 @@ +source: aws:ecs_capacity_provider +target: aws:ecs_cluster_capacity_provider +deployment_order_reversed: true + +operational_rules: + - configuration_rules: + - resource: '{{ .Target }}' + configuration: + field: CapacityProviders + value: + - '{{ fieldRef "Id" .Source }}' + - resource: '{{ .Target }}' + configuration: + field: DefaultCapacityProviderStrategy + value: + - CapacityProvider: '{{ fieldRef "Id" .Source }}' diff --git a/pkg/templates/aws/edges/ecs_cluster_capacity_provider-ecs_cluster.yaml b/pkg/templates/aws/edges/ecs_cluster_capacity_provider-ecs_cluster.yaml new file mode 100644 index 000000000..684d3aec1 --- /dev/null +++ b/pkg/templates/aws/edges/ecs_cluster_capacity_provider-ecs_cluster.yaml @@ -0,0 +1,9 @@ +source: aws:ecs_cluster_capacity_provider +target: aws:ecs_cluster + +operational_rules: + - configuration_rules: + - resource: '{{ .Source }}' + configuration: + field: Cluster + value: '{{ fieldRef "Id" .Target }}' diff --git a/pkg/templates/aws/edges/ecs_service-ecs_capacity_provider.yaml b/pkg/templates/aws/edges/ecs_service-ecs_capacity_provider.yaml new file mode 100644 index 000000000..67e656030 --- /dev/null +++ b/pkg/templates/aws/edges/ecs_service-ecs_capacity_provider.yaml @@ -0,0 +1,10 @@ +source: aws:ecs_service +target: aws:ecs_capacity_provider + +operational_rules: + - configuration_rules: + - resource: '{{ .Source }}' + configuration: + field: CapacityProviderStrategies + value: + - CapacityProvider: '{{ fieldRef "Id" .Target }}' diff --git a/pkg/templates/aws/edges/ecs_service-ecs_task_definition.yaml b/pkg/templates/aws/edges/ecs_service-ecs_task_definition.yaml index 5d58f9bb6..4ae768569 100644 --- a/pkg/templates/aws/edges/ecs_service-ecs_task_definition.yaml +++ b/pkg/templates/aws/edges/ecs_service-ecs_task_definition.yaml @@ -1,2 +1,2 @@ source: aws:ecs_service -target: aws:ecs_task_definition +target: aws:ecs_task_definition \ No newline at end of file diff --git a/pkg/templates/aws/edges/target_group-ecs_service.yaml b/pkg/templates/aws/edges/target_group-ecs_service.yaml index b249fa119..862a907a4 100644 --- a/pkg/templates/aws/edges/target_group-ecs_service.yaml +++ b/pkg/templates/aws/edges/target_group-ecs_service.yaml @@ -8,7 +8,7 @@ operational_rules: field: LoadBalancers value: - TargetGroup: '{{ .Source }}' - ContainerName: '{{ (downstream "aws:ecs_task_definition" .Target).Name }}' + ContainerName: '{{ fieldValue "ContainerDefinitions[0].Name" (downstream "aws:ecs_task_definition" .Target) }}' ContainerPort: '{{ fieldValue "ContainerDefinitions[0].PortMappings[0].ContainerPort" (fieldValue "TaskDefinition" .Target)}}' - resource: '{{ .Source }}' configuration: diff --git a/pkg/templates/aws/resources/ami.yaml b/pkg/templates/aws/resources/ami.yaml index bf621456f..123229179 100644 --- a/pkg/templates/aws/resources/ami.yaml +++ b/pkg/templates/aws/resources/ami.yaml @@ -2,8 +2,34 @@ qualified_type_name: aws:ami display_name: AMI properties: + Architecture: + type: string + description: Machine architecture for created instances. + default_value: x86_64 + ImageLocation: + type: string + description: Path to an S3 object containing an image manifest. + RootDeviceName: + type: string + description: The root device name (e.g. /dev/sda1). + default_value: /dev/xvda + VirtualizationType: + type: string + description: Keyword to choose what virtualization mode created instances will use. + allowed_values: + - hvm + - paravirtual aws:tags: type: model + Arn: + type: string + deploy_time: true + configuration_disabled: true + Id: + type: string + required: true + deploy_time: true + configuration_disabled: true classification: is: diff --git a/pkg/templates/aws/resources/auto_scaling_group.yaml b/pkg/templates/aws/resources/auto_scaling_group.yaml new file mode 100644 index 000000000..7e164d861 --- /dev/null +++ b/pkg/templates/aws/resources/auto_scaling_group.yaml @@ -0,0 +1,103 @@ +qualified_type_name: aws:auto_scaling_group +display_name: Auto Scaling Group + +properties: + AvailabilityZones: + type: list(string) + description: A list of Availability Zones where instances in the Auto Scaling group can be created. + CapacityRebalance: + type: bool + description: Indicates whether Capacity Rebalancing is enabled. When you turn on Capacity Rebalancing, Amazon EC2 Auto Scaling attempts to launch a Spot Instance whenever Amazon EC2 notifies that a Spot Instance is at an elevated risk of interruption. After launching a new instance, it then terminates an old instance. + default_value: false + Cooldown: + type: int + default_value: 300 + description: The amount of time, in seconds, after a scaling activity completes before another scaling activity can start. + DesiredCapacity: + type: int + description: The desired capacity is the initial capacity of the Auto Scaling group at the time of its creation and the capacity it attempts to maintain. It can scale beyond this capacity if you configure automatic scaling. + DesiredCapacityType: + type: string + description: The unit of measurement for the value specified for desired capacity. + default_value: units + allowed_values: + - units + - vcpu + - memory-mib + HealthCheckGracePeriod: + type: int + description: The amount of time, in seconds, that Amazon EC2 Auto Scaling waits before checking the health status of an EC2 instance that has come into service. + default_value: 0 + InstanceId: + type: string + description: The ID of the instance used to base the launch configuration on. If you specify LaunchTemplate, MixedInstancesPolicy, or LaunchConfigurationName, don't specify InstanceId. + LaunchTemplate: + type: map + default_value: {} + properties: + LaunchTemplateId: + type: string + description: The ID of the launch template. You must specify either a template ID or a template name. + operational_rule: + if: '{{ not (hasField "InstanceId" .Self) }}' + step: + direction: downstream + resources: + - aws:ec2_launch_template + unique: true + use_property_ref: Id + LaunchTemplateName: + type: string + description: The name of the launch template. You must specify either a template name or a template ID. + Version: + type: string + description: The version number, $Latest, or $Default. If the value is $Latest, Amazon EC2 Auto Scaling selects the latest version of the launch template when launching instances. If the value is $Default, Amazon EC2 Auto Scaling selects the default version of the launch template when launching instances. The default value is $Default. + default_value: $Latest + MaxSize: + type: int + required: true + description: The maximum size of the Auto Scaling group. + MinSize: + type: int + required: true + description: The minimum size of the Auto Scaling group. + VPCZoneIdentifier: + type: list(string) + description: A comma-separated list of subnet IDs for a virtual private cloud (VPC). If you specify VPCZoneIdentifier with AvailabilityZones, the subnets that you specify for this parameter must reside in those Availability Zones. + required: true + operational_rule: + step: + direction: downstream + num_needed: 2 + use_property_ref: Id + resources: + - selector: aws:subnet + properties: + Type: private + - aws:subnet + aws:tags: + type: model + Arn: + type: string + description: The Amazon Resource Name (ARN) of the Auto Scaling group. + configuration_disabled: true + deploy_time: true + required: true + Id: + type: string + description: The unique identifier for the cluster. + configuration_disabled: true + deploy_time: true + +classification: + is: + - auto_scaling + - ecs + +delete_context: + requires_no_upstream: true + +deployment_permissions: + deploy: ["autoscaling-plans:CreateScalingPlan", "autoscaling-plans:DescribeScalingPlanResources", "autoscaling-plans:DescribeScalingPlans", "autoscaling-plans:GetScalingPlanResourceForecastData"] + tear_down: ["autoscaling-plans:DeleteScalingPlan"] + update: ["autoscaling-plans:UpdateScalingPlan"] \ No newline at end of file diff --git a/pkg/templates/aws/resources/ec2_launch_template.yaml b/pkg/templates/aws/resources/ec2_launch_template.yaml new file mode 100644 index 000000000..94731eebd --- /dev/null +++ b/pkg/templates/aws/resources/ec2_launch_template.yaml @@ -0,0 +1,92 @@ +qualified_type_name: aws:ec2_launch_template +display_name: Ec2 Launch Template + +properties: + LaunchTemplateData: + type: map + description: The information for the launch template. + required: true + properties: + IamInstanceProfile: + type: map + description: The name or Amazon Resource Name (ARN) of an IAM instance profile. + properties: + Arn: + type: string + operational_rule: + step: + direction: downstream + resources: + - aws:iam_instance_profile + unique: true + use_property_ref: Arn + Name: + type: string + ImageId: + type: string + description: The ID of the AMI. + InstanceRequirements: + type: map + description: The instance requirements for the launch template. You must specify VCpuCount and MemoryMiB. If you specify InstanceRequirements, you can't specify InstanceType. + properties: + AllowedInstanceTypes: + type: list(string) + description: The instance types that can be launched. You can specify instance families to launch any instance type within those families (for example, c5 or m5). If you specify instance types, you can't specify a value for InstanceType. + ExcludedInstanceTypes: + type: list(string) + description: The instance types that aren't allowed to be launched. You can specify instance families to launch any instance type within those families (for example, c5 or m5). If you specify instance types, you can't specify a value for InstanceType. + MemoryMib: + type: map + description: The amount of memory, in MiB, that's required for the instance type. You must specify a value for MemoryMiB, and you can't specify a value for InstanceType. + properties: + Max: + type: int + description: The maximum number of vCPUs that are required for the instance type. + Min: + type: int + description: The minimum number of vCPUs that are required for the instance type. + VCpuCount: + type: map + description: The number of vCPUs that are required for the instance type. You must specify a value for VCpuCount, and you can't specify a value for InstanceType. + properties: + Max: + type: int + description: The maximum number of vCPUs that are required for the instance type. + Min: + type: int + description: The minimum number of vCPUs that are required for the instance type. + InstanceType: + type: string + description: The instance type. If you specify InstanceType, you can't specify InstanceRequirements. + SecurityGroupIds: + type: list(string) + description: The IDs of the security groups. + UserData: + type: string + description: The Base64-encoded user data to make available to the instance. + aws:tags: + type: model + Arn: + type: string + description: The Amazon Resource Name (ARN) of the launch template. + configuration_disabled: true + deploy_time: true + Id: + type: string + description: The unique identifier for the cluster. + configuration_disabled: true + deploy_time: true + required: true + +classification: + is: + - launch_template + - ec2 + +delete_context: + requires_no_upstream: true + +deployment_permissions: + deploy: ["ec2:CreateLaunchTemplate", "ec2:CreateLaunchTemplateVersion", "ec2:DescribeLaunchTemplates", "ec2:DescribeLaunchTemplateVersions", "ec2:GetLaunchTemplateData"] + tear_down: ["ec2:DeleteLaunchTemplate", "ec2:DeleteLaunchTemplateVersions"] + update: ["ec2:ModifyLaunchTemplate"] \ No newline at end of file diff --git a/pkg/templates/aws/resources/ecs_capacity_provider.yaml b/pkg/templates/aws/resources/ecs_capacity_provider.yaml new file mode 100644 index 000000000..7865e2111 --- /dev/null +++ b/pkg/templates/aws/resources/ecs_capacity_provider.yaml @@ -0,0 +1,86 @@ +qualified_type_name: aws:ecs_capacity_provider +display_name: ECS Capacity Provider + +properties: + AutoScalingGroupProvider: + type: map + properties: + AutoScalingGroupArn: + type: string + required: true + description: The Amazon Resource Name (ARN) that identifies the Auto Scaling group. + operational_rule: + step: + direction: downstream + resources: + - aws:auto_scaling_group + unique: true + use_property_ref: Arn + ManagedDraining: + type: string + allowed_values: ["ENABLED", "DISABLED"] + description: The managed draining option for the Auto Scaling group capacity provider. When you enable this, Amazon ECS manages and gracefully drains the EC2 container instances that are in the Auto Scaling group capacity provider. + ManagedScaling: + type: map + description: The managed scaling settings for the Auto Scaling group capacity provider. + properties: + InstanceWarmupPeriod: + type: int + default_value: 300 + min_value: 0 + max_value: 10000 + description: The period of time, in seconds, after a newly launched Amazon EC2 instance can contribute to CloudWatch metrics for Auto Scaling group. + MaximumScalingStepSize: + type: int + description: The maximum number of Amazon EC2 instances that Amazon ECS will scale out at one time. The scale in process is not affected by this parameter. + default_value: 10000 + min_value: 1 + max_value: 10000 + MinimumScalingStepSize: + type: int + description: The minimum number of Amazon EC2 instances that Amazon ECS will scale out at one time. + default_value: 1 + min_value: 1 + max_value: 10000 + Status: + type: string + description: Determines whether to use managed scaling for the capacity provider. + default_value: "ENABLED" + allowed_values: ["ENABLED", "DISABLED"] + TargetCapacity: + type: int + description: The target capacity utilization as a percentage for the capacity provider. + default_value: 100 + min_value: 1 + max_value: 100 + ManagedTerminationProtection: + type: string + allowed_values: ["ENABLED", "DISABLED"] + default_value: "DISABLED" + description: The managed termination protection setting to use for the Auto Scaling group capacity provider. This determines whether the Auto Scaling group has managed termination protection. + aws:tags: + type: model + Arn: + type: string + description: The Amazon Resource Name (ARN) that identifies the cluster. + deploy_time: true + configuration_disabled: true + Id: + type: string + description: The unique identifier for the cluster. + configuration_disabled: true + deploy_time: true + required: true + +classification: + is: + - auto_scaling + - ecs + +delete_context: + requires_no_upstream: true + +deployment_permissions: + deploy: ["ecs:CreateCapacityProvider", "ecs:DescribeCapacityProviders", "PutClusterCapacityProviders"] + tear_down: ["ecs:DeleteCapacityProvider"] + update: ["ecs:UpdateCapacityProvider"] \ No newline at end of file diff --git a/pkg/templates/aws/resources/ecs_cluster.yaml b/pkg/templates/aws/resources/ecs_cluster.yaml index bd18f6e92..e29495907 100644 --- a/pkg/templates/aws/resources/ecs_cluster.yaml +++ b/pkg/templates/aws/resources/ecs_cluster.yaml @@ -30,7 +30,12 @@ properties: configuration_disabled: true deploy_time: true required: true - + UserDataScript: + type: string + description: The user data script to run on the instances in the cluster. + deploy_time: true + configuration_disabled: true + classification: is: - cluster diff --git a/pkg/templates/aws/resources/ecs_cluster_capacity_provider.yaml b/pkg/templates/aws/resources/ecs_cluster_capacity_provider.yaml new file mode 100644 index 000000000..512f9efca --- /dev/null +++ b/pkg/templates/aws/resources/ecs_cluster_capacity_provider.yaml @@ -0,0 +1,54 @@ +qualified_type_name: aws:ecs_cluster_capacity_provider +display_name: ECS Cluster Capacity Provider + +properties: + Cluster: + type: string + required: true + namespace: true + min_length: 1 + max_length: 2048 + description: The short name or full Amazon Resource Name (ARN) of the cluster that hosts the capacity provider. + CapacityProviders: + type: list(string) + required: true + description: The capacity providers to associate with the cluster. + DefaultCapacityProviderStrategy: + required: true + type: list + properties: + Base: + type: int + description: The base value designates how many tasks, at a minimum, to run on the specified capacity provider. Only one capacity provider in a capacity provider strategy can have a base defined. + min_value: 0 + max_value: 10000 + default_value: 0 + CapacityProvider: + type: string + description: The short name or full Amazon Resource Name (ARN) of the capacity provider. + required: true + Weight: + type: int + description: The weight value designates the relative percentage of the total number of tasks launched that should use the specified capacity provider. + min_value: 0 + max_value: 10000 + default_value: 0 + Id: + type: string + description: The unique identifier for the cluster. + configuration_disabled: true + deploy_time: true + required: true + +classification: + is: + - auto_scaling + - ecs + +delete_context: + requires_no_upstream: true + +deployment_permissions: + deploy: ["ecs:PutClusterCapacityProviders"] + tear_down: ["ecs:DeleteCapacityProvider"] + update: ["ecs:UpdateCapacityProvider"] \ No newline at end of file diff --git a/pkg/templates/aws/resources/ecs_service.yaml b/pkg/templates/aws/resources/ecs_service.yaml index 0be0593dc..94f254ca7 100644 --- a/pkg/templates/aws/resources/ecs_service.yaml +++ b/pkg/templates/aws/resources/ecs_service.yaml @@ -7,6 +7,23 @@ properties: default_value: false description: Indicates whether the task's elastic network interface receives a public IP address + CapacityProviderStrategies: + type: set + operational_rule: + if: '{{ hasUpstream "aws:ecs_capacity_provider" (downstream "aws:ecs_cluster" .Self) }}' + value: + - CapacityProvider: '{{ fieldRef "Id" (upstream "aws:ecs_capacity_provider" (downstream "aws:ecs_cluster" .Self)) }}' + Weight: 1 + properties: + CapacityProvider: + type: string + description: Short name of the capacity provider. + Weight: + type: int + description: Relative percentage of the total number of launched tasks that should use the specified capacity provider. + Base: + type: int + description: Number of tasks, at a minimum, to run on the specified capacity provider. Cluster: type: resource(aws:ecs_cluster) operational_rule: @@ -40,8 +57,14 @@ properties: description: Specifies whether to force a new deployment of the service LaunchType: type: string - default_value: FARGATE + allowed_values: + - EC2 + - FARGATE + - EXTERNAL description: The launch type on which to run your service + operational_rule: + if: '{{ not (hasField "CapacityProviderStrategies" .Self) }}' + value: FARGATE LoadBalancers: type: list(map) properties: diff --git a/pkg/templates/aws/resources/ecs_task_definition.yaml b/pkg/templates/aws/resources/ecs_task_definition.yaml index 7a4ce9edc..ff85888d4 100644 --- a/pkg/templates/aws/resources/ecs_task_definition.yaml +++ b/pkg/templates/aws/resources/ecs_task_definition.yaml @@ -184,7 +184,8 @@ properties: description: The Docker networking mode to use for the containers in the task RequiresCompatibilities: type: list(string) - default_value: + allowed_values: + - EC2 - FARGATE description: A list of launch types required by the task EfsVolumes: diff --git a/pkg/templates/aws/resources/iam_instance_profile.yaml b/pkg/templates/aws/resources/iam_instance_profile.yaml index 091319bef..336af765c 100644 --- a/pkg/templates/aws/resources/iam_instance_profile.yaml +++ b/pkg/templates/aws/resources/iam_instance_profile.yaml @@ -14,6 +14,12 @@ properties: by the EC2 instances aws:tags: type: model + Arn: + type: string + description: The Amazon Resource Name (ARN) specifying the instance profile. + deploy_time: true + configuration_disabled: true + required: true deployment_permissions: deploy: ["iam:CreateInstanceProfile"] diff --git a/pkg/templates/aws/resources/iam_role.yaml b/pkg/templates/aws/resources/iam_role.yaml index 92bdf7afc..408442e18 100644 --- a/pkg/templates/aws/resources/iam_role.yaml +++ b/pkg/templates/aws/resources/iam_role.yaml @@ -1,5 +1,16 @@ qualified_type_name: aws:iam_role display_name: IAM Role +sanitize_name: + # https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Limits.html#RDS_Limits.Constraints + # Identifiers have these naming constraints: + # - Must contain 1–63 alphanumeric characters or hyphens. + # - First character must be a letter. + # - Can't end with a hyphen or contain two consecutive hyphens. + # - Must be unique for all DB instances per AWS account, per AWS Region. + | + {{ . + | length 1 55 + }} properties: AssumeRolePolicyDoc: