当前位置: 首页 > article >正文

IAM角色访问AWS RDS For MySQL

IAM角色访问AWS RDS For MySQL

Tips: 写这篇文章,主要是用作记录;在AWS配置IAM RDS 角色权限访问,官方文档不怎么全,踩了一些坑…

AWS云上配置
  • 开启IAM身份验证

    • 登录AWS控制台
    • 搜索并进入Databases管理页面
    • 选择数据库实例,点击修改按钮
    • 在Database authentication部分,选择Password and IAM database authentication,启用IAM数据库身份验证
      在这里插入图片描述
  • 创建IAM Policy

    • 搜索策略,创建策略,选择JSON配置; Resource指向的是 db实例/数据库账号
    • 示例策略:
      {"Version": "2012-10-17","Statement": [{"Sid": "Statement1","Effect": "Allow","Action": ["rds-db:connect"],"Resource": ["arn:aws-cn:rds-db:cn-northwest-1:xxxxxxxx:dbuser:cluster-xxxxxxxx/dbuser"]}]
      }
      
      在这里插入图片描述
  • 创建IAM角色并附加策略

    • 创建一个角色,选择RDS,并附加上述策略
      在这里插入图片描述

    • 编辑新创建的权限,信任关系,指向session;即AWS那个字段,取值为个人账号arn

    • 示例信任关系:

      {"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"AWS": "arn:aws-cn:iam::xxxxx:user/个人acount","Service": ["rds.amazonaws.com"]},"Action": "sts:AssumeRole"}]
      }
      
AWS Config 配置
  • 新增role配置
    • 登录到宿主机,进入.aws目录
    • 查看configcredentials文件
    • credentials中配置IAM用户的accessIdaccessSecret; config与 credentials 通过 profile {name} 匹配
    • config中新增相关配置:
      [profile prodaccess]role_arn = arn:aws:iam::xxxxxxxx:role/ProductionAccessRolesource_profile = default
      
    • 如果 default的credentials配置无role权限,请切换profile或者授权
Role授权
  • AWS上role信任实体配置
    • 跳板机执行命令:
      aws sts assume-role --role-arn "arn:aws-cn:iam::xxxxx:role/rolename" --role-session-name 主账号 --profile profile
      
      TIPS: 这里的rolename即是需要配置的role
使用IAM身份验证创建数据库账户
  • 创建数据库用户
    • 需要与策略中的用户保持一致,用户名为dbuser,可以换成自己的
    • 命令:
      CREATE USER 'dbuser' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
      
    • 如果要开启SSL:
      ALTER USER 'dbuser'@'%' REQUIRE SSL;
      
命令行连通性验证
  • 写入变量
    • 设置RDS主机名:
      export RDSHOST="rds-aurora-xxx.cluster-xxxx.rds.cn-northwest-1.amazonaws.com.cn"
      
    • 获取token:
      aws rds generate-db-auth-token --hostname $RDSHOST --port 3306 --region cn-northwest-1 --username dbuser --profile xxxx_profile
      
      xxxx_profile是自定义的profile名称,不加–profile 参数默认使用default
    • 将获取到的token写入变量:
      export TOKEN="...token..."
      
    • 引用变量进行连接:
      mysql --host=$RDSHOST --port=3306 --enable-cleartext-plugin --user=dbuser --password=$TOKEN
      
SpringBoot应用接入Datasource
  • 新增配置
    • application.properties中添加:
      aws.rds.host=rds-aurora-xxxxx.cluster-xxxxx.rds.cn-northwest-1.amazonaws.com.cn
      aws.rds.port=3306
      aws.rds.user=dbuser
      aws.rds.dbname=dbuser
      aws.region=cn-northwest-1
      
    • 添加AWS SDK依赖:
      <dependency><groupId>software.amazon.awssdk</groupId><artifactId>rds</artifactId><version>2.20.0</version>
      </dependency>
      
    • 剔除SpringBoot数据源配置文件注入,重新注入DataSource
