Amazon MSK Serverless が CloudFormation でサポートされました

2022.08.19

いわさです。

Amazon MSK (Managed Service for Kafka) では自分でノード管理が必要なクラスターモードに加えて、サーバーレスクラスターモードが AWS re:Invent 2021 で登場しました。

そんな MSK Serverless ですが、これまで CloudFormation には対応していませんでしたが先日のアップデートで CloudFormation にも対応するようになりました。

Terraform でもサポートされるようになったようですが、この記事では CloudFormation について試してみたいと思います。

テンプレートつくってみる

リソースタイプAWS::MSK::ServerlessClusterが使えるようになったのでこいつを使ってやりましょう。という感じです。

なお、非サーバーレスクラスターの場合はAWS::MSK::Clusterを使います。
その際はブローカーノードなどなどのサイズを考慮する必要があったのですが、サーバーレスクラスターの場合だと設定項目がだいぶ少なくなっていました。
ちなみに、非サーバーレスクラスターについても以前 CloudFormation での導入方法をご紹介していますので良ければご参照ください。

以降はポイントを抜粋して初回します。
なおテンプレートの全体は以下へアップしています。

サーバーレスクラスター

一番大きなポイントというか制約でもあるのですが、ClientAuthenticationですね。
MSK サーバーレスの認証は本日時点では IAM 認証のみとなっていますので以下のような構成のみ許容されます。

  MSKClusterServerless:
    Type: AWS::MSK::ServerlessCluster
    Properties: 
      ClientAuthentication: 
        Sasl: 
          Iam: 
            Enabled: true
      ClusterName: HogeClusterServerless
      VpcConfigs: 
        - SecurityGroups: 
            - !Ref MSKSecurityGroup
          SubnetIds: 
          - !Ref PrivateSubnetOne
          - !Ref PrivateSubnetTwo

  MSKSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: for MSK Serverless
      VpcId: !Ref TargetVpc
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 9098
          ToPort: 9098
          SourceSecurityGroupId: !Ref ClientSecurityGroup

クライアント

今回も、MSK クライアントとして EC2 を作成します。
こちらのポイントとしては IAM 認証を行うのでkafka-cluster:関係の権限を持つロールを作成します。
ちなみに以下のポリシーは少し広めになっています。詳しくはサーバーレスクラスターの設定タブにてより最小範囲になったポリシーをご確認ください。

  EC2Role:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: ''
            Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: 'sts:AssumeRole'
      Path: /
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/AmazonMSKFullAccess'
        - 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore'
      Policies:
        - PolicyDocument:
            Version: 2012-10-17
            Statement:
              Effect: Allow
              Action:
                - kafka-cluster:CreateTopic
                - kafka-cluster:ReadData
                - kafka-cluster:DescribeTopic
                - kafka-cluster:Connect
                - kafka-cluster:WriteData
              Resource: "*"
          PolicyName: hoge-client-policy

EC2 側では以下のハイライト部分がポイントです。
前回サーバーレスクラスターの動作確認をした際と同様に、IAM 認証用の MSK ライブラリを導入しています。
実際には利用するクライアントに応じて認証モジュールの導入方法は異なるはずなので、以下に従ってください。

  KafkaClientEC2Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      InstanceType: t3.small
      KeyName: !Ref KeyPairVM
      IamInstanceProfile: !Ref EC2InstanceProfile
      SubnetId: !Ref PrivateSubnetOne
      SecurityGroupIds: 
        - !Ref KafkaClientInstanceSecurityGroup
      ImageId: !Ref ClientAMI
      UserData:
        Fn::Base64: |
          #cloud-config
          package_update: true
          package_upgrade: true
          runcmd:
          - amazon-linux-extras enable corretto8
:
          - cd kafka
          - wget https://archive.apache.org/dist/kafka/2.8.1/kafka_2.12-2.8.1.tgz
          - tar -xzf kafka_2.12-2.8.1.tgz
          - cd kafka_2.12-2.8.1/libs
          - wget https://github.com/aws/aws-msk-iam-auth/releases/download/v1.1.1/aws-msk-iam-auth-1.1.1-all.jar
          - cd ../bin
          - touch client.properties
          - cd /home/ec2-user
          - wget https://bootstrap.pypa.io/get-pip.py
