AWS CDKをWSL2 Ubuntu環境からセキュアに実行してみた

# **AWS CDKをWSL2 Ubuntu環境からセキュアに実行してみた**

## **はじめに**

- 本アカウントでは初記事ですm(__)m
- AWS CDKを絶賛学習中の身なのですが、だんだんとPCのファイル数も増え管理がしづらくなってしまいました
- そこでなるべくPCをクリーンに保ちつつ、セキュリティ面も最低限考慮した環境構築方法を今回調査してみました

### **この記事でわかる・できること**

- WSL2(Ubuntu)環境の構築方法
- WSL2(Ubuntu)環境からAWS CDK v2を実行するための環境構築方法
- MFA認証済、特定IPアドレス範囲からのみAWS CDKコマンドを実行可能にする方法

## **動作環境・前提条件**

- OS
  - Windows 11 23H2
- WSL
  - VERSION 2
  - Ubuntu 24.04.1 LTS
- AWS(東京リージョン)
  - AWS CLI v2 2.18.2
  - AWS CDK 2.161.1 (build 0a606c9)
- Node
  - nvm 0.40.1
  - npm 10.8.2
  - node v20.18.0
- Typescript
  - tsc Version 5.6.3
- その他
  - AWSアカウントが発行済であること
  - VSCodeがインストール済であること

## 用語解説

