AWS-CDK的实践和应用

46 篇文章 0 订阅
4 篇文章 0 订阅

ㅤㅤㅤ
ㅤㅤㅤ
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ(我们关心的,不是你是否失败了,而是你对失败能否无怨。——林肯)
ㅤㅤㅤ
ㅤㅤㅤ
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ在这里插入图片描述

以dynamodb备份还原资源为例进行演示
什么是aws-cdk

aws-cdk由aws提供,用代码编写的方式构建可靠,可扩展,高效的应用程序,它的优点有

  • 用自定义代码的方式运行aws资源
  • 使用参数,条件,组合等编程习惯构建aws资源
  • 使用代码审查,单元测试的方式,让aws资源部署和运行更加稳健
  • 使用更简单的api对接方式来完成aws资源的操作
  • 技术团队间更容易了解和分享公司的aws架构
CDKToolkit

可以将 AWS CDK 应用程序部署到 AWS 之前为 AWS CDK 预置资源的过程。(AWS 环境是 AWS 账户和区域的组合)。
这些资源包括用于存储文件的 Amazon S3 存储桶和授予执行部署所需权限的 IAM 角色等资源

aws-cdk入门相关链接

https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_backup.CfnBackupPlan.BackupPlanResourceTypeProperty.html
cdk.json配置
https://docs.aws.amazon.com/cdk/v2/guide/cli.html

演示的功能列表

备份计划

  • backupPlanCore
    • 用途:生成核心备份计划
    • 频率:每小时连续备份一次,保留七天,热存储区,备份库用default,核心备份
  • backupPlanStandard
    • 用途:生成标准备份计划
    • 频率:每天凌晨,中午备份一次,保留十五天,热存储区,备份库用default,普通备份
  • backupPlanOffSite
    • 用途:生成多地区备份保存计划
    • 频率:每天凌晨全表全备,中国-宁夏和中国-北京,热存储区,分别保留三十天,备份库用default,双地备份

初始化

  1. 本地安装cdk

    npm install -g aws-cdk
    
  2. 初始化ts新项目

    cdk init app --language typescript
    
  3. 查看应用列表

    cdk ls
    
  4. 初始化堆栈资源,前提是本地已经配置了aws证书

    安装aws-cli:https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html

    配置aws证书:https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html

    yarn run cdk-bootstrap-dev --aws-profile dev STAGE=dev
    
  5. 发布应用程序

    yarn run cdk-deploy-dev --profile dev STAGE=dev
    
  6. 销毁应用程序

    yarn run cdk-destory-dev --profile dev STAGE=dev
    

目录结构

  • bin:cdk应用程序的入口,用于加载lib下的文件
  • lib:定义cdk应用程序的堆栈
  • cdk.out:cdk应用程序的堆栈信息和元数据
  • cdk.json:cdk应用程序运行的配置文件

使用

  • backupPlanCore

    // 初始化app
    const app = new cdk.App();
    // 描述
    const description = 'aws-cdk堆栈 目前用于执行数据库备份操作';
    // 堆栈信息
    const cdkStack = new CdkStack(app, 'CdkStack', { description });
    // 表名列表
    const coreTableNameList = ['tenant-table-local'];
    cdkStack.backupPlanCore(coreTableNameList);
    
  • backupPlanStandard

    // 初始化app
    const app = new cdk.App();
    // 描述
    const description = 'aws-cdk堆栈 目前用于执行数据库备份操作';
    // 堆栈信息
    const cdkStack = new CdkStack(app, 'CdkStack', { description });
    // 表名列表
    const standardTableNameList = ['tenant-table-local'];
    cdkStack.backupPlanStandard(standardTableNameList);
    
  • backupPlanOffSite

    // 初始化app
    const app = new cdk.App();
    // 描述
    const description = 'aws-cdk堆栈 目前用于执行数据库备份操作';
    // 堆栈信息
    const cdkStack = new CdkStack(app, 'CdkStack', { description });
    // 表名列表
    const offsiteTableNameList = ['tenant-table-local'];
    cdkStack.backupPlanOffSite(offsiteTableNameList);
    

备份的核心代码

import * as cdk from 'aws-cdk-lib';
import { Duration, aws_dynamodb } from 'aws-cdk-lib';
import * as Backup from 'aws-cdk-lib/aws-backup';
import { BackupPlanRule, BackupResource, IBackupVault } from 'aws-cdk-lib/aws-backup';
import { Schedule } from 'aws-cdk-lib/aws-events';
import { Construct } from 'constructs';
import * as dayjs from 'dayjs';
import * as dotenv from 'dotenv';

export class CdkStack extends cdk.Stack {