:
          write_files:
          - path: /home/ec2-user/kafka/kafka_2.12-2.8.1/bin/client.properties
            permissions: 0644
            owner: root
            content: |
              security.protocol=SASL_SSL
              sasl.mechanism=AWS_MSK_IAM
              sasl.jaas.config=software.amazon.msk.auth.iam.IAMLoginModule required;
              sasl.client.callback.handler.class=software.amazon.msk.auth.iam.IAMClientCallbackHandler

デプロイと動作確認

ではテンプレートをデプロイして動作確認をしてみます。
デプロイ完了までに数分必要でしたが、やはり非サーバーレスクラスターよりもだいぶ早く使い始めることが出来ますね。

デプロイ後にブートストラックサーバーのエンドポイントを取得しましょう。

クライアントのセキュリティグループからクラスターへの 9098 ポートは開けてあるのでこのエンドポイントを使って EC2 上から疎通確認をしてみます。

sh-4.2$ sudo su ec2-user
bash-4.2$ cd ~/kafka/kafka_2.12-2.8.1/bin/
bash-4.2$ export BS=boot-rmnal50h.c2.kafka-serverless.ap-northeast-1.amazonaws.com:9098
bash-4.2$ ./kafka-topics.sh --bootstrap-server $BS --command-config client.properties --create --topic hoge-msk-serverless --partitions 6
Created topic hoge-msk-serverless.
bash-4.2$ ./kafka-producer-perf-test.sh --topic hoge-msk-serverless --throughput 2560 --num-records 153600 --record-size 4096--producer-props bootstrap.servers=$BS acks=all --producer.config client.properties
12172 records sent, 2434.4 records/sec (9.51 MB/sec), 845.7 ms avg latency, 2006.0 ms max latency.
13430 records sent, 2686.0 records/sec (10.49 MB/sec), 40.8 ms avg latency, 675.0 ms max latency.
12798 records sent, 2559.6 records/sec (10.00 MB/sec), 6.6 ms avg latency, 30.0 ms max latency.
12806 records sent, 2561.2 records/sec (10.00 MB/sec), 6.6 ms avg latency, 33.0 ms max latency.
12796 records sent, 2559.2 records/sec (10.00 MB/sec), 6.4 ms avg latency, 34.0 ms max latency.
12808 records sent, 2561.6 records/sec (10.01 MB/sec), 6.6 ms avg latency, 29.0 ms max latency.
12797 records sent, 2559.4 records/sec (10.00 MB/sec), 6.3 ms avg latency, 29.0 ms max latency.
12801 records sent, 2559.7 records/sec (10.00 MB/sec), 6.6 ms avg latency, 34.0 ms max latency.
12809 records sent, 2561.8 records/sec (10.01 MB/sec), 6.3 ms avg latency, 36.0 ms max latency.
12799 records sent, 2559.8 records/sec (10.00 MB/sec), 6.5 ms avg latency, 34.0 ms max latency.
12802 records sent, 2559.9 records/sec (10.00 MB/sec), 6.4 ms avg latency, 29.0 ms max latency.
153600 records sent, 2558.166647 records/sec (9.99 MB/sec), 75.98 ms avg latency, 2006.00 ms max latency, 6 ms 50th, 783 ms 95th, 1283 ms 99th, 1497 ms 99.9th.

無事トピックの作成とプロデューサーのテストスクリプト実行が確認出来ました。
これで、CloudFormation でデプロイ後にリモート接続してすぐに使い始めることが出来る MSK クライアントとクラスターが用意出来るようになりましたね。

さいごに

本日は Amazon MSK Serverless が CloudFormation をサポートしたので使ってみました。

MSK Serverless はサーバーレスとはいえプロビジョニング期間中の時間あたりの料金が発生するのですが、CloudFormation でテンプレート化しておくと、必要な時にだけプロビジョニングが出来ていいですね。
今後 MSK サーバーレス周りでアップデートがされたらこのテンプレートを使ってすぐに新しい機能を試すことが出来そうです。