CI部の宮本です。在宅勤務で毎朝のコーヒーを淹れるのが面倒くさくなってきました。全自動のコーヒーメーカーが欲しいのですが、中々のお値段なのでためらっています。
さて、今回は AWS CDK を使って Redash の環境を構築してみました。
AWS CDK とは
AWS クラウド開発キット (AWS CDK) は、使い慣れたプログラミング言語を使用してクラウドアプリケーションリソースをモデル化およびプロビジョニングするためのオープンソースのソフトウェア開発フレームワークです。 引用元: https://aws.amazon.com/jp/cdk/
内部的には CloudFormation が生成され、リソースの作成が行われます。対応言語は TypeScript、Python、Java、C#等が使用出来ます。TypeScriptなどの静的型言語で、型に守られながらリソースを書けるところが良さそうです。
Redash とは
Redash はオープンソースで開発されているダッシュボードツールです。様々なデータソースと接続可能で、SQLと簡単な設定をすることでダッシュボードを作ることが出来ます。
接続可能なデータベースが豊富で、MySQLやPostgreSQLなどの一般的なRDBMSはもちろん、SnowflakeやSalesforce などのSaaSにも接続出来る優れものです。
完成イメージ
AWS CDK で以下の様な構成をAWS上に構築してみたいと思います。
Redash は Flask や Redis 、PostgreSQL などで構築されている様ですが、公式から全部入りのAMI が提供されているので、今回はこれを使用します。
AWS CDK の開発環境の準備
今回はTypeScriptにて開発を行います。以下が準備済みの前提で進めます。
- AWS CLI (2.0.19)
- Node.js (12.18.0)
AWS CDK のインストール
以下コマンドでインストールし、バージョンが確認できればインストール成功です。
$ npm install -g aws-cdk $ cdk --version 1.51.0 (build 8c2d53c)
CDKプロジェクトの作成
早速CDKプロジェクトの作成をしていきましょう。--language
オプションの後に使用したい言語を指定します。
$ mkdir redash-cdk && cd redash-cdk # プロジェクトディレクトリの作成 $ cdk init --language typescript # プロジェクトの初期化 ... 中略... ✅ All done! ************************************************** *** Newer version of CDK is available [1.51.0] *** *** Upgrade recommended *** **************************************************
お好みのエディタでプロジェクトを開いてみましょう。初期のプロジェクト構成はこの様になっています。
lib/redash-cdk-stack.ts
にリソースを定義するコードを書いて行きます。
依存ライブラリのインストール
AWS CDK では作成するリソース毎にライブラリが分けられており、使用したい場合は以下の様にインストールする必要があります。今回は EC2、IAM、ALBを使用するのでそれぞれインストールします。作成できるリソースは API Reference を参照してください。
$ npm install @aws-cdk/aws-ec2 @aws-cdk/aws-iam @aws-cdk/aws-elasticloadbalancingv2 @aws-cdk/aws-elasticloadbalancingv2-targets
スタックの実装
結論からですが、以下の様なコードで実現することが出来ました。
// lib/redash-cdk-stack.ts import * as cdk from "@aws-cdk/core"; import * as ec2 from "@aws-cdk/aws-ec2"; import * as iam from "@aws-cdk/aws-iam"; import * as elbv2 from "@aws-cdk/aws-elasticloadbalancingv2"; import * as targets from "@aws-cdk/aws-elasticloadbalancingv2-targets"; export class RedashCdkStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // (1) const vpc = new ec2.Vpc(this, "redash-vpc", { cidr: "10.100.0.0/16", enableDnsHostnames: true, enableDnsSupport: true, maxAzs: 2, natGateways: 1, subnetConfiguration: [ { name: "public", subnetType: ec2.SubnetType.PUBLIC, cidrMask: 24, }, { name: "private", subnetType: ec2.SubnetType.PRIVATE, cidrMask: 24, }, ], }); // (2) const role = new iam.Role(this, "redash-instance-role", { assumedBy: new iam.ServicePrincipal("ec2.amazonaws.com"), managedPolicies: [ iam.ManagedPolicy.fromAwsManagedPolicyName( "AmazonSSMManagedInstanceCore" ), ], }); // (3) const albSg = new ec2.SecurityGroup(this, "redash-alb-sg", { vpc: vpc, allowAllOutbound: true, }); // (4) const instanceSg = new ec2.SecurityGroup(this, "redash-instance-sg", { vpc: vpc, allowAllOutbound: true, }); instanceSg.addIngressRule(albSg, ec2.Port.tcp(80)); // (5) const instance = new ec2.Instance(this, "redash", { vpc, instanceType: new ec2.InstanceType("t2.small"), machineImage: ec2.MachineImage.genericLinux({ "us-east-1": "ami-0d915a031cabac0e0", "us-east-2": "ami-0b97435028ca44fcc", "us-west-1": "ami-068d0753a46192935", "us-west-2": "ami-0c457f229774da543", "eu-west-1": "ami-046c6a0123bf94619", "eu-west-2": "ami-0dbe8ba0cd21ea12b", "eu-west-3": "ami-041bf9180061ce7ea", "eu-central-1": "ami-0f8184e6f30cc0c33", "eu-north-1": "ami-08dd1b893371bcaac", "ap-south-1": "ami-0ff23052091536db2", "ap-southeast-1": "ami-0527e82bae7c51958", "ap-southeast-2": "ami-0bae8773e653a32ec", "ap-northeast-1": "ami-060741a96307668be", "ap-northeast-2": "ami-0d991ac4f545a6b34", "sa-east-1": "ami-076f350d5a5ec448d", "ca-central-1": "ami-0071deaa12b66d1bf", }), role, blockDevices: [ { deviceName: "/dev/sda1", volume: ec2.BlockDeviceVolume.ebs(30), }, ], securityGroup: instanceSg, }); // (6) const alb = new elbv2.ApplicationLoadBalancer(this, "redash-alb", { vpc, internetFacing: true, securityGroup: albSg, }); // (7) const listener = alb.addListener("redash-alb-listener", { port: 443, }); // (8) listener.addTargets("redash-alb-target", { port: 80, targets: [new targets.InstanceTarget(instance)], healthCheck: { path: "/status.json", }, }); } }
上から解説していきます。
(1) VPCを作成しています。cidr
や enableDnsHostnames
など、見慣れたオプションがありますね。maxAzs
はサブネットを作成するアベイラビリティーゾーンの数です。デフォルトだと3AZにサブネットを展開してしまうので、2に設定しています。また、natGateways
は作成する NatGatewayの数です。最後の subnetConfiguration
はその名の通り、作成するサブネットの設定です。subnetType
に PUBLIC
、PRIVATE
を設定することで、ルートテーブルをよしなに作成してくれます。
(2) EC2インスタンスにアタッチするIAMロールを作成しています。セッションマネージャーにてログインする為に、AmazonSSMManagedInstanceCore
のマネージドポリシーを設定しています。
(3) ALBにアタッチするセキュリティグループを作成しています。
(4) EC2インスタンスにアタッチするセキュリティグループを作成しています。作成後、ALBからの ポート80 へのインバウンドアクセスを許可するルールを追加しています。
(5) EC2インスタンスを作成しています。ec2.MachineImage.genericLinux
のパラメータでリージョンとAMIのマッピングを設定しています。blockDevices
でEBSの設定も可能です。
(6) ALBを作成しています。
(7) ALBのリスナーを追加しています。説明のし易さの為、ポート80 (HTTP) としていますが、現実的にはポート443 (HTTPS) を受け付ける様にしましょう。その際はACMで証明書を発行し、certificates プロパティに設定するなどしましょう。
(8) ターゲットを追加しています。EC2インスタンスのポート80 をターゲットとしています。また、ヘルスチェックのパスとして /status.json
を設定しています。こちらはRedashにて提供されるステータスチェック用のAPIのパスです。
// bin/redash-cdk.ts #!/usr/bin/env node import "source-map-support/register"; import * as cdk from "@aws-cdk/core"; import { RedashCdkStack } from "../lib/redash-cdk-stack"; const app = new cdk.App(); new RedashCdkStack(app, "RedashCdkStack", { env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION, }, });
こちらがエントリポイントとなるコードです。環境変数からアカウントとリージョンを設定しています。こちらはAMIの選択の為に追加をしています。デプロイ前に環境変数として設定しておきましょう。
CDK スタックのデプロイ
初めてデプロイする場合は以下の cdk bootstrap
を実行する必要があります。CFnテンプレートを保存するためのバケットの作成が行われます。
$ cdk bootstrap ⏳ Bootstrapping environment aws://XXXXXXXXXXXX/ap-northeast-1... ✅ Environment aws://XXXXXXXXXXXX/ap-northeast-1 bootstrapped (no changes).
早速デプロイしてみましょう。
$ cdk deploy This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening). Please confirm you intend to make the following modifications: IAM Statement Changes ┌───┬─────────────────────────────┬────────┬────────────────┬───────────────────────────┬───────────┐ │ │ Resource │ Effect │ Action │ Principal │ Condition │ ├───┼─────────────────────────────┼────────┼────────────────┼───────────────────────────┼───────────┤ │ + │ ${redash-instance-role.Arn} │ Allow │ sts:AssumeRole │ Service:ec2.amazonaws.com │ │ └───┴─────────────────────────────┴────────┴────────────────┴───────────────────────────┴───────────┘ IAM Policy Changes ┌───┬─────────────────────────┬────────────────────────────────────────────────────────────────────┐ │ │ Resource │ Managed Policy ARN │ ├───┼─────────────────────────┼────────────────────────────────────────────────────────────────────┤ │ + │ ${redash-instance-role} │ arn:${AWS::Partition}:iam::aws:policy/AmazonSSMManagedInstanceCore │ └───┴─────────────────────────┴────────────────────────────────────────────────────────────────────┘ Security Group Changes ┌───┬───────────────────────────────┬─────┬────────────┬──────────────────────────┐ │ │ Group │ Dir │ Protocol │ Peer │ ├───┼───────────────────────────────┼─────┼────────────┼──────────────────────────┤ │ + │ ${redash-alb-sg.GroupId} │ In │ TCP 80 │ Everyone (IPv4) │ │ + │ ${redash-alb-sg.GroupId} │ Out │ Everything │ Everyone (IPv4) │ ├───┼───────────────────────────────┼─────┼────────────┼──────────────────────────┤ │ + │ ${redash-instance-sg.GroupId} │ In │ TCP 80 │ ${redash-alb-sg.GroupId} │ │ + │ ${redash-instance-sg.GroupId} │ Out │ Everything │ Everyone (IPv4) │ └───┴───────────────────────────────┴─────┴────────────┴──────────────────────────┘ (NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) Do you wish to deploy these changes (y/n)? y RedashCdkStack: deploying... RedashCdkStack: creating CloudFormation changeset... ✅ RedashCdkStack Stack ARN: arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/RedashCdkStack/021bbd00-c807-11ea-8ab6-06255f79192b
デプロイが出来ました!デプロイ前にセキュリティ関連の変更を表示してくれるのが親切です。
動作確認
マネジメントコンソールで作成されたALBのエンドポイントを確認し、ブラウザでアクセスしてみましょう。以下の様な初期画面が表示されればOKです。
生成されるテンプレート
冒頭で内部的には CloudFormation のテンプレートが生成されると書きましたが、 cdk synth
コマンドで確認できます。
$ cdk synth Resources: redashvpc787F192D: Type: AWS::EC2::VPC Properties: CidrBlock: 10.100.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true InstanceTenancy: default Tags: - Key: Name Value: RedashCdkStack/redash-vpc Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/Resource redashvpcpublicSubnet1Subnet3D390376: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.100.0.0/24 VpcId: Ref: redashvpc787F192D AvailabilityZone: ap-northeast-1a MapPublicIpOnLaunch: true Tags: - Key: aws-cdk:subnet-name Value: public - Key: aws-cdk:subnet-type Value: Public - Key: Name Value: RedashCdkStack/redash-vpc/publicSubnet1 Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/publicSubnet1/Subnet redashvpcpublicSubnet1RouteTableE975F80B: Type: AWS::EC2::RouteTable Properties: VpcId: Ref: redashvpc787F192D Tags: - Key: Name Value: RedashCdkStack/redash-vpc/publicSubnet1 Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/publicSubnet1/RouteTable redashvpcpublicSubnet1RouteTableAssociationD0578F24: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: Ref: redashvpcpublicSubnet1RouteTableE975F80B SubnetId: Ref: redashvpcpublicSubnet1Subnet3D390376 Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/publicSubnet1/RouteTableAssociation redashvpcpublicSubnet1DefaultRoute3F4FA9A9: Type: AWS::EC2::Route Properties: RouteTableId: Ref: redashvpcpublicSubnet1RouteTableE975F80B DestinationCidrBlock: 0.0.0.0/0 GatewayId: Ref: redashvpcIGW7813B7C8 DependsOn: - redashvpcVPCGWD937466E Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/publicSubnet1/DefaultRoute redashvpcpublicSubnet1EIPCC704A65: Type: AWS::EC2::EIP Properties: Domain: vpc Tags: - Key: Name Value: RedashCdkStack/redash-vpc/publicSubnet1 Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/publicSubnet1/EIP redashvpcpublicSubnet1NATGatewayE9CE305C: Type: AWS::EC2::NatGateway Properties: AllocationId: Fn::GetAtt: - redashvpcpublicSubnet1EIPCC704A65 - AllocationId SubnetId: Ref: redashvpcpublicSubnet1Subnet3D390376 Tags: - Key: Name Value: RedashCdkStack/redash-vpc/publicSubnet1 Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/publicSubnet1/NATGateway redashvpcpublicSubnet2Subnet4F70832C: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.100.1.0/24 VpcId: Ref: redashvpc787F192D AvailabilityZone: ap-northeast-1c MapPublicIpOnLaunch: true Tags: - Key: aws-cdk:subnet-name Value: public - Key: aws-cdk:subnet-type Value: Public - Key: Name Value: RedashCdkStack/redash-vpc/publicSubnet2 Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/publicSubnet2/Subnet redashvpcpublicSubnet2RouteTableCECFFA67: Type: AWS::EC2::RouteTable Properties: VpcId: Ref: redashvpc787F192D Tags: - Key: Name Value: RedashCdkStack/redash-vpc/publicSubnet2 Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/publicSubnet2/RouteTable redashvpcpublicSubnet2RouteTableAssociationD50DF0BC: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: Ref: redashvpcpublicSubnet2RouteTableCECFFA67 SubnetId: Ref: redashvpcpublicSubnet2Subnet4F70832C Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/publicSubnet2/RouteTableAssociation redashvpcpublicSubnet2DefaultRouteEDB2F883: Type: AWS::EC2::Route Properties: RouteTableId: Ref: redashvpcpublicSubnet2RouteTableCECFFA67 DestinationCidrBlock: 0.0.0.0/0 GatewayId: Ref: redashvpcIGW7813B7C8 DependsOn: - redashvpcVPCGWD937466E Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/publicSubnet2/DefaultRoute redashvpcprivateSubnet1Subnet8CAD3737: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.100.2.0/24 VpcId: Ref: redashvpc787F192D AvailabilityZone: ap-northeast-1a MapPublicIpOnLaunch: false Tags: - Key: aws-cdk:subnet-name Value: private - Key: aws-cdk:subnet-type Value: Private - Key: Name Value: RedashCdkStack/redash-vpc/privateSubnet1 Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/privateSubnet1/Subnet redashvpcprivateSubnet1RouteTableAE169A43: Type: AWS::EC2::RouteTable Properties: VpcId: Ref: redashvpc787F192D Tags: - Key: Name Value: RedashCdkStack/redash-vpc/privateSubnet1 Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/privateSubnet1/RouteTable redashvpcprivateSubnet1RouteTableAssociation11192046: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: Ref: redashvpcprivateSubnet1RouteTableAE169A43 SubnetId: Ref: redashvpcprivateSubnet1Subnet8CAD3737 Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/privateSubnet1/RouteTableAssociation redashvpcprivateSubnet1DefaultRouteAAEFF0DE: Type: AWS::EC2::Route Properties: RouteTableId: Ref: redashvpcprivateSubnet1RouteTableAE169A43 DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: Ref: redashvpcpublicSubnet1NATGatewayE9CE305C Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/privateSubnet1/DefaultRoute redashvpcprivateSubnet2Subnet5B47BA0C: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.100.3.0/24 VpcId: Ref: redashvpc787F192D AvailabilityZone: ap-northeast-1c MapPublicIpOnLaunch: false Tags: - Key: aws-cdk:subnet-name Value: private - Key: aws-cdk:subnet-type Value: Private - Key: Name Value: RedashCdkStack/redash-vpc/privateSubnet2 Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/privateSubnet2/Subnet redashvpcprivateSubnet2RouteTable2FA16BB7: Type: AWS::EC2::RouteTable Properties: VpcId: Ref: redashvpc787F192D Tags: - Key: Name Value: RedashCdkStack/redash-vpc/privateSubnet2 Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/privateSubnet2/RouteTable redashvpcprivateSubnet2RouteTableAssociation523D6F0E: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: Ref: redashvpcprivateSubnet2RouteTable2FA16BB7 SubnetId: Ref: redashvpcprivateSubnet2Subnet5B47BA0C Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/privateSubnet2/RouteTableAssociation redashvpcprivateSubnet2DefaultRouteABA00E61: Type: AWS::EC2::Route Properties: RouteTableId: Ref: redashvpcprivateSubnet2RouteTable2FA16BB7 DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: Ref: redashvpcpublicSubnet1NATGatewayE9CE305C Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/privateSubnet2/DefaultRoute redashvpcIGW7813B7C8: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: RedashCdkStack/redash-vpc Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/IGW redashvpcVPCGWD937466E: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: Ref: redashvpc787F192D InternetGatewayId: Ref: redashvpcIGW7813B7C8 Metadata: aws:cdk:path: RedashCdkStack/redash-vpc/VPCGW redashinstanceroleCA5CD152: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: ec2.amazonaws.com Version: "2012-10-17" ManagedPolicyArns: - Fn::Join: - "" - - "arn:" - Ref: AWS::Partition - :iam::aws:policy/AmazonSSMManagedInstanceCore Metadata: aws:cdk:path: RedashCdkStack/redash-instance-role/Resource redashalbsgFF5DACBB: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: RedashCdkStack/redash-alb-sg SecurityGroupEgress: - CidrIp: 0.0.0.0/0 Description: Allow all outbound traffic by default IpProtocol: "-1" SecurityGroupIngress: - CidrIp: 0.0.0.0/0 Description: Allow from anyone on port 80 FromPort: 80 IpProtocol: tcp ToPort: 80 VpcId: Ref: redashvpc787F192D Metadata: aws:cdk:path: RedashCdkStack/redash-alb-sg/Resource redashinstancesg749BCA92: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: RedashCdkStack/redash-instance-sg SecurityGroupEgress: - CidrIp: 0.0.0.0/0 Description: Allow all outbound traffic by default IpProtocol: "-1" VpcId: Ref: redashvpc787F192D Metadata: aws:cdk:path: RedashCdkStack/redash-instance-sg/Resource redashinstancesgfromRedashCdkStackredashalbsg26A403EF8046A50BB9: Type: AWS::EC2::SecurityGroupIngress Properties: IpProtocol: tcp Description: from RedashCdkStackredashalbsg26A403EF:80 FromPort: 80 GroupId: Fn::GetAtt: - redashinstancesg749BCA92 - GroupId SourceSecurityGroupId: Fn::GetAtt: - redashalbsgFF5DACBB - GroupId ToPort: 80 Metadata: aws:cdk:path: RedashCdkStack/redash-instance-sg/from RedashCdkStackredashalbsg26A403EF:80 redashInstanceProfile17725B73: Type: AWS::IAM::InstanceProfile Properties: Roles: - Ref: redashinstanceroleCA5CD152 Metadata: aws:cdk:path: RedashCdkStack/redash/InstanceProfile redashE2FE35A2: Type: AWS::EC2::Instance Properties: AvailabilityZone: ap-northeast-1a BlockDeviceMappings: - DeviceName: /dev/sda1 Ebs: VolumeSize: 30 IamInstanceProfile: Ref: redashInstanceProfile17725B73 ImageId: ami-060741a96307668be InstanceType: t2.small SecurityGroupIds: - Fn::GetAtt: - redashinstancesg749BCA92 - GroupId SubnetId: Ref: redashvpcprivateSubnet1Subnet8CAD3737 Tags: - Key: Name Value: RedashCdkStack/redash UserData: Fn::Base64: "#!/bin/bash" DependsOn: - redashinstanceroleCA5CD152 Metadata: aws:cdk:path: RedashCdkStack/redash/Resource redashalbE9806DDF: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Scheme: internet-facing SecurityGroups: - Fn::GetAtt: - redashalbsgFF5DACBB - GroupId Subnets: - Ref: redashvpcpublicSubnet1Subnet3D390376 - Ref: redashvpcpublicSubnet2Subnet4F70832C Type: application DependsOn: - redashvpcpublicSubnet1DefaultRoute3F4FA9A9 - redashvpcpublicSubnet2DefaultRouteEDB2F883 Metadata: aws:cdk:path: RedashCdkStack/redash-alb/Resource redashalbredashalblistenerA15C76FF: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - TargetGroupArn: Ref: redashalbredashalblistenerredashalbtargetGroupEEFC3BEE Type: forward LoadBalancerArn: Ref: redashalbE9806DDF Port: 80 Protocol: HTTP Metadata: aws:cdk:path: RedashCdkStack/redash-alb/redash-alb-listener/Resource redashalbredashalblistenerredashalbtargetGroupEEFC3BEE: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckPath: /status.json Port: 80 Protocol: HTTP Targets: - Id: Ref: redashE2FE35A2 TargetType: instance VpcId: Ref: redashvpc787F192D Metadata: aws:cdk:path: RedashCdkStack/redash-alb/redash-alb-listener/redash-alb-targetGroup/Resource CDKMetadata: Type: AWS::CDK::Metadata Properties: Modules: aws-cdk=1.51.0,@aws-cdk/aws-cloudwatch=1.51.0,@aws-cdk/aws-ec2=1.51.0,@aws-cdk/aws-elasticloadbalancingv2=1.51.0,@aws-cdk/aws-elasticloadbalancingv2-targets=1.51.0,@aws-cdk/aws-events=1.51.0,@aws-cdk/aws-iam=1.51.0,@aws-cdk/aws-kms=1.51.0,@aws-cdk/aws-logs=1.51.0,@aws-cdk/aws-s3=1.51.0,@aws-cdk/aws-ssm=1.51.0,@aws-cdk/cloud-assembly-schema=1.51.0,@aws-cdk/core=1.51.0,@aws-cdk/cx-api=1.51.0,@aws-cdk/region-info=1.51.0,jsii-runtime=node.js/v12.18.0
一気にスクロールしましたね? AWS CDK の強力さがお分かりいただけたと思います。
スタック削除をする場合は cdk destroy
を実行します。
おわりに
AWS CDK で Redash 環境を構築しました。次回は Snowflake へ接続してダッシュボードを作ってみたいと思います。