  // 默认以秒为单位的日期作为备份计划和资源的后缀
  private readonly defaultPlanTime!: string;
  // 默认备份计划名称
  private readonly defaultPlanName!: string;
  // 默认备份资源名称
  private readonly defaultResourceName!: string;
  // 默认备份库配置
  private readonly defaultBackupVaultConfig!: IBackupVault;
  // 默认异地备份库配置
  private readonly defaultBackupVaultOffSiteConfig!: IBackupVault;
  // 默认备份库名称
  private readonly defaultBackupVaultName!: string;
  // 默认异地备份库名称
  private readonly defaultBackupVaultOffSiteName!: string;
  // 默认备份库ARN
  private readonly defaultBackupVaultArn!: string;
  // 默认异地备份库ARN
  private readonly defaultBackupVaultOffSiteArn!: string;
  // 当前账户id
  private readonly accountId!: string;

  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    // 加载环境变量
    const envPath = `${__dirname}/../.env.${process.env.STAGE ?? 'dev'}`;
    const env = dotenv.config({ path: envPath });
    if (!env.parsed) {
      throw new Error('class init error! env path invalid!');
    }
    // 获取账户环境信息
    this.accountId = cdk.Stack.of(this).account;
    this.defaultBackupVaultName = env.parsed.BACKUP_VAULT_NAME;
    this.defaultBackupVaultOffSiteName = env.parsed.OFFSITE_VAULT_NAME;
    // 中国-宁夏
    this.defaultBackupVaultArn = `arn:aws-cn:backup:cn-northwest-1:${this.accountId}:backup-vault:Default`;
    // 中国-北京
    this.defaultBackupVaultOffSiteArn = `arn:aws-cn:backup:cn-north-1:${this.accountId}:backup-vault:Default`;
    this.defaultPlanTime = dayjs().format('YYYYMMDDHHmmss');
    this.defaultPlanName = `backupPlan-${this.defaultPlanTime}`;
    this.defaultResourceName = `backupResource-${this.defaultPlanTime}`;
    this.defaultBackupVaultConfig = Backup.BackupVault.fromBackupVaultArn(this, this.defaultBackupVaultName, this.defaultBackupVaultArn);
    this.defaultBackupVaultOffSiteConfig = Backup.BackupVault.fromBackupVaultArn(this, `${this.defaultBackupVaultOffSiteName}-offsite`, this.defaultBackupVaultOffSiteArn);
  }

  // 核心计划备份
  backupPlanCore(tableNameList: string[]) {
    if (tableNameList.length === 0) {
      console.log('backupPlanCore tableNameList is empty');
      return;
    }
    const backPlan = new Backup.BackupPlan(this, 'BackPlanCore');
    const backPlanCoreRule = new BackupPlanRule({
      // 保存时长 保留七天
      deleteAfter: Duration.days(7),
      // 多久迁移至冷存储区 moveToColdStorageAfter
      // 规则名称
      ruleName: this.defaultPlanName,
      // 备份频率 每小时
      scheduleExpression: Schedule.cron({ hour: '*', minute: '0' }),
      // 备份库配置
      backupVault: this.defaultBackupVaultConfig,
      // 连续备份
      enableContinuousBackup: true,
    });
    const resourceList = tableNameList.map((tbName) => BackupResource.fromDynamoDbTable(aws_dynamodb.Table.fromTableName(this, 'TableCore', tbName)));
    const backCoreResource = {
      resources: resourceList,
      backupSelectionName: this.defaultResourceName,
    };
    backPlan.addSelection('Selection', backCoreResource);
    backPlan.addRule(backPlanCoreRule);
    return backPlan;
  }

  // 标准备份
  backupPlanStandard(tableNameList: string[]) {
    if (tableNameList.length === 0) {
      console.log('backupPlanStandard tableNameList is empty');
      return;
    }
    const backPlan = new Backup.BackupPlan(this, 'backupPlanStandard');
    const backPlanCoreRule = new BackupPlanRule({
      // 保存时长 保留七天
      deleteAfter: Duration.days(15),
      // 多久迁移至冷存储区 moveToColdStorageAfter
      // 规则名称
      ruleName: this.defaultPlanName,
      // 备份频率 每天凌晨和12点执行 utc时间 中国区会+8小时
      scheduleExpression: Schedule.cron({ hour: '16,4', minute: '0' }),
      // 备份库配置
      backupVault: this.defaultBackupVaultConfig,
      // 连续备份
      enableContinuousBackup: false,
    });
    const resourceList = tableNameList.map((tbName) => BackupResource.fromDynamoDbTable(aws_dynamodb.Table.fromTableName(this, 'TableStandard', tbName)));
    const backCoreResource = {
      resources: resourceList,
      backupSelectionName: this.defaultResourceName,
    };
    backPlan.addSelection('Selection', backCoreResource);
    backPlan.addRule(backPlanCoreRule);
    return backPlan;
  }

  // 异地备份
  backupPlanOffSite(tableNameList: string[]) {
    if (tableNameList.length === 0) {
      console.log('backupPlanOffSite tableNameList is empty');
      return;
    }
    const backPlan = new Backup.BackupPlan(this, 'backupPlanOffSite');
    const backPlanCoreRule = new BackupPlanRule({
      // 保存时长 保留30天
      deleteAfter: Duration.days(30),
      // 多久迁移至冷存储区 moveToColdStorageAfter
      // 规则名称
      ruleName: this.defaultPlanName,
      // 备份频率 每天凌晨和12点执行
      scheduleExpression: Schedule.cron({ hour: '16', minute: '0' }),
      // 备份库配置
      backupVault: this.defaultBackupVaultConfig,
      // 连续备份
      enableContinuousBackup: false,
      // 复制目标点
      copyActions: [
        {
          // 异地备份库配置
          destinationBackupVault: this.defaultBackupVaultOffSiteConfig,
          // 异地备份库保留30天
          deleteAfter: Duration.days(30),
        }
      ]
    });
    const resourceList = tableNameList.map((tbName) => BackupResource.fromDynamoDbTable(aws_dynamodb.Table.fromTableName(this, 'TableOffSite', tbName)));
    const backCoreResource = {
      resources: resourceList,
      backupSelectionName: this.defaultResourceName,
    };
    backPlan.addSelection('Selection', backCoreResource);
    backPlan.addRule(backPlanCoreRule);
    return backPlan;
  }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值