无法通过lambda函数承担角色 - Python

时间:2017-09-09 21:48:53

标签: python amazon-web-services aws-lambda boto3

嗨,我从昨天起就遇到了这个奇怪的问题。我有一个python模块web_token.py,当我尝试在pycharm上手动运行它并打印request_url它完全正常并输出requested_url。但是当我将web_token.py和fetch_accounts.py压缩在一起并将其上传到lambda函数时,它会给我以下错误 -

  

调用AssumeRole操作时发生错误(AccessDenied):User:arn:aws:sts :: 5398XXXXXXX:assume-role / sandbox-amp_sandbox-dev / sandbox-dev-amp_sandbox无权执行:sts:AssumeRole资源:arn:aws:iam :: 4540XXXXXXXX:role / AMPSandbox

我甚至试过给它FullAdministrativeAccess,但它似乎仍然有效。虽然我可以在pycharm中以stanalone模式运行web_token.py时生成requested_url。有人可以提供一些指导,真的很感激。

来自

的代码段
  

retrieve_accounts.py

import boto3

import web_token


def get_account(event, context):
    client = boto3.client('dynamodb')
    NameID = "test@orgz.com"
    ManagerEmail = "test1@orgaz.com"
    response = client.scan(
        TableName='Sandbox-Users',
        ScanFilter={
            'NameID': {
                'AttributeValueList': [
                    {
                        'S': NameID,
                    },
                ],
                'ComparisonOperator': 'EQ'
            }
        }
    )
    return web_token.request_url
  

web_token.py

import httplib
import urllib, json
import boto3

client = boto3.client('sts')
assumed_role_object = client.assume_role(
    RoleArn="arn:aws:iam::4540XXXXXXXX:role/AMPSandboxRole",
    RoleSessionName="AssumeRoleSession"
)

# Step 3: Format resulting temporary credentials into JSON
json_string_with_temp_credentials = '{'
json_string_with_temp_credentials += '"sessionId":"' + assumed_role_object.get("Credentials").get("AccessKeyId") + '",'
json_string_with_temp_credentials += '"sessionKey":"' + assumed_role_object.get("Credentials").get("SecretAccessKey") + '",'
json_string_with_temp_credentials += '"sessionToken":"' + assumed_role_object.get("Credentials").get("SessionToken") + '"'
json_string_with_temp_credentials += '}'

# Step 4. Make request to AWS federation endpoint to get sign-in token. Construct the parameter string with
# the sign-in action request, a 12-hour session duration, and the JSON document with temporary credentials
# as parameters.
request_parameters = "?Action=getSigninToken"
request_parameters += "&SessionDuration=43200"
request_parameters += "&Session=" + urllib.quote_plus(json_string_with_temp_credentials)
request_url = "/federation" + request_parameters

conn = httplib.HTTPSConnection("signin.aws.amazon.com")
conn.request("GET", request_url)
r = conn.getresponse()
# Returns a JSON document with a single element named SigninToken.
signin_token = json.loads(r.read())

request_parameters = "?Action=login"
request_parameters += "&Issuer=sandbox.com"
request_parameters += "&Destination=" + urllib.quote_plus("https://console.aws.amazon.com/")
request_parameters += "&SigninToken=" + signin_token["SigninToken"]
request_url = "https://signin.aws.amazon.com/federation" + request_parameters

更新: 我有两个策略附加到sandbox-amp_sandbox-dev role-

InfraLoggingPolicy [在5398XXXXXXX中]

    {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "sqs:SendMessage",
                "sqs:SendMessageBatch"
            ],
            "Resource": "arn:aws:sqs:*:131703196249:org-logging-prod",
            "Effect": "Allow"
        },
        {
            "Action": [
                "ec2:DescribeInstances",
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::em-log-intake-us-east-1-prod/*",
                "arn:aws:s3:::em-log-intake-us-west-2-prod/*"
            ]
        }
    ]
}

sandbox-amp_sandbox-policy-dev [在5398XXXXXXX中]

    {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "dynamodb:*",
            "Resource": "arn:aws:dynamodb:*:*:*"
        }
    ]
}

更新2.0 以上政策来自我的帐号5398XXXXXXX。我在4540XXXXXXXX账户AMPSandboxRole中有以下角色,我有以下政策

AssumeRole [在4540XXXXXXXX中]

    {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Resource": "arn:aws:iam::*:role/AMPSandboxRole",
            "Action": "sts:AssumeRole"
        }
    ]
}

[4540XXXXXXXX]中的组织访问

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "organizations:Describe*",
                "organizations:List*",
                "organizations:CreateAccount",
                "organizations:MoveAccount"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "organizations:MoveAccount"
            ],
            "Resource": "arn:aws:organizations::454084028794:root/o-eyec2h6qr0/r-ekzh"
        },
        {
            "Effect": "Allow",
            "Action": [
                "organizations:*"
            ],
            "Resource": "arn:aws:organizations::45xxxxxxxxxx:ou/o-eyec2h6qr0/ou-ekzh-x2xcsupl"
        }
    ]
}

更新3.0 45xxxxxxxxxx中的信任关系

 {
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::53xxxxxxxxxx:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

4 个答案:

答案 0 :(得分:1)

错误说:

  

用户:arn:aws:sts :: 5398XXXXXXX:assume-role / sandbox-amp_sandbox-dev / sandbox-dev-amp_sandbox无权执行:sts:AssumeRole on resource:arn:aws:iam :: 4540XXXXXXXX:作用/ AMPSandbox

AWS Lambda函数正在您上面列出的角色下执行。它只有权调用dynamodb:*还需要获得拨打AssumeRole的权限。

您的政策应更新为:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PermitDynamoDB",
      "Action": "dynamodb:*",
      "Effect": "Allow",
      "Resource": "*"
    },
    {
      "Sid": "PermitAssumeRole",
      "Action": [
        "sts:AssumeRole"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:iam::4540XXXXXXXX:role/AMPSandboxRole"
    }
  ]
}

答案 1 :(得分:0)

我想您忘记了信托关系政策文件中的Principal条目:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PermitAssumeRole",
      "Action": [
        "sts:AssumeRole"
      ],
       "Principal": {
        "Service": [
          "dynamodb.amazonaws.com",
          "lambda.amazonaws.com"
        ]
      },
      "Effect": "Allow",
      "Resource": "arn:aws:iam::4540XXXXXXXX:role/AMPSandboxRole"
    }
  ]
}
  

信任策略是一种JSON格式的文档,您可以在其中定义允许该角色的人员。此可信实体作为文档中的主体元素包含在策略中。

因此,您的信任关系政策文档应在 Principal 元素中包含您希望担任该角色的AWS资源

答案 2 :(得分:0)

我终于能够与AWS团队中的一些人找到这个帐户。因此,每当从一个帐户担当另一个角色时,我们都需要显式提供我们要担当角色的帐户的访问密钥和秘密密钥。所以它应该看起来像这样-

sts_connection = boto3.client('sts',
                                  aws_access_key_id="",
                                  aws_secret_access_key="")

通过提供这些详细信息,我终于可以在其他帐户中担任职务。感谢大家的指导和帮助。

答案 3 :(得分:0)

您将需要编辑信任关系并添加可以信任的角色名称。 这是一个示例-

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<<Account-ID>>:role/<Role_Name_to_be_trusted>",
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

这是一个有用的链接- https://github.com/serverless/serverless/issues/3040