Search code examples
amazon-web-serviceselasticsearchamazon-s3amazon-elasticsearch

Security token service exception while restoring snapshot from S3 to AWS managed elasticsearch


I have an AWS managed Elasticsearch Service (say smallES) which has an properly working S3 bucket attached to containing day wise rolling indices of last 1 year. I've created another AWS managed ES cluster (say bigES) for some business reason. I want to restore last 1 year's data from bucket into bigES. It's guaranteed that smallES bigES and bucket all are in the same region and same VPC.

So, I created a policy :

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation",
                "s3:ListBucketMultipartUploads",
                "s3:ListBucketVersions"
            ],
            "Resource": [
                "arn:aws:s3:::bucket"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": [
                "arn:aws:s3:::bucket/*"
            ]
        }
    ]
}

And attached the policy with a role. Trust relationship of that role is

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "s3.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
       }
    ]
}

Now, when I create a snapshot by http request within the same VPC, it can create a snapshot-repo for the bigES and I can query for that too

curl -XGET 'http://bigESid.region.es.amazonaws.com:80/_snapshot'

Output

{
    "snapshot-repo": {
        "type": "s3",
        "settings": {
            "bucket": "bucket",
            "region": "region",
            "role_arn": "role_arn"
        }
    }
}

But when I try to see the snapshots in this snapshot repo I get error (described below)

curl -XGET 'http://bigESid.region.es.amazonaws.com:80/_cat/snapshots/snapshot-repo'

I get the following error:

{
    "error": {
        "root_cause": [
            {
                "type": "a_w_s_security_token_service_exception",
                "reason": "User: arn:aws:sts::acountid:assumed-role/cp-sts-grant-role/swift-region-prod-365021432299 is not authorized to perform: sts:AssumeRole on resource: role-arn (Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied; Request ID: some-id)"
            }
        ],
        "type": "a_w_s_security_token_service_exception",
        "reason": "User: arn:aws:sts::acountid:assumed-role/cp-sts-grant-role/swift-region-prod-365021432299 is not authorized to perform: sts:AssumeRole on resource: role-arn (Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied; Request ID: some-id)"
    },
    "status": 500
}

I've given all access of s3 to my role, but no luck. I've posted all the http requests from a ec2 machine inside the VPC.

Also to mention, if I query like following, I see expected result

curl -XGET 'http://smallESid.region.es.amazonaws.com:80/_cat/snapshots/snapshot-repo'

IDK why I tried making a role which has trust relationship like following. Still no luck.

{
    "Version": "2012-10-17",
    "Statement": [
      {
          "Effect": "Allow",
          "Principal": {
              "Service": "ec2.amazonaws.com"
          },
          "Action": "sts:AssumeRole"
      }
    ]
}

Thanks in advance for any kind of help/suggestions.


Solution

  • I solved this problem using the following policy

    {
    "Statement": [
        {
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation",
                "s3:ListBucketMultipartUploads",
                "s3:ListBucketVersions"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::bucket-name"
            ]
        },
        {
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts",
                "iam:PassRole"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::bucket-name/*"
            ]
        }
    ],
    "Version": "2012-10-17"
    }
    

    Then I attached the policy to the role. I think "iam:PassRole"has done the work.