moto icon indicating copy to clipboard operation
moto copied to clipboard

Request AWS::EMR::Cluster resource to be added to cloudformation

Open sli10 opened this issue 1 year ago • 6 comments

Request for AWS::EMR::Cluster to be added to cloudformation. This is used for our testing and we would like to request this resource to be added.

sli10 avatar Feb 21 '24 19:02 sli10

Hi @sli10, welcome to Moto! I'll mark it as an enhancement to add this feature.

bblommers avatar Feb 22 '24 20:02 bblommers

Hi @sli10, an initial implementation is now part of moto >= 5.0.3.dev14 and the latest Docker image.

Are you able to try it out, and see whether this solves your issue?

Not all properties for the CloudFormation-template are processed at the moment, so please let us know if there are any specific properties that you use that are missing.

bblommers avatar Feb 23 '24 12:02 bblommers

Hi @bblommers, we were able to try this out and it resolved our issue. On top of that we were encountering an issue with the stack deletion. We were wondering if Cloudformation implementation supports in order deletion of resources?

sli10 avatar Feb 28 '24 23:02 sli10

Happy to hear that @sli10!

I don't think we do anything special with stack deletion - we just delete all all resources in a random order, and re-try to delete them in case of failure, up to 5 times, to try and resolve any dependency problems.

Can you share a bit more about the issues you're running into, ideally with an example template?

bblommers avatar Feb 28 '24 23:02 bblommers

Hi @bblommers , we are running into an issue with delete stack where the ordering of how the resources are deleted is causing an issue. When the cloudformation delete it's resources it gets deleted in reverse order it is created, so in our case the random order that moto deletes in gives us an error of An error occurred (DeleteConflict) when calling the DeleteStack operation: Cannot delete entity, must remove roles from instance profile first.

Example of the resources we are using: Resources: Cluster: Type: 'AWS::EMR::Cluster' Properties: : : emrRole: Type: 'AWS::IAM::Role' : : emrEc2Role: Condition: CreateEMREc2Role Type: 'AWS::IAM::Role' : : emrEc2InstanceProfile: Type: 'AWS::IAM::InstanceProfile' Properties: : :

sli10 avatar Feb 29 '24 20:02 sli10

With that particular example I can't quite reproduce it @sli10 - but I imagine that the actual setup is quite more complex.

Having said that, I was able to improve the logic a bit around stack deletions in #7413. Are you able to test whether moto >= 5.0.3.dev34 fixes your problem?

If that doesn't work, I would probably need a reproducible example to really understand what's going wrong.

bblommers avatar Mar 01 '24 22:03 bblommers

Hi @bblommers, the issue with delete stack is not producible with latest version any more, thank you for your timely response. We have a few more problems, one relating to AWS::EFS::FileSystem which complains about the following missing parameters EFSBackend.create_file_system() missing 7 required positional arguments: 'performance_mode', 'kms_key_id', 'throughput_mode', 'provisioned_throughput_in_mibps', 'availability_zone_name', 'backup', and 'tags'. According to the aws documentation, these aren't required fields. Are these required for moto?

Example of cf template: Resources: FileSystem: Type: 'AWS::EFS::FileSystem' Properties: Encrypted: true

Another issue is related to the emr cluster resource mentioned above, when we create a resource using the latest docker image we get No Moto CloudFormation support for AWS::EMR::Cluster. Create stack request outputs stack id, but doesn't end up creating cluster.

One more request we have regarding the AWS::IAM::Role resource, we were wondering if we can add support for RoleId?

sli10 avatar Mar 05 '24 21:03 sli10

when we create a resource using the latest docker image

Just to double check - do you mean the latest version (5.0.2), or motoserver/moto:latest? We added support for EMR::Cluster a few weeks ago, and while there hasn't been a proper release yet, it should be part of the :latest Docker image.

I'll have a look at the other issues later this week.

bblommers avatar Mar 05 '24 23:03 bblommers

We are using motoserver/moto:latest as the Docker image.

sli10 avatar Mar 05 '24 23:03 sli10

