aws / aws-parallelcluster

AWS ParallelCluster is an AWS supported Open Source cluster management tool to deploy and manage HPC clusters in the AWS cloud.
https://github.com/aws/aws-parallelcluster
Apache License 2.0
817 stars 311 forks source link

Feature request: adding to resources created with pcluster CloudFormation stack with additional_cfn_template #1287

Open joeydumont opened 4 years ago

joeydumont commented 4 years ago

Environment:

Is it possible to access resources created with the base pcluster CloudFormation template within additional_cfn_template?

I wanted to add a lifecycle hook to the ComputeFleet autoscaling group, but the following fails because ComputeFleet is not defined in that nested stack. Since we can't pass parameters from the parent stack to the nested stack (or at least I haven't found how), I believe the parent stack should export some of its variables to expose the resources it creates. (I'm a CloudFormation newbie, so I might be wrong.)

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Additional CloudFormation Stack for ParallelCluster config.",
  "Resources": {
    "ComputeFleetTerminationLifeCycleHook": {
      "Type": "AWS::AutoScaling::LifecycleHook",
      "Properties": {
        "AutoScalingGroupName": {
          "Ref": "ComputeFleet"
        },
        "DefaultResult": "ABANDON",
        "HeartbeatTimeout": 3600,
        "LifeCycleHookName": "ComputeFleetTermination",
        "LifecycleTransition": "autoscaling:EC2_INSTANCE_TERMINATING"
      }
    }
  }
}
enrico-usai commented 4 years ago

Hi @joeydumont

In general it is possible to pass parameters from the parent stack to the nested stack. We are doing it for example for the ebs-substack and all the others substacks.

The missing point is that the additional_cfn_template is treated as a substack but it doesn't have input parameters.

To get what you want you have some ways:

  1. modify the AdditionalCfnStack Resource of the standard template by passing your required parameters as input.
  2. modify the standard aws-parallelcluster.cfn.json template to add your custom resources to the main template.

In both the cases you have to upload the modified template in your S3 bucket and create the stack by passing the template_url parameter.

Let us know if it helps. Enrico

joeydumont commented 4 years ago

Ah, I was afraid it would come down to modifying the standard template.

In general, wouldn't it be better if the base template exported its resources so that other stacks could access them? Like this. That way, users don't have to manually update the CloudFormation stack when a new version of parallelcluster is released.

Thoughts?

demartinofra commented 4 years ago

I'm afraid that values are exported when stack outputs are created, which, if I'm not wrong, happens at the end of a stack provisioning. According to this you should not be able to import in a nested stack a value exported in the parent stack.

An alternative solution that does not require any modification to the ParallelCluster standard template is to add a lambda backed custom resource to the AdditionalCfnStack which reads the parameters from the parent stack (with a describe_stacks call) and returns them in the response object.

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources-lambda.html

joeydumont commented 4 years ago

So, the AdditionalCfnStack would provision a lambda function that reads data from the standard template and then pass them to a different stack?

demartinofra commented 4 years ago

The returned value of a custom resource can be accessed in the same nested template with a Fn::GetAtt. Look at the example in the link above.

The only problem is that you'll have to wait in the lambda function for the ASG to be created in the parent stack.

joeydumont commented 4 years ago

Wouldn't it be necessary to pass the name of parent stack as a parameter to the nested stack to ensure that the DescribeStack call gives a unique result?

demartinofra commented 4 years ago

Yes I'm afraid there is no way to retrieve the parent stack name from a nested stack, unless we explicitly pass it in the template.

I think a valuable enhancement to the additional_cfn_template feature consists in adding a config entry, such as additional_cfn_template_parameters, which allows the user to specify parameters for the nested stack.

joeydumont commented 4 years ago

Yes, that would be very nice.

This is a little involved a PR for me to offer working on this, at least at this point. I'll settle for modifying the standard template for the time being and revisit later.

Thanks!