User: arn:aws:sts::{account_id}:assumed-role/* is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::{account_id}:role/*

I am creating two resources AWS Lambda function and Role using cloudformation template.
I am using role arn as Environment variable. Later using it in code for S3 connection. But getting exception as

com.amazonaws.services.securitytoken.model.AWSSecurityTokenServiceException: 
User: arn:aws:sts::{account_id}:assumed-role/* is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::{account_id}:role/* 
Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied; Request ID: ; Proxy: null)

How can I add same role arn in Trust Relationship and in inline policy?
How to overcome above exception?

Other solutions appreciated

CF Template snippet

Resources:
  LambdaFunctionExecutionRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
#             AWS:
#               - {Role ARN}
            Action:
              - 'sts:AssumeRole'
      Path: /
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
        - 'arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole'
        - 'arn:aws:iam::aws:policy/SecretsManagerReadWrite'
        - 'arn:aws:iam::aws:policy/AmazonS3FullAccess'
        - 'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess'
        - 'arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess'
        - 'arn:aws:iam::aws:policy/service-role/AWSLambdaRole'
      Policies:
      - PolicyName: CustomLambdaPolicy
        PolicyDocument:
          Statement:
          - Effect: Allow
            Action:
            - 'ec2:Describe*'
            - 'ec2:Get*'
            Resource: '*'

  LambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      Description: !Ref Name
      FunctionName: !Ref Name
      Handler: com.fileservice::handleRequest
      Role: !GetAtt LambdaFunctionExecutionRole.Arn
      Timeout: 900
      MemorySize: 512
      Environment:
        Variables:
          bucketName: !Ref S3BucketName
          roleARN: !GetAtt LambdaFunctionExecutionRole.Arn
      CodeUri: target/fileservice-1.0.0.jar
      Runtime: java11

AWS S3 Connectivity Code Snippet

public AmazonS3 connectS3(String roleArn, String region) {
    STSAssumeRoleSessionCredentialsProvider stsAssumeRoleSessionCredentialsProvider = new STSAssumeRoleSessionCredentialsProvider.Builder(
            roleArn, "MySession").withStsClient(AWSSecurityTokenServiceClientBuilder.standard().build())
                    .withRoleSessionDurationSeconds(900).build();

    BasicSessionCredentials basicSessionCredentials = new BasicSessionCredentials(
            stsAssumeRoleSessionCredentialsProvider.getCredentials().getAWSAccessKeyId(),
            stsAssumeRoleSessionCredentialsProvider.getCredentials().getAWSSecretKey(),
            stsAssumeRoleSessionCredentialsProvider.getCredentials().getSessionToken());

    System.out.println("serviceEndpoint:- "+ String.format("https://s3.%s.amazonaws.com", region) );
    AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(basicSessionCredentials))
                            .withEndpointConfiguration( new EndpointConfiguration( String.format("https://s3.%s.amazonaws.com", region), region) )
                            .build();
    return s3Client;
}

Solution 1:

LambdaFunction:
  Type: AWS::Serverless::Function
  Properties:
    Role: !GetAtt LambdaFunctionExecutionRole.Arn

If you are using the role property of AWS::Serverless::Function, you do not need to assume the role again in your Lambda code. Any AWS SDK or CLI will automatically retrieve credentials associated with that role.

Reference: https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html (From the documentation: You provide this role when you create a function, and Lambda assumes the role when your function is invoked.)

Ignoring the fact that you should not have reason to allow a role to assume itself, with CloudFormation, it is not possible to reference the ARN of the role inside the role definition itself. Attempting to use !GetAtt LambdaFunctionExecutionRole.Arn in the trust policy of LambdaFunctionExecutionRole would give a Circular Dependency error.

Edit for changes in code which OP has now included in the question:

Instead of:

public AmazonS3 connectS3(String roleArn, String region) {
    STSAssumeRoleSessionCredentialsProvider stsAssumeRoleSessionCredentialsProvider = new STSAssumeRoleSessionCredentialsProvider.Builder(
            roleArn, "MySession").withStsClient(AWSSecurityTokenServiceClientBuilder.standard().build())
                    .withRoleSessionDurationSeconds(900).build();

    BasicSessionCredentials basicSessionCredentials = new BasicSessionCredentials(
            stsAssumeRoleSessionCredentialsProvider.getCredentials().getAWSAccessKeyId(),
            stsAssumeRoleSessionCredentialsProvider.getCredentials().getAWSSecretKey(),
            stsAssumeRoleSessionCredentialsProvider.getCredentials().getSessionToken());

    System.out.println("serviceEndpoint:- "+ String.format("https://s3.%s.amazonaws.com", region) );
    AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(basicSessionCredentials))
                            .withEndpointConfiguration( new EndpointConfiguration( String.format("https://s3.%s.amazonaws.com", region), region) )
                            .build();
    return s3Client;
}

Why not just do this?

public AmazonS3 connectS3(String region) {
   
    AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withRegion(region).build();
    return s3Client;
}

If your code is running in an AWS Lambda function, you don't need to do an AssumeRole action to get credentials, you can just directly use the role which is assigned to the Lambda function to access S3. The only reason for trying to assume a role would be if it is a completely separate role which has the required permissions which the role assigned to AWS Lambda function does not have.