Tengo una función de paso (padre) creada en una plantilla SAM/CloudFormation que, entre otras cosas, llama a otra función de paso (hijo). Estoy siguiendo las instrucciones para llamar a Child, desde Parent, usando el patrón de integración de servicios . Pero recibo un error relacionado con IAM (creo) que no puedo resolver al implementar a través de la CLI. (El error se manifiesta en la salida de la CLI, por lo que en realidad nunca llega a AWS. Ha habido muchas implementaciones anteriores, por lo que el conjunto de changeset solo intenta modificar la función Step con esta implementación).
'arn:aws:iam::{Account-Number}:role/{Parent-Step-Function-Role-Name}' is not authorized to create managed-rule. (Service: AWSStepFunctions; Status Code: 400; Error Code: AccessDeniedException; Request ID: {Long-Id-Number})
Para obtener el comportamiento síncrono que quiero (el padre llama al niño, espera a que se complete la ejecución del niño y luego pasa al siguiente estado), utilizo la sugerencia (del enlace del patrón de integración de servicios anterior) para crear una tarea (en mi plantilla SAM) que se parece a lo siguiente:
...More States... "Call Child State": { "Type": "Task", "Next": "The Next State", "Resource": "arn:aws:states:::states:startExecution.sync", "Parameters": { "Input": { "comment": "Hello World!" }, "StateMachineArn": "${ChildStepFunction}", "Name": "ChildExecutionFromParent" } }, ...More States... He definido el rol de IAM para Parent de la siguiente manera, asegurándome de que solo tiene privilegios de ejecución de Lambda para las funciones de Lambda en Parent y, más aplicable al problema, tiene permiso para StartExecution la ejecución de Child. Seguí las instrucciones en el enlace justo debajo, que indicaba que StartExecution era el único permiso necesario cuando se usaba el patrón de integración de servicios.
https://docs.aws.amazon.com/step-functions/latest/dg/stepfunctions-iam.html
ParentStepFunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - !Sub states.${AWS::Region}.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: ChildStepFunctionExecution PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: states:StartExecution Resource: !Ref ChildStepFunction - Effect: Allow Action: lambda:InvokeFunction Resource: - !GetAtt Function1.Arn ... - !GetAtt FunctionX.Arn Intenté reemplazar el estado anterior con un estado de Pass simple para asegurarme de que no hubiera otros errores en la función de paso que bloquearan la implementación, y se implementó bien. Así que sé que tiene que ver con ese Estado. (También cabe destacar que al implementar con Pass State para realizar pruebas, dejé el rol como se definió anteriormente, por lo que, nuevamente, sé que no es un error de sintaxis con las Políticas lo que estaría causando esto. Obviamente, eso no es lo mismo que quizás tener políticas incorrectas o faltantes ).
[Actualizado el 22/05/2020 según la publicación de @Matt y el comentario de @Joe.CK para reducir el alcance al Recurso específico requerido.]
Esta pregunta de Stack Overflow me indicó la dirección correcta. botocore.exceptions.ClientError: se produjo un error (AccessDeniedException) al llamar a la operación CreateStateMachine
El problema parece provenir de CloudWatch y pude superarlo agregando la siguiente declaración a mi política de IAM.
- Effect: Allow Action: - events:PutTargets - events:PutRule - events:DescribeRule Resource: - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/StepFunctionsGetEventsForStepFunctionsExecutionRuleEl proyecto de muestra de AWS Step Functions "Iniciar un flujo de trabajo dentro de un flujo de trabajo" incluye algo similar pero restringido a una sola función de Lambda que invoca.
Agregar la definición completa de Rol que resolvió el problema combinando lo que Andrew proporcionó y lo que estaba en la documentación. Está en cuatro partes:
ParentStepFunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - !Sub states.${AWS::Region}.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: ParentStepFunctionExecutionPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: states:StartExecution Resource: !Ref ChildStepFunction - Effect: Allow Action: - states:DescribeExecution - states:StopExecution Resource: "*" - Effect: Allow Action: - events:PutTargets - events:PutRule - events:DescribeRule Resource: !Sub arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/StepFunctionsGetEventsForStepFunctionsExecutionRule - Effect: Allow Action: lambda:InvokeFunction Resource: - !GetAtt Function1.Arn ... - !GetAtt FunctionX.ArnSólo un segundo. Esto es ligeramente diferente, una política en línea, que autoriza la acción events:PutRule en el recurso de regla administrada StepFunctionsGetEventsForStepFunctionsExecutionRule .
StateMachine: Type: AWS::Serverless::StateMachine Properties: DefinitionUri: statemachine/parentstatemachine.asl.json DefinitionSubstitutions: ChildWorkflowArn: !Ref ChildStateMachine Policies: - Version: 2012-10-17 Statement: - Effect: Allow Action: - events:PutTargets - events:PutRule - events:DescribeRule Resource: !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/StepFunctionsGetEventsForStepFunctionsExecutionRule - StepFunctionsExecutionPolicy: StateMachineName: !Ref ChildStateMachineSolo para asegurarse de que no se crucen los cables, lo siguiente es algo así como el error que informa CloudFormation sin la declaración de política en línea, aunque no exactamente.
'arn:aws:iam::xxxxxxxx:role/xxxxxxxx' is not authorized to create managed-rule. ( Service: AWSStepFunctions; Status Code: 400; Error Code: AccessDeniedException; Request ID: xxxxxxx; Proxy: null ) role/xxxxxxxx lo genera la transformación SAM CloudFormation para el recurso AWS::Serverless::StateMachine . Es una automatización flagrante.
Agregué la política administrada "CloudWatcheventsFullAccess" y ese error desapareció. Gracias a las respuestas anteriores. Quería agregar mi ejemplo de código aquí, porque no encajaría dentro de un comentario.
NetworkFactory: Type: AWS::Serverless::StateMachine Properties: DefinitionUri: statemachine/network-factory.asl.json DefinitionSubstitutions: CreateHubStateMachineArn: !Ref CreateHubStateMachine CreateVpcStateMachineArn: !Ref CreateVpcStateMachine Policies: - StepFunctionsExecutionPolicy: StateMachineName: !GetAtt CreateHubStateMachine.Name - StepFunctionsExecutionPolicy: StateMachineName: !GetAtt CreateVpcStateMachine.Name - "CloudWatchEventsFullAccess"StepFunctionsGetEventsForStepFunctionsExecutionRule es definitivamente clave para la solución. Para mi situación, eso no fue suficiente. Al usar Terraform, también tuve que aumentar el proveedor de AWS a >= 2.69, ya que ahí es donde el proveedor selecciona la lógica de reintento para AccessDeniedException s. Además, tenía problemas con el gráfico de dependencia de recursos que creó Terraform para aplicar los cambios. El gráfico tenía terraformación que intentaba crear la máquina de estado antes de que se creara la política y la política tenía dependencias en la máquina de estado. La solución fue dividir la política uber en tres adjuntos de política al rol utilizado por la máquina de estado. Una política tenía StepFunctionsGetEventsForStepFunctionsExecutionRule , una segunda tenía políticas sobre la acción de los states y la tercera era la política uber original. Con eso en su lugar, el gráfico de dependencia fue tal que se crearon las dos nuevas políticas, luego la máquina de estado, luego la política uber original y todo estuvo bien.