函数计算访问阿里云其他云服务时,需要授予相应权限,该权限为服务级别。当服务被授予某权限后,该服务下所有函数都将具有此权限。本文介绍如何通过控制台授予函数计算访问其他云服务的权限。

功能原理

函数计算根据函数所在服务配置的角色,通过AssumeRole获取一个临时密钥(STS Token)。然后通过上下文中的参数Credentialscredentials将临时密钥传递给您的函数。此临时密钥包含了您所配置的权限的所有资源,您可以在函数代码中使用其访问其他阿里云服务。

临时密钥的有效期为36小时,且不支持修改。函数的最大执行时间为24小时,因此,执行函数过程中,临时密钥不会过期。

不同的运行时,参数Credentialscredentials的位置不同,您可以点击以下链接访问对应的文档。需要强调的是,当您使用Custom Runtime或Custom Container的时候,临时密钥会被注入HTTP请求的Header中。

函数计算默认服务角色

在函数运行的过程中,函数计算需要访问其他云资源,例如将函数日志写入到您指定的日志服务内、拉取ACR镜像或打通VPC网络访问等。为了简化您的授权操作,函数计算为您提供了一个系统默认的服务角色,即AliyunFCDefaultRole。该角色内包含了函数计算需要访问的部分云资源权限。关于如何创建默认角色AliyunFCDefaultRole和绑定该角色的操作步骤,请参见开通服务。您可以登录RAM角色管理控制台,查看AliyunFCDefaultRole的授权内容。

由于AliyunFCDefaultRole角色包含的权限是粗粒度的,如果需要更细粒度的权限,您可以为服务授予其他角色及相关权限策略。

例如,需要函数计算某服务内的所有函数都具有管理对象存储服务的权限,但AliyunFCDefaultRole角色内没有该权限。您需在配置服务权限时,为该服务绑定一个角色,然后将管理对象存储服务的权限策略绑定到该角色上。成功绑定后,该服务内的所有函数都将具有管理对象存储服务的权限。具体操作,请参见操作步骤
重要 AliyunFCDefaultRole函数计算系统默认的、所有服务级别的角色,请勿在该角色上添加其他权限策略。如果在默认角色的基础上,您还需要添加其他权限策略,请新增一个角色并为该角色添加相关权限。

前提条件

操作步骤

本文以授予函数计算访问对象存储OSS管理权限为例进行介绍。

  1. 登录函数计算控制台,在左侧导航栏,单击服务及函数
  2. 在顶部菜单栏,选择地域,然后在服务列表页面,单击目标服务操作列的配置
  3. 在编辑服务页面的角色配置区域,完成以下操作,然后单击保存
    • 使用新角色
      1. 单击创建新的服务角色,页面跳转至角色页面。
      2. 角色页面,创建可信实体为阿里云服务的RAM角色。具体操作,请参见创建可信实体为阿里云服务的RAM角色
        说明 本示例中目标授信服务选择函数计算
      3. 给新角色授予管理对象存储服务的权限策略。具体操作,请参见为RAM角色授权
    • 使用已有角色
      1. 服务角色下拉列表中选择需要授权的角色。
      2. 如果选择的角色不具有管理对象存储服务的权限,需要为角色授予相关权限策略。具体操作,请参见为RAM角色授权
  4. 在左侧导航栏,单击函数管理,然后在函数管理页面单击目标函数。
  5. 在函数详情页面,单击函数代码页签,在代码编辑器中编写代码,然后单击部署代码
    以Python标准运行时为例,您可以使用函数计算为您提供的临时密钥访问对象存储OSS。
    import json
    import oss2
    
    def handler(event, context):
        evt = json.loads(event)
        creds = context.credentials
        # 输入用户临时密钥,包括临时Token。
        # 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
        # 建议不要把AccessKey ID和AccessKey Secret保存到工程代码里,否则可能导致AccessKey泄露,威胁您账号下所有资源的安全。
        # 本示例以从上下文中获取AccessKey/AccessSecretKey为例。
        auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret, creds.security_token)
        bucket = oss2.Bucket(auth, evt['endpoint'], evt['bucket'])
        bucket.put_object(evt['objectName'], evt['message'])
        return 'success'