Update on delete stack issue, sorry for going back and forth. Here is a reproducible example @bblommers , that's causing an issue when trying to delete stack. We were able to reproduce the An error occurred (DeleteConflict) when calling the DeleteStack operation: Cannot delete entity, must remove roles from instance profile first. with this cf template.

` Parameters: InputRole: Type: String Default: "test-emr-role"

Resources: CertificateStoreSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Allow NFS traffic VpcId: "subnet-f90771ae" CertificateStoreSecurityGroupIngress: Type: 'AWS::EC2::SecurityGroupIngress' Properties: FromPort: 2049 ToPort: 2049 IpProtocol: tcp GroupId: !Ref CertificateStoreSecurityGroup SourceSecurityGroupId: !Ref CertificateStoreSecurityGroup Cluster: Type: 'AWS::EMR::Cluster' Properties: LogUri: "s3://test-bucket/emr-logs" EbsRootVolumeSize: 64 Instances: MasterInstanceGroup: InstanceCount: 1 InstanceType: m6g.xlarge Market: ON_DEMAND Name: cfnMaster EbsConfiguration: EbsOptimized: true EbsBlockDeviceConfigs: - VolumeSpecification: SizeInGB: 128 VolumeType: gp3 VolumesPerInstance: 1 CoreInstanceGroup: InstanceCount: 1 InstanceType: m6g.xlarge Market: ON_DEMAND Name: cfnCore EbsConfiguration: EbsOptimized: true EbsBlockDeviceConfigs: - VolumeSpecification: SizeInGB: 128 VolumeType: gp3 VolumesPerInstance: 1 TerminationProtected: 'false' AdditionalMasterSecurityGroups: - !Ref CertificateStoreSecurityGroup AdditionalSlaveSecurityGroups: - !Ref CertificateStoreSecurityGroup HadoopVersion: 3.3.3 Name: !Ref 'AWS::StackName' JobFlowRole: !Ref emrEc2InstanceProfile ServiceRole: !Ref emrRole ReleaseLabel: emr-6.10.0 AutoScalingRole: EMR_AutoScaling_DefaultRole ScaleDownBehavior: TERMINATE_AT_TASK_COMPLETION VisibleToAllUsers: true Applications: - Name: Hive - Name: Spark emrRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2008-10-17 Statement: - Sid: '' Effect: Allow Principal: Service: elasticmapreduce.amazonaws.com Action: 'sts:AssumeRole' Path: / ManagedPolicyArns: - 'arn:aws:iam::aws:policy/service-role/AmazonElasticMapReduceRole' emrEc2Role: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2008-10-17 Statement: - Sid: '' Effect: Allow Principal: Service: ec2.amazonaws.com Action: 'sts:AssumeRole' Path: / Policies: - PolicyName: EMRNodeResourcesPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - 'kms:Decrypt' Resource: '' - Effect: Allow Action: - 'logs:DescribeLogGroups' - 'logs:DescribeLogStreams' - 'logs:CreateLogGroup' - 'logs:CreateLogStream' Resource: '' - Effect: Allow Action: 'ssm:StartSession' Resource: - 'arn:aws:ec2:::instance/' - 'arn:aws:ssm:::document/AWS-StartSSHSession' - 'arn:aws:ssm::*:document/AWS-StartPortForwardingSession' ManagedPolicyArns: - 'arn:aws:iam::aws:policy/service-role/AmazonElasticMapReduceforEC2Role' - 'arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole' - 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore' - 'arn:aws:iam::aws:policy/CloudWatchAgentAdminPolicy' - 'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess' - 'arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess' emrEc2InstanceProfile: Type: 'AWS::IAM::InstanceProfile' Properties: Path: / Roles: - !Ref InputRole EventBridgeEventBusPolicy: Type: AWS::IAM::Policy Properties: Roles: - !Ref InputRole PolicyName: EventBridgeEventBusPolicy PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "events:DescribeEventBus" - "events:PutEvents" Resource: "arn:aws:events:us-west-2:12345612345:event-bus/test-event-bus" LambdaPolicy: Type: AWS::IAM::Policy Properties: Roles: - !Ref InputRole PolicyName: LambdaPolicy PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "lambda:InvokeFunction" Resource: "arn:aws:lambda:us-west-2:12345612345:function:test-function"`

