设置 Openflow¶
本主题介绍设置 Openflow 的步骤。
设置 Openflow 涉及以下步骤:
先决条件¶
在您的 Snowflake 和 AWS 账户上需要满足的先决条件如下:
Snowflake 账户¶
如果您从未在 Snowflake 账户中使用过镜像存储库,则需要进行以下设置,以确保部署服务可从 Snowflake 提取 Openflow 镜像。
USE ROLE ACCOUNTADMIN; CREATE DATABASE IF NOT EXISTS OPENFLOW; USE OPENFLOW; CREATE SCHEMA IF NOT EXISTS OPENFLOW; USE SCHEMA OPENFLOW; CREATE IMAGE REPOSITORY IF NOT EXISTS OPENFLOW; grant usage on database OPENFLOW to role public; grant usage on schema OPENFLOW to role public; grant read on image repository OPENFLOW.OPENFLOW.OPENFLOW to role public;
要设置 Openflow,需要在 Snowflake 账户级别定义新的权限。新权限作为默认权限集的一部分分配给 ACCOUNTADMIN 角色。ACCOUNTADMIN 将自动获得以下两个权限,并且能够向自己授予其选择的 Openflow 管理员角色角色,在以下代码中以 $OPENFLOW_ADMIN_ROLE 表示:
USE ROLE ACCOUNTADMIN; GRANT CREATE OPENFLOW DATA PLANE INTEGRATION ON ACCOUNT TO ROLE $OPENFLOW_ADMIN_ROLE; GRANT CREATE OPENFLOW RUNTIME INTEGRATION ON ACCOUNT TO ROLE $OPENFLOW_ADMIN_ROLE;
此外,您需要为所有 Openflow 用户将
default_secondary_roles
设置为ALL
。这是因为 Openflow 操作授权会使用任何经过身份验证的用户角色,而不仅仅是默认角色。为每个 Openflow 用户替换以下代码中的 $OPENFLOW_USER:USE ROLE ACCOUNTADMIN; ALTER USER $OPENFLOW_USER SET DEFAULT_SECONDARY_ROLES = ('ALL');
部署集成权限¶
部署集成对象表示为了部署一个或多个 Snowflake Openflow 运行时而预置的一组资源。对于自带云资源的组织,部署集成对象代表托管 Kubernetes 集群及其关联节点。
拥有 Snowflake 账户 CREATE DATA PLANE INTEGRATION 权限的用户可以创建和删除部署集成对象。
为支持区分访问权限,可以直接在部署集成对象上定义其他权限。
您可以授予对于部署集成对象的以下权限:
OWNERSHIP:允许完全控制部署操作对象,包括删除部署。
USAGE:允许创建运行时子对象。
运行时权限¶
运行时对象代表一个或多个 Snowflake Openflow 运行时服务器构成的集群,这些服务器为运行流程定义而预置。对于 Kubernetes 部署,运行时对象代表在命名空间中部署的一组有状态 Snowflake Openflow 运行时容器以及支持组件。
拥有父部署集成对象 OWNERSHIP 权限和 CREATE RUNTIME INTEGRATION 账户级别权限的用户可创建运行时集成对象。为支持区分访问权限,可以直接在运行时集成对象上定义其他权限。
您可以授予对于运行时集成对象的以下权限:
OWNERSHIP:允许完全控制运行时操作,包括删除相关运行时以及修改运行时流程定义。
USAGE:允许对已部署的运行时进行读取访问,以观察运行状况和状态,而不需要进行任何更改。
角色设置示例¶
考虑下面的场景,我们希望设置以下角色:
accountadmin:Snowflake 开箱提供的角色,它将拥有以下两项 CREATE 权限:
CREATE OPENFLOW DATA PLANE INTEGRATION
CREATE OPENFLOW RUNTIME INTEGRATION
deployment_manager:可以创建、管理和删除部署的角色
deployment1_runtime_manager_1:该角色只能在部署 1 中创建运行时。它可以修改和删除由其创建的部署 1 中的运行时,但不能修改和删除由 deployment1_runtime_manager_2 创建的运行时。
deployment1_runtime_manager_2:该角色只能在部署 1 中创建运行时。它可以修改和删除由其创建的部署 1 中的运行时,但不能修改和删除由 deployment1_runtime_manager_1 创建的运行时。
deployment1_runtime_viewer_1:该角色可以查看部署 1 中由 deployment1_runtime_manager_1 创建的运行时画布。
deployment1_runtime_viewer_2:该角色可以查看部署 1 中由 deployment1_runtime_manager_2 创建的运行时画布。
deployment2_runtime_manager:该角色只能在部署 2 中创建运行时。
deployment2_runtime_viewer:该角色可以查看部署 2 中的运行时画布。
要使用这些角色设置 Openflow,请执行以下操作:
创建新角色,并分配相关权限。
use role accountadmin; create role if not exists deployment_manager; create role if not exists deployment1_runtime_manager_1; create role if not exists deployment1_runtime_manager_2; create role if not exists deployment1_runtime_viewer_1; create role if not exists deployment1_runtime_viewer_2; create role if not exists deployment2_runtime_manager; create role if not exists deployment2_runtime_viewer; -- assign create deployment privilege to roles, since this privilege cannot be granted in openflow ui grant create openflow data plane integration on account to role deployment_manager; -- assign create runtime privilege to roles, since this privilege cannot be granted in cp ui grant create openflow runtime integration on account to role deployment1_runtime_manager_1; grant create openflow runtime integration on account to role deployment1_runtime_manager_2; grant create openflow runtime integration on account to role deployment2_runtime_manager; -- grant these roles to desired users grant role <role name> to user <username>; ........
创建部署。
以 deployment_manager 的身份登录。
在 Openflow UI 中创建部署 1。授予 deployment1_runtime_manager_1 和 deployment1_runtime_manager_2 USAGE 权限。
在 Openflow UI 中创建部署 2。授予 deployment2_runtime_manager USAGE 权限。
您需要 CREATE OPENFLOW RUNTIME INTEGRATION 权限和对于部署的 USAGE 权限,才能在该部署中创建运行时。
在部署 1 中以 deployment1_runtime_manager_1 的身份创建运行时。
以 deployment1_runtime_manager_1 的身份登录。
按照以下部分的说明创建运行时。deployment1_runtime_manager_1 应该能在此部署中创建运行时并管理由其创建的任何运行时。
在 Openflow UI 中,选择 deployment1_runtime_viewer_1 并授予其 USAGE 权限。
AWS 账户¶
确保您的 AWS 账户符合以下条件:
您有一个 AWS 账户,并且具备创建 CloudFormation 堆栈所需的权限。
您的组织中有一位 AWS 管理员,可以执行 CloudFormation 脚本,以在新的 VPC(由 CloudFormation 创建)或现有 VPC 中设置 EKS。请参阅 BYO-VPC(现有 VPC)的先决条件。
备注
要了解如何在您的 AWS 账户中安装 Openflow 以及由 CloudFormation 模板配置的权限,请参阅 安装流程。
BYO-VPC(现有 VPC)的先决条件¶
如果您想使用现有 VPC 和自己的专用子网,请确保具备以下条件:
一个 VPC
一个连接到 VPC 的互联网网关
位于不同可用区的两个公共子网:
公共子网的范围应至少为 /27 CIDR,拥有 32 个用于公共子网的的 IPs。
两个公共子网都应具有针对目的地 0.0.0.0/0 和目标互联网网关的路由。
公共子网必须位于不同的可用区,因为 AWS 网络负载均衡器要求具备高可用性。
要创建 AWS 负载均衡器,必须按如下方式标记公共子网:
键:kubernetes.io/role/elb
值:1
一个具有“Public”连接类型的 NAT 网关,连接到公共子网。
位于不同可用区的两个专用子网。
子网的范围应至少为 /24 CIDR,有 256 个 IPs 可供分配。这限制了您可以创建的运行时数量和规模,因此为部署使用更大的范围可能更合适。
每个专用子网都需要一个 0.0.0.0/0 到公共子网 NAT 网关的路由表条目。
这些子网必须位于不同的可用区中,这是 EKS 预置的先决条件。
请记住以下要点:
Openflow 部署代理在专用子网 1 中运行,该子网需要绑定到互联网网关。否则将无法正确初始化或设置,也不会预置任何基础设施。
如果没有可从专用子网路由的公共 NAT 网关,EKS 集群等资源将无法访问互联网。此外,部署代理将无法安装 Openflow 部署。
接受 Openflow 服务条款¶
贵组织仅需执行一次此步骤。
以具有 ORGADMIN 角色的用户身份登录 Snowflake。
导航到 Data » Openflow。
接受 Openflow 服务条款。
在您的云环境中创建部署¶
重要
如果用户的默认角色为 ACCOUNTADMIN、ORGADMIN、GLOBALORGADMIN 或 SECURITYADMIN,则无法登录 Openflow。要登录 Openflow,您必须将用户的默认角色更改为 ACCOUNTADMIN、ORGADMIN、GLOBALORGADMIN、SECURITYADMIN 以外的角色。有关更多信息,请参阅 先决条件。
使用您的 ACCOUNTADMIN 为使用 Openflow 而分配的角色登录 Snowflake。
导航到 Data » Openflow。
选择 Launch Openflow。
在 Openflow UI 中,选择 Create a deployment。这会打开 Deployments 选项卡。
选择 Create a deployment。这会打开“Creating a deployment”向导。
在 Prerequisites 步骤中,确保您满足所有要求。选择 Next。
在 Deployment location 步骤中,选择 Amazon Web Services 作为部署位置。输入部署的名称。选择 Next。
在 Configuration 步骤中,您可以选择以下配置选项之一:
Fully managed VPC:如果您希望由 Snowflake 管理您的 VPC,请选择此选项
Bring your own VPC:如果您想使用现有 VPC,请选择此选项。
选择 Create Deployment。
配置好部署后,将出现一个对话框,允许您下载 CloudFormation 模板,以在您的 AWS 账户中完成设置过程。下载此模板并导航到您的 AWS 账户。
在您的 AWS 账户中,使用模板创建新的 CloudFormation 堆栈。创建 Openflow 部署代理的 EC2 实例后,它会使用基础设施即代码脚本,完成 安装过程 的其余部分。您可以按照 跟踪安装进度 中所述跟踪安装进度。
如果您使用现有 VPC,请在上传 CloudFormation 模板后,在下拉列表中为两个专用子网和您的 VPC 选择相应的值。
导航到您的 Snowflake 账户。
[可选] 只有在使用网络策略来控制 Snowflake 访问权限时,您才需要执行此步骤。为 Openflow 创建网络规则,并将其添加到您的 Snowflake 账户的现有网络策略中。网络策略是一组规则,用于控制哪些 IP 地址可访问您的 Snowflake 账户。将以下代码片段中的 {$NAT_GATEWAY_PUBLIC_IP} 替换为作为 CloudFormation 堆栈一部分创建的 NAT 网关公共 IP 地址(在 AWS 控制台上搜索“NAT Gateway”,或者检查 CFN 堆栈的输出)。NAT 网关负责 DPA 和 EKS 的 Openflow 出口。DPA 和 EKS 都在安装的专用子网 1 中运行。
USE ROLE ACCOUNTADMIN; USE DATABASE {REPLACE_WITH_YOUR_DB_NAME}; CREATE NETWORK RULE allow_openflow_deployment MODE = INGRESS TYPE = IPV4 VALUE_LIST = ('{$NAT_GATEWAY_PUBLIC_IP}/32'); -- Run this command to find your currently active network policy and copy the value column SHOW PARAMETERS LIKE 'NETWORK_POLICY' IN ACCOUNT; -- Now add the new network rule to this policy ALTER NETWORK POLICY {ENTER_YOUR_ACTIVE_NETWORK_POLICY_NAME} ADD ALLOWED_NETWORK_RULE_LIST = (allow_openflow_deployment);
创建事件表。事件表旨在存储和管理事件数据,例如用户操作、系统日志和事务。您可以选择使用特定于 Openflow 的事件表,或是特定于账户的事件表。
创建特定于 Openflow 的事件表
USE ROLE accountadmin; GRANT create event table on schema OPENFLOW.OPENFLOW to role $ROLE_OF_DEPLOYMENT_OWNER; USE ROLE $ROLE_OF_DEPLOYMENT_OWNER; CREATE event table if not exists openflow.openflow.openflow_events; -- Find the Data Plane Integrations SHOW openflow data plane integrations; ALTER openflow data plane integration $OPENFLOW_deployment_UUID SET event_table = 'openflow.openflow.openflow_events';
创建特定于账户的事件表
USE database openflow; CREATE schema if not exists openflow.telemetry; CREATE event table if not exists openflow.telemetry.events; ALTER ACCOUNT SET EVENT_TABLE = openflow.telemetry.events;
导航到 Openflow UI。在 AWS 上,创建部署大约需要 45 分钟。创建后,您可以在 Openflow UI 的“Deployments”选项卡中查看您的部署,其状态标记为 Active。
在您的云环境中创建运行时环境¶
在 Openflow Control Plane 中,选择 Create a runtime。此时会出现 Create Runtime 对话框。
从 Deployment 下拉列表中,选择要在其中创建运行时的部署。
输入运行时名称。
从 Node type 下拉列表中选择一种节点类型。这指定了您的节点的大小。
在 Min/Max node 范围选择器中,选择一个范围。最小值指定在运行时启动时创建的节点数,最大值指定在数据量较大或 CPU 负载较高的情况下,运行时可以扩展到的节点数。
选择 Create。运行时需要几分钟时间才能创建完毕。
创建之后,您可以导航到 Openflow 控制平面的 Runtimes 选项卡来查看运行时。点击运行时打开 Openflow 画布。
后续步骤¶
在运行时中部署连接器。有关 Openflow 中可用的连接器列表,请参阅 Openflow 连接器。
网络注意事项:Openflow EKS 到源系统¶
Openflow CloudFormation 堆栈会创建:
一个 VPC,带有两个公共子网和两个专用子网
公共子网托管稍后创建的 AWS 网络负载均衡器,专用子网托管 EKS 集群和支持节点组的所有 EC2 实例。Openflow 运行时在专用子网 1 内运行。
NAT 网关目前是 DPA 和 EKS 的出口。DPA 和 EKS 都在安装的专用子网 1 中运行。
示例:使用新 VPC 进行 BYOC 部署,以便在相同账户的不同 VPC 中与 RDS 通信¶
要启用 Openflow EKS 集群与 RDS 实例之间的通信,您需要创建一个新的安全组,将该 EKS 集群安全组作为 RDS 连接入站规则的来源,并将该组连接到 RDS 中。
找到 EKS 集群安全组,导航到 EKS 并找到您的部署密钥。您也可以通过执行以下步骤在 Openflow UI 上找到它:
登录 Openflow。
转到 Deployments 选项卡。
选择您的部署旁边的“More options”图标。
选择 View details。字段 Key 中的值就是您的部署密钥。
找到部署密钥后,您可以使用它按密钥值筛选 AWS 资源。
创建一个新的安全组,允许通过相关的数据库端口(在 PostgreSQL 中默认为 5432)访问 Openflow EKS 集群。
在 RDS 中将其附加为新的安全组。
如果您需要排查故障,Reachability Analyzer (https://docs.aws.amazon.com/vpc/latest/reachability/getting-started.html) 可能会很有帮助。它将通过在 AWS 平台内使用跟踪功能,向您提供有关可能阻碍连接的因素的详细信息。
有关使用 VPC 对等互连和相关的安全组配置访问 DB 实例的信息,请参阅以下 AWS 文档:
在 VPC 中访问 DB 实例的场景 - Amazon Relational Database Service (https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.Scenarios.html#USER_VPC.Scenario3)
更新您的安全组以引用对等安全组 - Amazon Virtual Private Cloud (https://docs.aws.amazon.com/vpc/latest/peering/vpc-peering-security-groups.html)
安装过程¶
在 CloudFormation 堆栈和 Openflow 代理之间,BYOC 部署安装过程管理多个协调的步骤。目标是划分责任:冷启动(通过 CloudFormation 解决)用于为组织提供一种便捷的方法,从而为其 BYOC 部署提供输入;以及部署的配置及其核心软件组件,这需要随着时间推移而更改(通过 Openflow Agent 解决)。
部署代理有助于创建 Openflow 部署基础设施和安装部署软件组件(包括部署服务)。部署代理使用 Snowflake 系统镜像注册表进行身份验证,以获取 Openflow 容器镜像。
步骤如下:
备注
使用 BYO-VPC 时,您将从模板中选择一个 VPC ID 和两个专用子网 IDs,CloudFormation 堆栈将使用选定专用子网,而不是创建步骤 1a、1b 和 1c 中提到的资源。
CloudFormation 模板创建以下内容,并使用 已配置 AWS 权限 中提及的 AWS 权限进行配置:
一个 VPC,带有两个公共子网和两个专用子网。公共子网托管 AWS 网络负载均衡器(稍后创建)。专用子网托管 EKS 集群和所有支持 NodeGroups 的 EC2 实例。Openflow 运行时在专用子网内运行。
用于从 VPC 出口的互联网网关
专用子网出口的 NAT 网关
用户输入的 OIDC 配置的 AWS Secrets Manager 条目
供 Openflow 代理通过其 EC2 实例使用的 IAM 角色和实例配置文件
Openflow 部署代理的 EC2 实例,配有自动运行初始化过程的 UserData 脚本。此脚本根据输入 CloudFormation 参数设置环境变量,供 Openflow 部署代理使用。
Openflow 部署代理的 EC2 Instance Connect 端点,用于在需要时升级部署。
使用 BYO-VPC 时,默认情况下,CloudFormation 堆栈将创建 EC2 Instance Connect 端点。但是此默认行为可以修改。使用托管 VPC 选项时,CloudFormation 堆栈将始终创建 EC2 Instance Connect 端点。
Instance Connect 端点可在多个 VPCs 之间共享。
如果删除了部署,同时删除了 CloudFormation 堆栈,它还将移除端点。如果端点为共享,这将阻止对其他 BYO VPC 代理的访问。
要添加 EC2 Instance Connect 端点,请在您的 AWS 账户中执行以下步骤:
在左侧导航栏中,导航至 VPC » Endpoints。
选择 Create Endpoint。
选择“EC2 Instance Connect Endpoint”作为端点类型。
选择 VPC。清除所有安全组(即使其成为未选中状态),以使用默认 VPC 安全组。
选择子网时,使用与 CloudFormation 参数中的专用子网 1 相同的值。
选择 Create。创建端点大约需要 5 分钟时间。
存储 Openflow 代理的 Terraform 状态、日志和输出的 S3 存储桶
Openflow 部署代理会创建以下内容:
包含以下元素的 EKS 集群:
节点组
自动缩放组
VPC CNI 附加组件
EBS CSI 附加组件
PostgreSQL、OAuth 凭据等的密钥管理器记录。
各种 K8s 服务账户的 IAM 策略和角色,用于从 AWS Secrets Manager 检索其密钥。
K8s 组件
命名空间
集群自动扩缩器
EBS CSI 可扩展存储
AWS 负载均衡器控制器,用于创建可公开访问的网络负载均衡器
Let's Encrypt 证书颁发机构
Nginx Ingress,为 Let's Encrypt 进行了配置
Metrics Server
Jetstack (http://jetstack.io/) 提供的证书管理器
External Secrets Operator (http://external-secrets.io/)
用于临时、部署服务和 OIDC 的服务账户
用于临时服务、部署服务和 OIDC 的密钥存储
用于临时和部署服务的外部密钥。OIDC 的外部密钥由运行时操作器创建和管理。
PostgreSQL
临时
用于运行时节点之间通信的自签名证书颁发机构和入口配置
Openflow 运行时操作器
Openflow 部署服务
默认情况下,所有 AWS 账户在每个区域都有五个弹性 IP 地址的配额,因为公共 (IPv4) 互联网地址是一种稀缺的公共资源。Snowflake 强烈建议您使用弹性 IP 地址,主要是因为在实例出现故障时,它们能够将地址重新映射到另一个实例,并使用 DNS 主机名进行所有其他节点间通信。
追踪安装进度¶
在 CloudFormation 堆栈进入 CREATE_COMPLETE 状态后,Openflow 代理会自动创建基础设施的其余部分。
其中涉及到几个步骤,每个步骤都可能需要 10-15 分钟完成,例如:
创建 EKS 集群
将 EBS CSI 附加组件安装到 EKS 集群
创建 RDS PostgreSQL 数据库
Openflow 代理的状态报告尚不可用。在此期间,您可以查看 Openflow 代理上的日志,以验证 BYOC 部署是否已做好运行准备。为此,请执行以下步骤:
在 EC2 实例列表中,找到以下两个实例:
openflow-agent-{data-plane-key}:这是您将用来管理运行时的 Openflow 代理
{data-plane-key}-mgmt-group:这是 BYOC 部署的 EKS 集群中的一个节点,用于运行操作器和其他核心软件
右键点击 openflow-agent-{data-plane-key} 实例,并选择 Connect。
从 EC2 Instance Connect 切换到 Connect using EC2 Instance Connect Endpoint。保留默认的 EC2 实例连接端点。
点击 Connect。此时将出现一个带有命令行界面的新浏览器选项卡或者窗口。
运行以下命令,查看正在配置您的部署的 docker 镜像的安装日志:
journalctl -xe -f -n 100 -u docker
安装完成后,您将看到以下输出:
{timestamp} - app stack applied successfully {timestamp} - All resources applied successfully
已配置的 AWS 权限¶
此部分列出了 Openflow BYOC 堆栈根据角色配置的 AWS 权限。
备注
{key} 代表部署密钥,用于唯一标识 Openflow 为特定部署创建和管理的云资源。
管理用户
cloudformation
以及如下所有权限。
IAM 角色:openflow-agent-role-{key}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"autoscaling:DescribeTags",
"ec2:DescribeImages",
"ec2:DescribeInstances",
"ec2:DescribeLaunchTemplates",
"ec2:DescribeLaunchTemplateVersions",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeTags",
"ec2:DescribeVolumes",
"ec2:DescribeVpcs",
"ec2:DescribeVpcAttribute",
"iam:GetRole",
"iam:GetOpenIDConnectProvider",
"ecr:GetAuthorizationToken",
"ec2:RunInstances",
"ec2:CreateLaunchTemplate",
"ec2:CreateSecurityGroup",
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Condition": {
"StringLike": {
"aws:ResourceTag/Name": [
"{key}-oidc-provider"
]
}
},
"Action": [
"iam:CreateOpenIDConnectProvider",
"iam:DeleteOpenIDConnectProvider",
"iam:TagOpenIDConnectProvider"
],
"Resource": "arn:aws:iam::{Account_ID}:oidc-provider/oidc.eks.{Region}.amazonaws.com/id/*",
"Effect": "Allow"
},
{
"Action": [
"iam:DeletePolicy",
"iam:CreatePolicy",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"iam:ListPolicyVersions"
],
"Resource": [
"arn:aws:iam::{Account_ID}:policy/dp-service-role-policy-{key}",
"arn:aws:iam::{Account_ID}:policy/oauth2-role-policy-{key}",
"arn:aws:iam::{Account_ID}:policy/temporal-service-role-policy-{key}",
"arn:aws:iam::{Account_ID}:policy/oidc-service-role-policy-{key}",
"arn:aws:iam::{Account_ID}:policy/dps-temporal-role-policy-{key}"
"arn:aws:iam::{Account_ID}:policy/dps-postgres-role-policy-{key}"
],
"Effect": "Allow"
},
{
"Action": [
"iam:UpdateAssumeRolePolicy",
"iam:PutRolePolicy",
"iam:ListInstanceProfilesForRole",
"iam:ListAttachedRolePolicies",
"iam:ListRolePolicies",
"iam:GetRolePolicy",
"iam:CreateRole",
"iam:AttachRolePolicy",
"iam:DeleteRole",
"iam:DeleteRolePolicy",
"iam:DetachRolePolicy",
"iam:TagRole"
],
"Resource": [
"arn:aws:iam::{Account_ID}:role/openflow-agent-role-{key}",
"arn:aws:iam::{Account_ID}:role/{key}-*",
"arn:aws:iam::{Account_ID}:role/dps-temporal-role-{key}",
"arn:aws:iam::{Account_ID}:role/dps-postgres-role-{key}",
"arn:aws:iam::{Account_ID}:role/dp-service-role-{key}",
"arn:aws:iam::{Account_ID}:role/oauth2-role-{key}",
"arn:aws:iam::{Account_ID}:role/oidc-service-role-{key}"
],
"Effect": "Allow"
},
{
"Action": [
"autoscaling:CreateOrUpdateTags",
"autoscaling:DeleteTags"
],
"Resource": "arn:aws:autoscaling:{Region}:{Account_ID}:autoScalingGroup:*:autoScalingGroupName/eks-{key}-*",
"Effect": "Allow"
},
{
"Condition": {
"StringLike": {
"aws:ResourceTag/Name": [
"{key}-EC2SecurityGroup-*",
"k8s-traffic-{key}-*",
"eks-cluster-sg-{key}-*",
"{key}-cluster-sg",
"postgres-{key}-sg"
]
}
},
"Action": [
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:DeleteSecurityGroup",
"ec2:CreateTags",
"ec2:DeleteTags",
"ec2:CreateNetworkInterface",
"ec2:DeleteNetworkInterface"
],
"Resource": "arn:aws:ec2:{Region}:{Account_ID}:security-group/*",
"Effect": "Allow"
},
{
"Condition": {
"StringLike": {
"aws:ResourceTag/elbv2.k8s.aws/cluster": "{key}"
}
},
"Action": [
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:DeleteSecurityGroup",
"ec2:CreateTags",
"ec2:DeleteTags",
"ec2:CreateNetworkInterface",
"ec2:DeleteNetworkInterface"
],
"Resource": "arn:aws:ec2:{Region}:{Account_ID}:security-group/*",
"Effect": "Allow"
},
{
"Action": [
"ec2:CreateSecurityGroup"
],
"Resource": "arn:aws:ec2:{Region}:{Account_ID}:vpc/vpc-018d2da0fde903de4",
"Effect": "Allow"
},
{
"Condition": {
"StringLike": {
"ec2:ResourceTag/Name": "openflow-agent-{key}"
}
},
"Action": [
"ec2:AttachNetworkInterface"
],
"Resource": "arn:aws:ec2:{Region}:{Account_ID}:instance/*",
"Effect": "Allow"
},
{
"Condition": {
"StringLike": {
"aws:ResourceTag/Name": "{key}-*-group"
}
},
"Action": [
"ec2:DeleteLaunchTemplate"
],
"Resource": "arn:aws:ec2:{Region}:{Account_ID}:launch-template/*",
"Effect": "Allow"
},
{
"Action": [
"eks:CreateCluster",
"eks:CreateAccessEntry",
"eks:CreateAddon",
"eks:CreateNodegroup",
"eks:DeleteCluster",
"eks:DescribeCluster",
"eks:ListClusters",
"eks:ListNodeGroups",
"eks:DescribeUpdate",
"eks:UpdateClusterConfig",
"eks:TagResource"
],
"Resource": "arn:aws:eks:{Region}:{Account_ID}:cluster/{key}",
"Effect": "Allow"
},
{
"Action": [
"eks:DescribeAddon",
"eks:DescribeAddonVersions",
"eks:UpdateAddon",
"eks:DeleteAddon",
"eks:DescribeUpdate"
],
"Resource": "arn:aws:eks:{Region}:{Account_ID}:addon/{key}/*",
"Effect": "Allow"
},
{
"Action": [
"eks:DeleteNodegroup",
"eks:DescribeNodegroup",
"eks:ListNodegroups",
"eks:UpdateNodegroupConfig",
"eks:TagResource",
"eks:DescribeUpdate"
],
"Resource": "arn:aws:eks:{Region}:{Account_ID}:nodegroup/{key}/*",
"Effect": "Allow"
},
{
"Action": [
"s3:CreateBucket",
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::byoc-tf-state-{key}",
"Effect": "Allow"
},
{
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::byoc-tf-state-{key}/*",
"Effect": "Allow"
},
{
"Action": [
"secretsmanager:CreateSecret",
"secretsmanager:DeleteSecret",
"secretsmanager:DescribeSecret",
"secretsmanager:GetResourcePolicy",
"secretsmanager:GetSecretValue",
"secretsmanager:PutSecretValue",
"secretsmanager:UpdateSecretVersionStage"
],
"Resource": "arn:aws:secretsmanager:{Region}:{Account_ID}:secret:*-{key}*",
"Effect": "Allow"
},
{
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:DescribeImages",
"ecr:DescribeRepositories",
"ecr:GetDownloadUrlForLayer",
"ecr:ListImages"
],
"Resource": "arn:aws:ecr:{Region}:{Account_ID}:*",
"Effect": "Allow"
},
{
"Action": [
"ecr:CreateRepository",
"ecr:CompleteLayerUpload",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart"
],
"Resource": "arn:aws:ecr:{Region}:{Account_ID}:repository/snowflake-openflow/*",
"Effect": "Allow"
},
{
"Condition": {
"StringLike": {
"iam:AWSServiceName": "eks.amazonaws.com"
}
},
"Action": [
"iam:CreateServiceLinkedRole"
],
"Resource": "arn:aws:iam::*:role/aws-service-role/eks.amazonaws.com/AWSServiceRoleForAmazonEKS",
"Effect": "Allow"
},
{
"Condition": {
"StringLike": {
"iam:AWSServiceName": "eks-nodegroup.amazonaws.com"
}
},
"Action": [
"iam:CreateServiceLinkedRole"
],
"Resource": "arn:aws:iam::*:role/aws-service-role/eks-nodegroup.amazonaws.com/AWSServiceRoleForAmazonEKSNodegroup",
"Effect": "Allow"
},
{
"Action": [
"eks:AssociateAccessPolicy",
"eks:ListAssociatedAccessPolicies",
"eks:DisassociateAccessPolicy"
],
"Resource": "arn:aws:eks:{Region}:{Account_ID}:access-entry/{key}/*",
"Effect": "Allow"
},
{
"Action": "iam:PassRole",
"Resource": "*",
"Effect": "Allow"
}
]
}
IAM 角色:{key}-cluster-ServiceRole
AWS 托管策略:
AmazonEKSClusterPolicy
AmazonEKSVPCResourceController
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"cloudwatch:PutMetricData"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:DescribeAccountAttributes",
"ec2:DescribeAddresses",
"ec2:DescribeInternetGateways"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
IAM 角色:{key}-addon-vpc-cni-Role
AWS 托管策略:
AmazonEKS_CNI_Policy
IAM 角色:{key}-eks-role
AWS 托管策略:
AmazonEBSCSIDriverPolicy
AmazonEC2ContainerRegistryReadOnly
AmazonEKS_CNI_Policy
AmazonEKSWorkerNodePolicy
AmazonSSMManagedInstanceCore
AutoScalingFullAccess
ElasticLoadBalancingFullAccess
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:CreateSecurityGroup",
"ec2:CreateTags"
],
"Effect": "Allow",
"Resource": [
"arn:aws:ec2:{Region}:{Account_ID}:security-group/*",
"arn:aws:ec2:{Region}:{Account_ID}:vpc/{VPC_ID}"
],
"Sid": "CreateOpenflowEKSSecurityGroupAndTags"
},
{
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:DeleteSecurityGroup"
],
"Condition": {
"StringLike": {
"aws:ResourceTag/Name": "eks-cluster-sg-{key}-*"
}
},
"Effect": "Allow",
"Resource": [
"arn:aws:ec2:{Region}:{Account_ID}:security-group/*"
],
"Sid": "OpenflowManageEKSSecurityGroup"
}
]
}
备注
{VPC_ID} 表示由 BYOC 创建或由 BYO-VPC 使用的 VPC 的标识符。
IAM 角色:oidc-service-role-{key}
{
"Statement": [
{
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret",
"secretsmanager:GetResourcePolicy",
"secretsmanager:ListSecretVersionIds"
],
"Effect": "Allow",
"Resource": [
"arn:aws:secretsmanager:{Region}:{Account_ID}:secret:oidc-{key}*"
]
}
],
"Version": "2012-10-17"
}
IAM 角色:dps-postgres-role-{key}
{
"Statement": [
{
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret",
"secretsmanager:GetResourcePolicy",
"secretsmanager:ListSecretVersionIds"
],
"Effect": "Allow",
"Resource": [
"arn:aws:secretsmanager:{Region}:{Account_ID}:secret:postgres_creds-{key}*"
]
}
],
"Version": "2012-10-17"
}
IAM 角色:dps-temporal-role-{key}
{
"Statement": [
{
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret",
"secretsmanager:GetResourcePolicy",
"secretsmanager:ListSecretVersionIds"
],
"Effect": "Allow",
"Resource": [
"arn:aws:secretsmanager:{Region}:{Account_ID}:secret:temporal_creds-{key}*"
]
}
],
"Version": "2012-10-17"
}
IAM 角色:dp-service-role-{key}
{
"Statement": [
{
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret",
"secretsmanager:GetResourcePolicy",
"secretsmanager:ListSecretVersionIds"
],
"Effect": "Allow",
"Resource": [
"arn:aws:secretsmanager:{Region}:{Account_ID}:secret:dps_creds-{key}*",
"arn:aws:secretsmanager:{Region}:{Account_ID}:secret:snowflake-oauth2-{key}*"
]
}
],
"Version": "2012-10-17"
}
IAM 角色:oauth2-role-{key}
{
"Statement": [
{
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret",
"secretsmanager:GetResourcePolicy",
"secretsmanager:ListSecretVersionIds"
],
"Effect": "Allow",
"Resource": [
"arn:aws:secretsmanager:{Region}:{Account_ID}:secret:snowflake-oauth2-{key}*"
]
}
],
"Version": "2012-10-17"
}
IAM 角色:{key}-nodegroup-NodeInstanceRole
AWS 托管策略:
AmazonEBSCSIDriverPolicy
AmazonEC2ContainerRegistryReadOnly
AmazonEKS_CNI_Policy
AmazonEKSWorkerNodePolicy
AmazonSSMManagedInstanceCore
AutoScalingFullAccess
ElasticLoadBalancingFullAccess
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"servicediscovery:CreateService",
"servicediscovery:DeleteService",
"servicediscovery:GetService",
"servicediscovery:GetInstance",
"servicediscovery:RegisterInstance",
"servicediscovery:DeregisterInstance",
"servicediscovery:ListInstances",
"servicediscovery:ListNamespaces",
"servicediscovery:ListServices",
"servicediscovery:GetInstancesHealthStatus",
"servicediscovery:UpdateInstanceCustomHealthStatus",
"servicediscovery:GetOperation",
"route53:GetHealthCheck",
"route53:CreateHealthCheck",
"route53:UpdateHealthCheck",
"route53:ChangeResourceRecordSets",
"route53:DeleteHealthCheck",
"appmesh:*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeScalingActivities",
"autoscaling:DescribeTags",
"ec2:DescribeInstanceTypes",
"ec2:DescribeLaunchTemplateVersions"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup",
"ec2:DescribeImages",
"ec2:GetInstanceTypesFromInstanceRequirements",
"eks:DescribeNodegroup"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"iam:CreateServiceLinkedRole"
],
"Condition": {
"StringEquals": {
"iam:AWSServiceName": "elasticloadbalancing.amazonaws.com"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:DescribeAccountAttributes",
"ec2:DescribeAddresses",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeInternetGateways",
"ec2:DescribeVpcs",
"ec2:DescribeVpcPeeringConnections",
"ec2:DescribeSubnets",
"ec2:DescribeSecurityGroups",
"ec2:DescribeInstances",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeTags",
"ec2:GetCoipPoolUsage",
"ec2:DescribeCoipPools",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeLoadBalancerAttributes",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:DescribeListenerCertificates",
"elasticloadbalancing:DescribeSSLPolicies",
"elasticloadbalancing:DescribeRules",
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeTargetGroupAttributes",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:DescribeTags"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"cognito-idp:DescribeUserPoolClient",
"acm:ListCertificates",
"acm:DescribeCertificate",
"iam:ListServerCertificates",
"iam:GetServerCertificate",
"waf-regional:GetWebACL",
"waf-regional:GetWebACLForResource",
"waf-regional:AssociateWebACL",
"waf-regional:DisassociateWebACL",
"wafv2:GetWebACL",
"wafv2:GetWebACLForResource",
"wafv2:AssociateWebACL",
"wafv2:DisassociateWebACL",
"shield:GetSubscriptionState",
"shield:DescribeProtection",
"shield:CreateProtection",
"shield:DeleteProtection"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:CreateSecurityGroup"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:CreateTags"
],
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "false"
},
"StringEquals": {
"ec2:CreateAction": "CreateSecurityGroup"
}
},
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:security-group/*"
},
{
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "true",
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
},
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:security-group/*"
},
{
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress",
"ec2:DeleteSecurityGroup"
],
"Condition": {
"Null": {
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"elasticloadbalancing:CreateLoadBalancer",
"elasticloadbalancing:CreateTargetGroup"
],
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "false"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"elasticloadbalancing:CreateListener",
"elasticloadbalancing:DeleteListener",
"elasticloadbalancing:CreateRule",
"elasticloadbalancing:DeleteRule"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"elasticloadbalancing:AddTags",
"elasticloadbalancing:RemoveTags"
],
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "true",
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
},
"Effect": "Allow",
"Resource": [
"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",
"arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",
"arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"
]
},
{
"Action": [
"elasticloadbalancing:AddTags",
"elasticloadbalancing:RemoveTags"
],
"Effect": "Allow",
"Resource": [
"arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*",
"arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*",
"arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*",
"arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*"
]
},
{
"Action": [
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"elasticloadbalancing:SetIpAddressType",
"elasticloadbalancing:SetSecurityGroups",
"elasticloadbalancing:SetSubnets",
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:ModifyTargetGroupAttributes",
"elasticloadbalancing:DeleteTargetGroup"
],
"Condition": {
"Null": {
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"elasticloadbalancing:AddTags"
],
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "false"
},
"StringEquals": {
"elasticloadbalancing:CreateAction": [
"CreateTargetGroup",
"CreateLoadBalancer"
]
}
},
"Effect": "Allow",
"Resource": [
"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",
"arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",
"arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"
]
},
{
"Action": [
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:DeregisterTargets"
],
"Effect": "Allow",
"Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*"
},
{
"Action": [
"elasticloadbalancing:SetWebAcl",
"elasticloadbalancing:ModifyListener",
"elasticloadbalancing:AddListenerCertificates",
"elasticloadbalancing:RemoveListenerCertificates",
"elasticloadbalancing:ModifyRule"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"route53:ChangeResourceRecordSets"
],
"Effect": "Allow",
"Resource": "arn:aws:route53:::hostedzone/*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"route53:GetChange"
],
"Effect": "Allow",
"Resource": "arn:aws:route53:::change/*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"route53:ListResourceRecordSets",
"route53:ListHostedZonesByName"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:CreateSnapshot",
"ec2:AttachVolume",
"ec2:DetachVolume",
"ec2:ModifyVolume",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeInstances",
"ec2:DescribeSnapshots",
"ec2:DescribeTags",
"ec2:DescribeVolumes",
"ec2:DescribeVolumesModifications"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:CreateTags"
],
"Condition": {
"StringEquals": {
"ec2:CreateAction": [
"CreateVolume",
"CreateSnapshot"
]
}
},
"Effect": "Allow",
"Resource": [
"arn:aws:ec2:*:*:volume/*",
"arn:aws:ec2:*:*:snapshot/*"
]
},
{
"Action": [
"ec2:DeleteTags"
],
"Effect": "Allow",
"Resource": [
"arn:aws:ec2:*:*:volume/*",
"arn:aws:ec2:*:*:snapshot/*"
]
},
{
"Action": [
"ec2:CreateVolume"
],
"Condition": {
"StringLike": {
"aws:RequestTag/ebs.csi.aws.com/cluster": "true"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:CreateVolume"
],
"Condition": {
"StringLike": {
"aws:RequestTag/CSIVolumeName": "*"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:DeleteVolume"
],
"Condition": {
"StringLike": {
"ec2:ResourceTag/ebs.csi.aws.com/cluster": "true"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:DeleteVolume"
],
"Condition": {
"StringLike": {
"ec2:ResourceTag/CSIVolumeName": "*"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:DeleteVolume"
],
"Condition": {
"StringLike": {
"ec2:ResourceTag/kubernetes.io/created-for/pvc/name": "*"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:DeleteSnapshot"
],
"Condition": {
"StringLike": {
"ec2:ResourceTag/CSIVolumeSnapshotName": "*"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:DeleteSnapshot"
],
"Condition": {
"StringLike": {
"ec2:ResourceTag/ebs.csi.aws.com/cluster": "true"
}
},
"Effect": "Allow",
"Resource": "*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"route53:ChangeResourceRecordSets"
],
"Effect": "Allow",
"Resource": "arn:aws:route53:::hostedzone/*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"route53:ListHostedZones",
"route53:ListResourceRecordSets",
"route53:ListTagsForResource"
],
"Effect": "Allow",
"Resource": "*"
}
]
}