[機能拡張]IaC対応されたAmazon CodeWhispererの稼働検証をしてみた

## はじめに
2023年11月に開催されたAWS reInvent2023で発表された新機能、アップデートの中に、[Amazon CodeWhisperer](https://aws.amazon.com/jp/codewhisperer/?nc2=h_ql_prod_ml_cw)の機能拡張が紹介されていました。これまで、Amazon CodeWhisperer(以下、CodeWhisperer)は主にプログラミング言語に対するAIコード作成支援、コードのセキュリティー・スキャン機能のサポートがされていました。今回のアップデートでは、IaC(CloudFormationやTerraform)に対しても同様の機能をサポートするように機能拡張されています。私はIaC大好き人間なので、早速CloudFormationのコードに対してCodeWhispererの稼働検証を実施しました。

## CodeWhispererのセットアップ
CodeWhispererは様々なIDE(統合開発環境)で利用することが可能です。今回は、VS Code(以下VSC)上にCodeWhisperer環境を導入して使用できるようにしました。
### AWS ToolKitのインストール
VSC上でAWSの各種サービスを使用したオペレーションや開発などを実施する際に便利なのがAWS ToolKitです。CodeWhispererを使用するには、このAWS ToolkitをVSC側にインストールしておく必要があります。私の環境では2年ほど前からAWS Toolkitを導入していますが、気づいたら下記画面のようにCodeWhisperer対応バージョンに変わってました。
![AWS Toolkit画面.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567099/0921d8e7-ce57-0497-b7b1-9efb1e3beaa2.jpeg)
### AWS Builder IDの作成
CodeWhispererのAIコード作成支援機能を有効化/無効化したり、セキュリティー・スキャン機能を使用できるようにするためには、サインインを行う必要があります。組織によってはSSOを使用すればそのままサインインが可能ですが、私は個人ユーザーなので無料のAWS Buidler IDというものを作成してサインインを実施しました。「Use for free with AWS Builder ID」というボタンをクリックすれば、次々に作成のためのダイアログが出てきますので、AWS Builder IDの作成は簡単に終わります。ID作成完了後は、このIDを使用してサインインを行います。サインイン後の画面は下記のようになります。
![AWS Toolkit画面2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567099/576011d6-980a-d85d-481e-834cdd5f7f80.jpeg)
上記画面左側の「CodeWhisperer」の下の部分にいくつか項目が増えているのがわかるかと思います。
* 「Pause Auto Suggestion」ボタン
   * デフォルトでは、AIによるコード作成支援機能が有効化されています。このボタンを押下すると、コード作成支援機能を一時的に無効化することが可能です。
* 「Run Security Scan」ボタン
   * 画面に表示させているコードのセキュリティー・スキャンを実施するのに使用します。 

:::note info
<font color="Blue">(2024年3月26日追記)</font>
最近、VSCodeにおけるAWS Tool Kitの画面表示が変わっていることに気づきました。昨年当記事を執筆した時点のAWS Tool Kitのバージョンでは、「Amazon Q」と「CodeWhisperer」は画面左側に別々の項目として表示されていました。今のバージョン2.16ですと、Amazon QとCodeWhispererが一体化し、ほとんどの選択メニューが下記画面のようにステータスバーに移動になっています。機能自体は特に変わってはいないようです。
![p2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567099/24c371af-fde4-d84e-03f1-514fbc2cec50.jpeg)
ステータスバー上にメニュー表示させるには、画面左側の「AMAZON Q(PREVIEW) + CODEWHISPERER」という枠の中にある「New Menu moved to status bar learn more」というメニューをクリックする、もしくは、画面左下にある紫色のバーに表示されている「CodeWhisperer」をクリックすることで表示することが可能です。

現在のVSCodeの画面がこのようになっている方は、以降の記事に記載の手順を上記画面での利用に読み替えてください。
:::


## AIによるコード生成支援機能の利用
IaCに対してもコード生成支援機能が提供されるようになりましたので、今回はCloudFormationのコードに対してコード生成支援機能の有効性を検証してみました。
### 今回作成する環境

![構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567099/5d7abdc3-931c-3715-6423-49295d23e717.png)

* プライベート・サブネットのみを持つ単一のVPCを作成
* プライベート・サブネット内にEC2インスタンスを1つ作成
* AWS Client VPNサービスを利用して、外部からプライベート・インスタンスに直接プライベートIPアドレスでSSH接続できるようにする。

Client VPNサービスを選択した理由としては、以下の2点です。
* AWSコンソールで作業したことはあるが、一度もコード化したことがないため、それならとCodeWhispererの力を借りようと考えた。
* 下記AWSブログにて、2024年2月よりパブリックIPアドレスが有料化されるとの情報あり。故に、パブリックIPを使用しなくても外部からEC2インスタンスにアクセスできる術がないかを模索した。
[新着情報 – パブリック IPv4 アドレスの利用に対する新しい料金体系を発表 / Amazon VPC IP Address Manager が Public IP Insights の提供を開始](https://aws.amazon.com/jp/blogs/news/new-aws-public-ipv4-address-charge-public-ip-insights/)

なお、本記事ではCodeWhispererの機能検証に主眼を置いている為、AWS Client VPNサービスの詳細設定内容については別記事で紹介したいと思います。

### コード生成支援機能のサンプル
下記は、今回コード化に初挑戦したAWS Client VPN設定部分に関して、AIによるコード生成支援機能を使用した場合のサンプル表示です。白色部分の表示が、コード生成支援機能が提案したコードのイメージになります。
![Auto-Suggestionsあり.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567099/212727c0-ba62-9c2f-5f31-e7caa5093ef1.jpeg)
この状態でTabキーを押下すると、提案されたコード内容がアクティブ表示になります。当然ながら各々のパラメータ設定値についてはAWSのドキュメントを見ながら適宜確認していく必要はあります。
### 使用してみた感想
* 当機能が提供されたおかげで、ドキュメントからパラメータをコピーしてくる等の作業の余計な手間の省略化に繋がるかと思いました。特に一度もコード化したことのないAWSサービスの場合、コード作成のハードルが大きく下がるかと思います。
* TagのValueに表示される値や、Ref関数に指定されている値については、既に作成済みのコード部分から上手く予測してコード提案してくれていると感動しました。

### 作成したCloudFormationコードのサンプル
CodeWhispererのAIコード生成支援機能の力を借りて、最終的に作成することができたコードのサンプルは下記のCreate_ClientVPN.yamlです。(稼働実績はあります。)
```yaml:Create_ClientVPN.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: Sample Script for Creating Client-VPN Environment
    
Resources:
  MyVPC:
    Type: AWS::EC2::VPC
    Properties: 
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: 'true'
      EnableDnsSupport: 'true'
      Tags: 
        - Key: Name
          Value: My-VPC
  MyPrivateSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: ap-northeast-1a
      Tags:
        - Key: Name
          Value: My-Private-Subnet
    DependsOn: MyVPC 
  MyPrivateRtbl:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyVPC
      Tags:
        - Key: Name
          Value: My-Private-Rtbl
    DependsOn: MyVPC
  MyPrivateSubnetRouteTblAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref MyPrivateRtbl
      SubnetId: !Ref MyPrivateSubnet
  MyClientVPNSecGrp:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security Group for Client VPN Endpoint
      VpcId: !Ref MyVPC
      Tags:
        - Key: Name
          Value: My-ClientVPN-Security-Group
  MyPrivateSecGrp:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security Group for VPC Private Subnet
      VpcId: !Ref MyVPC
      SecurityGroupIngress:
        - SourceSecurityGroupId: !Ref MyClientVPNSecGrp
          IpProtocol: tcp
          FromPort: 22
          ToPort: 22
        - SourceSecurityGroupId: !Ref MyClientVPNSecGrp
          IpProtocol: icmp
          FromPort: 8
          ToPort: -1     
      Tags:
        - Key: Name
          Value: My-PrivateSubnet-Security-Group
  MyPrivateInstance:
    Type: AWS::EC2::Instance
    Properties:
      CreditSpecification: 
        CPUCredits: standard
      InstanceType: t2.micro
      KeyName: MyEC2Key
      ImageId: ami-078296f82eb463377
      NetworkInterfaces:
        - AssociatePublicIpAddress: "false"
          DeviceIndex: "0"
          SubnetId: !Ref MyPrivateSubnet
          GroupSet:
            - !Ref MyPrivateSecGrp
      Tags:
        - Key: Name
          Value: My-Private-Instance

  MyClientVPNEndpoint:
    Type: AWS::EC2::ClientVpnEndpoint
    Properties: 
      AuthenticationOptions: 
        - Type: certificate-authentication
          MutualAuthentication: 
            ClientRootCertificateChainArn: '{{resolve:ssm:RootCertARN}}'
      ClientCidrBlock: 192.168.0.0/22
      ConnectionLogOptions: 
        Enabled: false
      ServerCertificateArn: '{{resolve:ssm:ServerCertARN}}'
      VpcId: !Ref MyVPC
      VpnPort: 443
      SecurityGroupIds:
        - !Ref MyClientVPNSecGrp
      TransportProtocol: udp
      TagSpecifications:
        - ResourceType: client-vpn-endpoint
          Tags:
            - Key: Name
              Value: My-Client-VPN-Endpoint

  MyClientVPNTargetNetworkAssociation:
    Type: AWS::EC2::ClientVpnTargetNetworkAssociation
    Properties:
      ClientVpnEndpointId: !Ref MyClientVPNEndpoint
      SubnetId: !Ref MyPrivateSubnet

  MyClientVPNAuthorizationRule:
    Type: AWS::EC2::ClientVpnAuthorizationRule
    Properties:
      AuthorizeAllGroups: true
      ClientVpnEndpointId: !Ref MyClientVPNEndpoint
      TargetNetworkCidr: 10.0.1.0/24

Outputs:
  MyPrivateInstanceIPaddr:
    Description: My Private Instance's Private IP address 
    Value: !GetAtt MyPrivateInstance.PrivateIp
```
上記コードの「MyClientVPNEndpoint」～「MyClientVPNAuthorizationRule」の部分が、CodeWhispererのAIコード生成支援機能の力を借りながら作成した箇所になります。「MyClientVPNEndpoint」の所は自分流に色々カスタマイズをしていますが、残りの「MyClientVPNTargetNetworkAssociation」と「MyClientVPNAuthorizationRule」については、AIが生成してくれたコードをそのまま手を加えずに使用することができました。実に良き機能をご提供いただいたとAWSの開発チームの方々には感謝の言葉しかありません!!

## コードのセキュリティー・スキャン機能の利用
スキャンをかけたいコードを表示している状態で、左側の「Run Security Scan」を押下します。
![AWS Toolkit画面3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567099/81db3676-a4e9-6ee0-2ae5-7b457e9f996c.jpeg)
押下後、画面右下に下記のボックスが表示されます。
![セキュリティー・スキャン開始.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567099/10366c4a-cabe-9718-b6b9-fa218ea97763.jpeg)
スキャンが終了すると、コード上に何かしらの問題があると判定された場合に警告文が表示されます。今回は下記のような6つのメッセージが出力されました。
![セキュリティー・スキャン結果.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567099/3b8e9708-de80-34ac-3c8f-6d16936ca5bc.jpeg)

VPCのサブネットにパブリックIPアドレスがアサインされていないとか、EC2インスタンスのモニタリング機能が無効化されている等といった内容でした。今回の環境作成、及び、検証目的を踏まえると、敢えて対応が必要な項目ではないと判断し、対応は見送りました。

### 使用してみた感想
* 可能であれば、警告文を出力するだけでなく、対応方法も併せて提示してくれるとより良い機能になるかなと思いました。(例えば、対応するためのパラメータ値を提案する等)
* 今回出力された警告内容を踏まえると、本当に適切なスキャンをしてくれているのかなと、微妙な気持ちになりました。(明らかに、EC2インスタンスがVPC内に存在しないとかって、スキャン結果としておかしい気がします。)

## さいごに
今回は、AWS reInvent2023で発表された新機能、アップデートの内、Amazon CodeWhispererのIac対応機能拡張に関して、CloudFormationのコードを使った稼働検証を行い、検証結果による考察を行いました。発表されてからあまり時間の経っていない新機能、アップデートということもあり、個人的には有用な機能だと思った部分もある反面、あれっ？て思う部分もあったというのが正直な感想です。

とはいえ、AIによるコード生成支援機能については、コード作成作業におけるワークロード削減に大きく貢献できる良き機能だと思いましたので、セキュリティー・スキャン機能も含めて今後より便利な機能になればいいなと思います。