- WSLとは
    > WSLは、マイクロソフト社によって提供されているサブシステムで「Windows Subsystem for Linux」の略です。Windows上で**Linuxのコマンド・ツール・アプリケーション等を直接実行可能です**。GNU/Linux 環境のほとんどのコマンド ライン ツール・ユーティリティ・アプリケーションがそのまま実行できます。
    [WSL2とは？Linuxが完全動作する仕組みと特長を紹介！ | アンドエンジニア (and-engineer.com)](https://and-engineer.com/articles/YfEnlBEAACMAm3GD)
    >
- AWS CDKとは
    > AWS Cloud Development Kit (AWS CDK) は、クラウドインフラストラクチャをコードで定義し、AWS CloudFormation を通じてプロビジョニングするためのオープンソースソフトウェア開発フレームワークです。
    [**What is the AWS CDK**](https://docs.aws.amazon.com/cdk/v2/guide/home.html)(和訳)
    >

## 環境構築手順

### 1. WSL2(Ubuntu)環境セットアップ

#### 1-1. wsl2インストール

- 新規インストールする場合
  - **WSLインストール（管理者権限でPowerShellを実行）**

    ```powershell
    wsl --install
    ```

- 既存のWSLを初期化する場合
  - **WSLを再インストール（管理者権限でPowerShellを実行）**

    ```powershell
    # 現状設定確認
    wsl --list

    # wslアンインストール
    wsl --unregister Ubuntu

    # wslインストール
    wsl --install -d Ubuntu
    ```

#### 1-2.PC再起動

- 設定反映のためにPCを再起動する

#### 1-3. wslバージョン確認

- Powershell上から以下のコマンドでVERSION欄が2であることを確認

  ```powershell

  wsl -l -v
  ```

#### 1-4. **Linux(Ubuntu)のセットアップ**

- 検索画面でUbuntuを起動
  - ユーザ名とパスワードを入力
    - 環境によってはwslインストール時にユーザ名とパスワード設定画面がポップアップされる
    - 設定終了後は、Ubuntuが起動していたら一度終了させる（ctr + D）

#### 1-5. VSCodeセットアップ

- **VSCode拡張機能(Remote WSL)のインストール**
  - 拡張機能WSLをインストール
  - VSCode再起動
  - f1キーを押しコマンドパレットに「wsl」と入力
    - 「wslへの接続」を押下してターミナルでwsl2（Ubuntu）環境に接続できることを確認

### 2. AWS CDK実行用のIAMユーザ作成

#### 2-1. IAMポリシー作成

- IAM>ポリシー>ポリシーの作成
  - ポリシー名
    - 任意
  - json(MFA認証なしではすべての操作不可設定)

    ```json
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "AllDenyWithoutMFA",
                "Effect": "Deny",
                "Action": [
                    "*"
                ],
                "Resource": [
                    "*"
                ],
                "Condition": {
                    "BoolIfExists": {
                        "aws:MultiFactorAuthPresent": false
                    }
                }
            }
        ]
    }
    ```

    - json(特定のIPアドレスから以外からのアクセスを拒否設定)
      - ※特定のIPアドレス範囲からのみ接続する場合有効※必要なければ飛ばして問題なし
      - グローバルIPアドレスの確認
        - [**CMAN**](https://www.cman.jp/network/support/go_access.cgi)にアクセス
        - 「あなたのIPアドレス(グローバルIP)」欄にグローバルIPアドレスが表示

            ```json
            {
                "Version": "2012-10-17",
                "Statement": {
                    "Effect": "Deny",
                    "Action": "*",
                    "Resource": "*",
                    "Condition": {
                        "NotIpAddress": {
                            "aws:SourceIp": [
                                "192.0.2.0/24",
                                "203.0.113.0/24"
                            ]
                        }
                    }
                }
            }
            ```

#### 2-2. IAMユーザ作成(CLIコマンド実行用)

- IAM>ユーザー>ユーザーの作成
  - ユーザ名
    - 任意
  - AWS マネジメントコンソールへのユーザーアクセスを提供する - *オプション*
    - チェックなし
  - 許可のオプション
    - ポリシーを直接アタッチする
  - 許可ポリシー
    - `AdministratorAccess`
      - 許可ポリシーは実際に使うリソースの範囲に限定すること
    - 2-1. で作成した「MFA認証なしではすべての操作不可」するIAMポリシー
    - 2-1. で作成した「特定のIPアドレスから以外からのアクセスを拒否」するIAMポリシー

#### 2-3. MFAデバイスの設定

- IAM>ユーザー>CLI用ユーザ>セキュリティ認証情報>多要素認証>MFAデバイスの割り当て
  - MFAのARNは後で使うためメモしておくこと

#### 2-4. アクセスキーの発行

- IAM>ユーザー>CLI用ユーザ>セキュリティ認証情報>アクセスキー
  - アクセスキー/シークレットアクセスキー情報が記載されたCSVファイルをダウンロードしておくこと

### 3. AWS CDK実行環境構築

#### 3-1. AWSCLI v2環境構築

- unzipコマンドインストール
  - awscliv2.zipを解凍するためにunzipコマンドが必要
  - WSL2(Ubuntu)の初期状態にはunzipコマンドがないため、インストールする必要がある

    ```markdown
    # unzipインストール
    sudo apt install unzip
    
    # unzipインストール確認
    which unzip
    ```

- AWS CLI v2コマンドインストール

    ```markdown
    # インストール先ディレクトリ作成
     mkdir -p ~/setup/aws && cd ~/setup/aws
    
    # AWS CLI v2インストール
    curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
    unzip awscliv2.zip
    sudo ./aws/install
    
    # CLIバージョン確認
    aws --version
    ```

#### 3-2. Node環境構築

- nvmインストール(Node.jｓのバージョン管理ツール)

    ```markdown
    
    # nvmインストール
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
    wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
    
    # シェル再実行
    exec bash
    
    # nvmインストール確認
    nvm --version
    ```

- Node.jsインストール

    ```markdown
    
    # LTS バージョンのみを確認する
    nvm ls-remote --lts
    
    # Node.jsインストール
    nvm install v20.18.0
    
    # Node.jsインストール確認
    node -v
    
    # npmインストール確認
    npm -v
    ```

#### 3-3. AWS CDK(for TypeScript)環境構築

- TypeScriptインストール

    ```markdown
    # TypeScriptインストール
    npm install -g typescript
    
    # TypeScriptインストール確認
    tsc --version
    ```

- AWS CDK v2インストール

    ```markdown
    # CDKのインストール
    npm install -g aws-cdk
    
    # CDKインストール確認
    cdk --version
    ```

### 4. AWS CLI認証プロファイル設定

#### 4-1. クレデンシャルを登録宇

- 2-4. アクセスキーの発行で作成したIAMユーザのアクセスキー/シークレットアクセスキーをcredentialに登録
- プロファイル名は任意

    ```markdown
    aws configure --profile <プロファイル名>
    ```

  - リージョンはap-northeast-1、outputはjsonでOK

#### 4-2. 一時的な認証情報を発行

- MFA が設定されているIAMユーザを使用する場合は `aws sts` コマンドを入力して、一時認証情報を取得する必要があります。

    ```markdown
    # 一時認証情報取得
    aws sts get-session-token \
    --serial-number <MFAデバイスのARN> \
    --token-code <MFAデバイスに表示される6桁番号> \
    --profile　<プロファイル名> ※4-1.で設定したもの
    
    # 実行結果
    {
        "Credentials": {
            "AccessKeyId": "XXXXXXXXXXXXXXXXXXX",
            "SecretAccessKey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
            "SessionToken": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
            "Expiration": "XXXXXXXXXXXXXXXXXXXXXX"
        }
    }
    ```

#### 4-3. 一時的な認証情報をプロファイルに設定

- .aws/credentialsとconfigファイルを編集
  - [xxx]は任意のプロファイル名　※4-1.で設定したものとは別もの

    ```markdown
    
    # credentials
    [xxx]
    aws_access_key_id = AccessKeyId          ※4-2.出力されたもの
    aws_secret_access_key = SecretAccessKey  ※4-2.出力されたもの)
    aws_session_token = SessionToken         ※4-2.出力されたもの)
    ```

    ```markdown
    # config
    [profile XXX]
    region = ap-northeast-1
    output = json
    ```

#### 4-4. 設定したプロファイルが有効か確認

- aws stsコマンドを打って値が返ってくるか確認

    ```markdown
    
    # プロファイルが有効か確認
    aws sts get-caller-identity --profile <プロファイル名> ※4-3.で設定したもの
    
    # 実行結果
    {
        "UserId": "XXXXXXXXXXXXXX",
        "Account": "XXXXXXXXXXXXX",
        "Arn": "arn:aws:iam::XXXXXXXXXXXX:XXXXXXXXXXXXXX
    }
    ```

### 5. AWS CDKサンプルアプリデプロイ

#### 5-1. サンプル用のフォルダ作成＆移動

- CDKアプリは空のディレクトリで作成する必要があるため、ディレクトリを新規で作成

  ```markdown
  mkdir -p ~/cdk-sample/ && cd ~/cdk-sample/
  ```

#### 5-2. AWS CDK デプロイ準備～デプロイ～スタック削除

- sample-appではSNSとSQSが作成されます。

- アプリの初期化

  ```markdown
  cdk init sample-app --language typescript
  ```

- ブートストラップ(cdkアプリのために必要な初期化やリソースをAWS環境にデプロイ)

  ```markdown
  cdk bootstrap --profile <プロファイル名>※4-3.で設定したもの
  ```

- 現環境とデプロイする環境の差分確認

  ```markdown
  cdk diff --profile <プロファイル名>※4-3.で設定したもの
  ```

- デプロイ

  ```markdown
  cdk deploy --profile <プロファイル名>※4-3.で設定したもの
  ```

- スタックの削除

  ```markdown
  cdk destroy --profile <プロファイル名>※4-3.で設定したもの
  ```

## **参考資料**

https://qiita.com/tmiki/items/517996dde5a8a7341aac

https://zenn.dev/akkie1030/articles/aws-cli-mfa-account

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_deny-ip.html

## **その他**

- 認証の有効期限が切れるたびに、毎回設定するのは手間なのでシェルスクリプトを組むのがよさそうです
  - [**AWS CLIのMFA認証を簡単するシェルスクリプト**](https://qiita.com/mizue/items/8292a1ea39d31a0d43bf)

## **おわりに・まとめ**

- AWS CDKの環境構築について今回まとめてみました。
- 読みづらい箇所もあるかもしれませんが、最後まで読んでいただいてありがとうございます。今後もCDKの学習中にまとめたいネタがあれば記事にしてみたいと思います