sli10 avatar Mar 06 '24 00:03 sli10

Thank you for the example @sli10, that was very useful. I hadn't considered the scenario where a IAM role could be created/controlled outside of CloudFormation.

Creating an AWS::EMR::Cluster does work for me - as long as I explicitly do a docker pull motoserver/moto:latest. Could there be a caching issue at play somehow?

The latest release (as of this morning) contains:

  • Delete support for AWS::EMR::Cluster
  • Create and Delete support for AWS::EFS::FileSystem (it was implemented, just incredibly broken - should be fixed now)
  • A fix for the IAM DeleteConflict

One more request we have regarding the AWS::IAM::Role resource, we were wondering if we can add support for RoleId?

Yes - I'll try to get to that later this week.

bblommers avatar Mar 07 '24 10:03 bblommers

@bblommers Thank you for fixing the above. The latest release has resolved the issues you've listed above and I've also tried it out and it was working on our end.

We realized a few more things that we want to request support for. AWS::Logs::LogGroup doesn't seem to have delete implemented which I think is cause this issue when we delete the stack and recreate it with the same name. b'{"__type": "ResourceAlreadyExistsException", "message": "The specified log group already exists"}' Another resource that isn't supported is the AWS::EMR::InstanceGroupConfig, we were wondering if these resources can also be added to moto?

Thank you so much for your help, we really appreciate it!

sli10 avatar Mar 07 '24 21:03 sli10

Didn't mean to close this, so I'll reopen. But latest should support everything you've asked for so far @sli10!

bblommers avatar Mar 08 '24 22:03 bblommers

Thanks @bblommers for your help!

Question about latest docker image, we are getting this error that didn't occur before pulling latest moto docker image. An error occurred (ValidationError) when calling the DescribeStacks operation: Template error: instance of Fn::GetAtt references undefined resource Role This has been occurring on the most recent docker image. We are creating a role resource with cloudformation and outputs the !GetAtt role.Arn. Can you please take a look?

sli10 avatar Mar 11 '24 18:03 sli10

Happy to help @sli10!

I can't reproduce that ValidationError though, I'm afraid. I just tried the following template, and that is created just fine (with the correct outputs) :

AWSTemplateFormatVersion: 2010-09-09
Resources:
  role:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
              - ec2.amazonaws.com
            Action:
              - 'sts:AssumeRole'
Outputs:
  RootRole:
    Value: !Ref role
  RoleARN:
    Value: {"Fn::GetAtt": ["role", "Arn"]}
  InlineRoleARN:
    Value: !GetAtt role.Arn
  RoleID:
    Value: {"Fn::GetAtt": ["role", "RoleId"]}

bblommers avatar Mar 11 '24 19:03 bblommers

@bblommers Does moto cloudformation support conditions? For the role use case we have a condition check, if the parameter inputted is not empty then continue with creating the resource.

sli10 avatar Mar 13 '24 07:03 sli10

@sli10 Yes, we do - we have some tests for that here:

https://github.com/getmoto/moto/blob/565442e23d642fc379cc1caf2dc0ce1280d6c919/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py#L1984

bblommers avatar Mar 13 '24 15:03 bblommers

Hi @bblommers, we have conditional checks in the outputs section. Here is an example that reproduces the error with DescribeStacks operation: Template error: instance of Fn::GetAtt references undefined resource role.

Template Sample:

Outputs:
  roleArn:
    Condition: RoleCondition
    Value: !GetAtt role.Arn

Parameters:
  roleName:
    Type: String
    Description: Predefined role name

Conditions:
  RoleCondition: !Equals [ !Ref roleName, "" ]

Resources:
  role:
    Condition: RoleCondition
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - 'sts:AssumeRole'

sli10 avatar Mar 13 '24 17:03 sli10

Hi @sli10, can you pull the latest and try again? This should be fixed as now - with the latest PR Moto now behaves the same as AWS with conditional outputs.

bblommers avatar Mar 15 '24 10:03 bblommers

I'll assume this is fixed - but feel free to open a new issue if you run into any (other) problems.

bblommers avatar May 04 '24 10:05 bblommers