package com.xxl.job.admin.core.conf;import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.rds.RdsUtilities;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;@Slf4j
@Configuration
public class DynamicDataSourceConfig {@Value("${aws.rds.host}") private String dbHost;@Value("${aws.rds.port}") private int dbPort;@Value("${aws.rds.user}") private String dbUser;@Value("${aws.rds.dbname}") private String dbName;@Value("${aws.region}") private String region;@Bean@Primarypublic DataSource dataSource() {log.info("[DynamicDataSourceConfig] create datasource start");String token = refreshIamToken();log.info("[DynamicDataSourceConfig] get token: {}", token);HikariDataSource dataSource = new HikariDataSource();dataSource.setJdbcUrl(buildJdbcUrl());dataSource.setUsername(dbUser);dataSource.setPassword(token);//TODO 验证可用性,可删除validateDataSource(dataSource);// 每10分钟刷新令牌// 临时凭证,默认有效期为15分钟ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);scheduler.scheduleAtFixedRate(() -> dataSource.setPassword(refreshIamToken()), 10, 10, TimeUnit.MINUTES);return dataSource;}private void validateDataSource(HikariDataSource dataSource) {try (Connection conn = dataSource.getConnection();Statement stmt = conn.createStatement()) {ResultSet rs = stmt.executeQuery("SELECT 1");log.info("Database connection test succeeded");} catch (SQLException e) {log.error("Database connection test FAILED", e);throw new RuntimeException("Datasource validation failed", e);}}private String refreshIamToken() {return generateAuthToken(dbHost, dbPort, dbUser, Region.of(region));}private String buildJdbcUrl() {return String.format("jdbc:mysql://%s:%d/%s?" +"allowCleartextPasswords=true&useUnicode=true&characterEncoding=UTF-8"+ "&autoReconnect=true&serverTimezone=Asia/Shanghai"+ "&useSSL=false&requireSSL=false",dbHost, dbPort, dbName);}private String generateAuthToken(String dbHost, int dbPort, String dbUser, Region region) {//profile需做成环境变量//dev_mysql_auth_profile, 这里换成对应的profile名称,若没有自定义配置则设置为defaultAwsCredentialsProvider credentialsProvider =ProfileCredentialsProvider.create("dev_mysql_auth_profile");return RdsUtilities.builder().credentialsProvider(credentialsProvider).region(region).build().generateAuthenticationToken(b -> b.hostname(dbHost).port(dbPort).username(dbUser).region(region));}
}
  • 使用默认凭证链,自动获取Pod角色权限:AwsCredentialsProvider
K8s secret 挂载映射
  • 代码中使用:AwsCredentialsProvider
  • 使用默认凭证链,自动获取Pod角色权限:AwsCredentialsProvider
官方文档
  • 参考AWS官方文档以获取更多详细信息。
  • 通用文档:https://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.Connecting.Java.html
  • 切换角色:https://docs.amazonaws.cn/IAM/latest/UserGuide/id_roles_use_switch-role-cli.html
  • 信任授权:https://repost.aws/zh-Hans/knowledge-center/iam-assume-role-error
http://www.lryc.cn/news/2386937.html

相关文章:

  • android property 系统
  • Karakeep | 支持Docker/NAS 私有化部署!稍后阅读工具告别云端依赖,让知识收藏更有序
  • RV1126+FFMPEG多路码流监控项目大体讲解
  • el-dialog 组件 多层嵌套 被遮罩问题
  • 探秘谷歌Gemini:开启人工智能新纪元
  • TCP建立连接为什么不是两次握手,而是三次,为什么不能在第二次握手时就建立连接?
  • 《Stable Diffusion 3.0企业级落地指南》——技术赋能与商业价值的深度融合实践
  • 【软考向】Chapter 3 数据结构
  • [原创](计算机数学)(The Probability Lifesaver)(P14): 推导计算 In(1-u) 约等于 -u
  • wordcount在集群上的测试
  • OpenCV CUDA模块图像过滤------创建一个 Sobel 滤波器函数createSobelFilter()
  • [面试精选] 0053. 最大子数组和
  • 怎么判断一个Android APP使用了Cordova这个跨端框架
  • PDF 转 JPG 图片小工具:CodeBuddy 助力解决转换痛点
  • VisionPro 与 C# 联合编程:相机连接实战指南
  • 鸿蒙OSUniApp 实现动态的 tab 切换效果#三方框架 #Uniapp
  • Docker系列(三):深度剖析Dockerfile与图形化容器实战 --- 3种容器构建方法对比与性能调优
  • 论文阅读:Next-Generation Database Interfaces:A Survey of LLM-based Text-to-SQL
  • OS面试篇
  • FFMPEG-FLV-MUX编码
  • 青少年编程与数学 02-020 C#程序设计基础 05课题、数据类型
  • React vs Vue.js:选哪个框架更适合你的项目?
  • Kafka|基础入门
  • ADS学习笔记(五) 谐波平衡仿真
  • MySQL存储引擎对比及选择指南
  • 【IDEA问题】springboot本地启动应用报错:程序包不存在;找不到符号
  • PETR- Position Embedding Transformation for Multi-View 3D Object Detection
  • Prompt Tuning与自然语言微调对比解析
  • 二十七、面向对象底层逻辑-SpringMVC九大组件之HandlerAdapter接口设计
  • QT软件开发环境及简单图形的绘制-图形学(实验一)-[成信]