diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md index 2f5d463067a35..f4721f21fda00 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md @@ -700,6 +700,20 @@ new tasks.EmrCreateCluster(this, 'Create Cluster', { }); ``` +If you want to use an [auto-termination policy](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-auto-termination-policy.html), +you can specify the `autoTerminationPolicy` property. Set the `idleTimeout` as a `Duration` between 60 seconds and 7 days. +`autoTerminationPolicy` requires the EMR release label to be 5.30.0 or above. + +```ts +new tasks.EmrCreateCluster(this, 'Create Cluster', { + instances: {}, + name: 'ClusterName', + autoTerminationPolicy: { + idleTimeout: Duration.seconds(120), + }, +}); +``` + ### Termination Protection Locks a cluster (job flow) so the EC2 instances in the cluster cannot be diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-create-cluster.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-create-cluster.ts index 4cac7c7180bde..eed78656efec0 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-create-cluster.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-create-cluster.ts @@ -5,6 +5,7 @@ import { Construct } from 'constructs'; import { integrationResourceArn, validatePatternSupported } from '../private/task-utils'; import { ApplicationConfigPropertyToJson, + AutoTerminationPolicyPropertyToJson, BootstrapActionConfigToJson, ConfigurationPropertyToJson, InstancesConfigPropertyToJson, @@ -67,6 +68,15 @@ export interface EmrCreateClusterProps extends sfn.TaskStateBaseProps { */ readonly autoScalingRole?: iam.IRole; + /** + * An auto-termination policy for an Amazon EMR cluster. An auto-termination policy defines the amount of + * idle time in seconds after which a cluster automatically terminates. The value must be between + * 60 seconds and 7 days. + * + * @default - None + */ + readonly autoTerminationPolicy?: EmrCreateCluster.AutoTerminationPolicyProperty; + /** * A list of bootstrap actions to run before Hadoop starts on the cluster nodes. * @@ -269,6 +279,7 @@ export class EmrCreateCluster extends sfn.TaskStateBase { AdditionalInfo: cdk.stringToCloudFormation(this.props.additionalInfo), Applications: cdk.listMapper(ApplicationConfigPropertyToJson)(this.props.applications), AutoScalingRole: cdk.stringToCloudFormation(this._autoScalingRole?.roleName), + AutoTerminationPolicy: this.props.autoTerminationPolicy ? AutoTerminationPolicyPropertyToJson(this.props.autoTerminationPolicy) : undefined, BootstrapActions: cdk.listMapper(BootstrapActionConfigToJson)(this.props.bootstrapActions), Configurations: cdk.listMapper(ConfigurationPropertyToJson)(this.props.configurations), CustomAmiId: cdk.stringToCloudFormation(this.props.customAmiId), @@ -1389,6 +1400,20 @@ export namespace EmrCreateCluster { readonly version?: string; } + /** + * Auto-termination policy for the EMR cluster. + * + * @see https://docs.aws.amazon.com/emr/latest/APIReference/API_AutoTerminationPolicy.html + * + */ + export interface AutoTerminationPolicyProperty { + + /** + * Specifies the amount of idle time after which the cluster automatically terminates. + */ + readonly idleTimeout: cdk.Duration; + } + /** * Configuration of the script to run during a bootstrap action. * diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/private/cluster-utils.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/private/cluster-utils.ts index c8ae8a50a360c..fd05d71370584 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/private/cluster-utils.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/private/cluster-utils.ts @@ -4,8 +4,6 @@ import { EmrModifyInstanceGroupByName } from '../emr-modify-instance-group-by-na /** * Render the KerberosAttributesProperty as JSON - * - * @param property */ export function KerberosAttributesPropertyToJson(property: EmrCreateCluster.KerberosAttributesProperty) { return { @@ -19,8 +17,6 @@ export function KerberosAttributesPropertyToJson(property: EmrCreateCluster.Kerb /** * Render the InstancesConfigProperty to JSON - * - * @param property */ export function InstancesConfigPropertyToJson(property: EmrCreateCluster.InstancesConfigProperty) { return { @@ -46,8 +42,6 @@ export function InstancesConfigPropertyToJson(property: EmrCreateCluster.Instanc /** * Render the ApplicationConfigProperty as JSON - * - * @param property */ export function ApplicationConfigPropertyToJson(property: EmrCreateCluster.ApplicationConfigProperty) { return { @@ -58,10 +52,17 @@ export function ApplicationConfigPropertyToJson(property: EmrCreateCluster.Appli }; } +/** + * Render the AutoTerminationPolicyProperty as JSON + */ +export function AutoTerminationPolicyPropertyToJson(property: EmrCreateCluster.AutoTerminationPolicyProperty) { + return { + IdleTimeout: cdk.numberToCloudFormation(property.idleTimeout.toSeconds()), + }; +} + /** * Render the ConfigurationProperty as JSON - * - * @param property */ export function ConfigurationPropertyToJson(property: EmrCreateCluster.ConfigurationProperty) { return { @@ -73,8 +74,6 @@ export function ConfigurationPropertyToJson(property: EmrCreateCluster.Configura /** * Render the EbsBlockDeviceConfigProperty as JSON - * - * @param property */ export function EbsBlockDeviceConfigPropertyToJson(property: EmrCreateCluster.EbsBlockDeviceConfigProperty) { return { @@ -89,8 +88,6 @@ export function EbsBlockDeviceConfigPropertyToJson(property: EmrCreateCluster.Eb /** * Render the EbsConfigurationProperty to JSON - * - * @param property */ export function EbsConfigurationPropertyToJson(property: EmrCreateCluster.EbsConfigurationProperty) { return { @@ -117,8 +114,6 @@ export function InstanceTypeConfigPropertyToJson(property: EmrCreateCluster.Inst /** * Render the InstanceFleetProvisioningSpecificationsProperty to JSON - * - * @param property */ export function InstanceFleetProvisioningSpecificationsPropertyToJson(property: EmrCreateCluster.InstanceFleetProvisioningSpecificationsProperty) { return { @@ -133,8 +128,6 @@ export function InstanceFleetProvisioningSpecificationsPropertyToJson(property: /** * Render the InstanceFleetConfigProperty as JSON - * - * @param property */ export function InstanceFleetConfigPropertyToJson(property: EmrCreateCluster.InstanceFleetConfigProperty) { return { @@ -152,8 +145,6 @@ export function InstanceFleetConfigPropertyToJson(property: EmrCreateCluster.Ins /** * Render the MetricDimensionProperty as JSON - * - * @param property */ export function MetricDimensionPropertyToJson(property: EmrCreateCluster.MetricDimensionProperty) { return { @@ -164,8 +155,6 @@ export function MetricDimensionPropertyToJson(property: EmrCreateCluster.MetricD /** * Render the ScalingTriggerProperty to JSON - * - * @param property */ export function ScalingTriggerPropertyToJson(property: EmrCreateCluster.ScalingTriggerProperty) { return { @@ -185,8 +174,6 @@ export function ScalingTriggerPropertyToJson(property: EmrCreateCluster.ScalingT /** * Render the ScalingActionProperty to JSON - * - * @param property */ export function ScalingActionPropertyToJson(property: EmrCreateCluster.ScalingActionProperty) { return { @@ -201,8 +188,6 @@ export function ScalingActionPropertyToJson(property: EmrCreateCluster.ScalingAc /** * Render the ScalingRuleProperty to JSON - * - * @param property */ export function ScalingRulePropertyToJson(property: EmrCreateCluster.ScalingRuleProperty) { return { @@ -215,8 +200,6 @@ export function ScalingRulePropertyToJson(property: EmrCreateCluster.ScalingRule /** * Render the AutoScalingPolicyProperty to JSON - * - * @param property */ export function AutoScalingPolicyPropertyToJson(property: EmrCreateCluster.AutoScalingPolicyProperty) { return { @@ -230,8 +213,6 @@ export function AutoScalingPolicyPropertyToJson(property: EmrCreateCluster.AutoS /** * Render the InstanceGroupConfigProperty to JSON - * - * @param property */ export function InstanceGroupConfigPropertyToJson(property: EmrCreateCluster.InstanceGroupConfigProperty) { return { @@ -250,8 +231,6 @@ export function InstanceGroupConfigPropertyToJson(property: EmrCreateCluster.Ins /** * Render the PlacementTypeProperty to JSON - * - * @param property */ export function PlacementTypePropertyToJson(property: EmrCreateCluster.PlacementTypeProperty) { return { @@ -262,8 +241,6 @@ export function PlacementTypePropertyToJson(property: EmrCreateCluster.Placement /** * Render the BootstrapActionProperty as JSON - * - * @param property */ export function BootstrapActionConfigToJson(property: EmrCreateCluster.BootstrapActionConfigProperty) { return { @@ -277,8 +254,6 @@ export function BootstrapActionConfigToJson(property: EmrCreateCluster.Bootstrap /** * Render the InstanceGroupModifyConfigProperty to JSON - * - * @param property */ export function InstanceGroupModifyConfigPropertyToJson(property: EmrModifyInstanceGroupByName.InstanceGroupModifyConfigProperty) { return { @@ -291,8 +266,6 @@ export function InstanceGroupModifyConfigPropertyToJson(property: EmrModifyInsta /** * Render the ShrinkPolicyProperty to JSON - * - * @param property */ function ShrinkPolicyPropertyToJson(property: EmrModifyInstanceGroupByName.ShrinkPolicyProperty) { return { @@ -303,8 +276,6 @@ function ShrinkPolicyPropertyToJson(property: EmrModifyInstanceGroupByName.Shrin /** * Render the InstanceResizePolicyProperty to JSON - * - * @param property */ function InstanceResizePolicyPropertyToJson(property: EmrModifyInstanceGroupByName.InstanceResizePolicyProperty) { return { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-create-cluster.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-create-cluster.test.ts index 3effd99e5eed0..74342d66efb53 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-create-cluster.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-create-cluster.test.ts @@ -864,6 +864,58 @@ test('Create Cluster with InstanceFleet with allocation strategy=capacity-optimi }); }); +test('Create Cluster with AutoTerminationPolicy', () => { + // WHEN + const task = new EmrCreateCluster(stack, 'Task', { + instances: {}, + clusterRole, + name: 'Cluster', + serviceRole, + autoScalingRole, + autoTerminationPolicy: { + idleTimeout: cdk.Duration.seconds(120), + }, + integrationPattern: sfn.IntegrationPattern.REQUEST_RESPONSE, + }); + + // THEN + expect(stack.resolve(task.toStateJson())).toEqual({ + Type: 'Task', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:::elasticmapreduce:createCluster', + ], + ], + }, + End: true, + Parameters: { + Name: 'Cluster', + Instances: { + KeepJobFlowAliveWhenNoSteps: true, + }, + VisibleToAllUsers: true, + JobFlowRole: { + Ref: 'ClusterRoleD9CA7471', + }, + ServiceRole: { + Ref: 'ServiceRole4288B192', + }, + AutoScalingRole: { + Ref: 'AutoScalingRole015ADA0A', + }, + AutoTerminationPolicy: { + IdleTimeout: 120, + }, + }, + }); +}); + test('Create Cluster with InstanceFleet', () => { // WHEN const task = new EmrCreateCluster(stack, 'Task', {