AWS CDKとPythonでの開発環境をDevcontainerで作成

AWS CDKとPythonでの開発環境をDevcontainerで作成

Clock Icon2024.09.25

はじめに

データ事業本部ビッグデータチームのyosh-kです。
今回は件名の通り、プロジェクトの開発環境をDevcontainerを用いて作成してみたいと思います。

前提

基本的には以下のブログを土台として使用します。今回はTypeScriptでAWS CDKを実装し、AWS GlueやAWS LambdaのScriptをPythonで実装したいので、それに合わせた設定や、拡張機能などを追加で実装していきたいと思います。
https://dev.classmethod.jp/articles/devcontainer-python-aws-cdk-sls-etc/

  • Python
  • Node.js
  • AWS CDK
  • Git

事前準備

VSCodeのインストールと、Devcontainerの拡張機能をインストールしておきます。

https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers

Gitのセットアップも実施します。
https://prog-8.com/docs/git-env

AWS CLIのセットアップも実施します。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-configure.html

実装

実装コードはリポジトリにもありますので、ご参照いただければと思います。

https://github.com/cm-yoshikikasama/blog_code/tree/main/.devcontainer

.devcontainer/devcontainer.json
{
    "name": "My DevContainer", 
    "build": {
        "dockerfile": "Dockerfile"
    },
    "workspaceFolder": "/workspace", 
    "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached",
    "mounts": [
        // AWSのプロファイルディレクトリをマウント
        "source=${localEnv:HOME}/.aws,target=/root/.aws,type=bind,consistency=cached",
    ],
   "postCreateCommand": [
        "bash",
        "-c",
        "pip install -r requirements.txt && npm install"
    ],
    "customizations": {
      "vscode": {
        "extensions": [
          // CloudFormationテンプレートの構文チェック
          "kddejong.vscode-cfn-lint",
          // AWSの開発ツールキット
          "amazonwebservices.aws-toolkit-vscode",
          // Pythonコードのリンターとフォーマッター
          "charliermarsh.ruff",
          // Markdownのリンター
          "davidanson.vscode-markdownlint",
          // JavaScriptとTypeScriptのリンター
          "dbaeumer.vscode-eslint",
          // Gitの履歴を視覚化
          "donjayamanne.githistory",
          // Gitの機能拡張
          "eamodio.gitlens",
          // コードフォーマッター
          "esbenp.prettier-vscode",
          // シェルスクリプトのフォーマッター
          "foxundermoon.shell-format",
          // 図表作成ツール
          "hediet.vscode-drawio",
          // CSVファイルの編集
          "janisdd.vscode-edit-csv",
          // Markdownプレゼンテーションツール
          "marp-team.marp-vscode",
          // CSVファイルの表示改善
          "mechatroner.rainbow-csv",
          // Dockerサポート
          "ms-azuretools.vscode-docker",
          // 日本語言語パック
          "ms-ceintl.vscode-language-pack-ja",
          // Pythonデバッガー
          "ms-python.debugpy",
          // Python言語サポート
          "ms-python.python",
          // Python言語サーバー
          "ms-python.vscode-pylance",
          // YAML言語サポート
          "redhat.vscode-yaml",
          // SQLフォーマッター
          "renesaarsoo.sql-formatter-vsc",
          // スペルチェッカー
          "streetsidesoftware.code-spell-checker",
          // シェルスクリプトの静的解析ツール
          "timonwong.shellcheck",
          // ファイルアイコンテーマ
          "vscode-icons-team.vscode-icons",
          // Markdown機能拡張
          "yzhang.markdown-all-in-one"
        ],
        "settings": {
          // Gitの自動更新を有効化
          "git.autorefresh": true,
          // VSCodeのカラーテーマ設定
          "workbench.colorTheme": "Visual Studio Dark",
          // Draw.io拡張の設定
          "hediet.vscode-drawio.resizeImages": null,
          // セマンティックトークンの色のカスタマイズ
          "editor.semanticTokenColorCustomizations": {},
          // 保存時の自動フォーマットを無効化(言語ごとに設定)
          "editor.formatOnSave": false,
          // Pythonのデフォルトインタープリターパス
          "python.defaultInterpreterPath": "/opt/venv/bin/python",
          "python.pythonPath": "/opt/venv/bin/python",
          // Python固有の設定
          "[python]": {
              "editor.defaultFormatter": "charliermarsh.ruff",
              "editor.formatOnType": true,
              "editor.formatOnSave": true
          },
          // Markdown固有の設定
          "[markdown]": {
              "editor.defaultFormatter": "yzhang.markdown-all-in-one"
          },
          // SQL固有の設定
          "[sql]": {
              "editor.formatOnSave": false,
              "editor.defaultFormatter": "ReneSaarsoo.sql-formatter-vsc"
          },
          // JavaScript固有の設定
          "[javascript]": {
              "editor.defaultFormatter": "esbenp.prettier-vscode",
              "editor.formatOnSave": true
          },
          // TypeScript固有の設定
          "[typescript]": {
              "editor.defaultFormatter": "esbenp.prettier-vscode",
              "editor.formatOnSave": true
          },
          // シェルスクリプト固有の設定
          "[shellscript]": {
              "editor.defaultFormatter": "foxundermoon.shell-format",
              "editor.formatOnSave": true
          },
          // YAML固有の設定
          "[yaml]": {
              "editor.defaultFormatter": "redhat.vscode-yaml",
              "editor.insertSpaces": true,
              "editor.tabSize": 2,
              "cfnLint.validate": true,
              "cfnLint.path": "/opt/venv/bin/cfn-lint"    
          },
          // フォントリガチャを無効化
          "editor.fontLigatures": false,
          // ワークスペースの信頼設定を無効化
          "security.workspace.trust.enabled": false,
          // YAMLのカスタムタグ設定(CloudFormation用)
          "yaml.customTags": [
              "!And", "!And sequence", "!If", "!If sequence",
              "!Not", "!Not sequence", "!Equals", "!Equals sequence",
              "!Or", "!Or sequence", "!FindInMap", "!FindInMap sequence",
              "!Base64", "!Join", "!Join sequence", "!Cidr",
              "!Ref", "!Sub", "!Sub sequence", "!GetAtt",
              "!GetAZs", "!ImportValue", "!ImportValue sequence",
              "!Select", "!Select sequence", "!Split", "!Split sequence"
          ],
          // AWSツールキットのプロンプト抑制設定
          "aws.suppressPrompts": {
              "regionAddAutomatically": true
          },
          // ファイル末尾に改行を挿入
          "files.insertFinalNewline": true,
          // ファイルアイコンテーマの設定
          "workbench.iconTheme": "vscode-icons",
          // TypeScriptのファイル移動時のインポート更新設定
          "typescript.updateImportsOnFileMove.enabled": "always"
        }
      }
    }
}

参考ブログから変更した点としては、以下になります。

  • requirements.txtpackage.jsonからpip installnpm installコマンドでそれぞれのライブラリをinstallしています。
  • customizations.vscode.extensionsでインストールする拡張機能を定義。PythonやJavaScriptのフォーマッターや、yaml、シェルスクリプト、csvなど、プロジェクトで実装する上でよく使っている拡張機能を定義しています。
  • customizations.vscode.settingsでVS Code上の設定を定義しています。
.devcontainer/Dockerfile
# syntax=docker/dockerfile:1
FROM debian:bookworm-slim

# バージョンの指定
ARG PYTHON_VERSION=3.12.0
ARG NODE_VERSION=20.17.0
ARG AWS_CDK_VERSION=2.160.0
ARG TARGETARCH

# 環境変数の設定
ENV VIRTUAL_ENV=/opt/venv
ENV DEBIAN_FRONTEND=noninteractive
ENV PATH="/usr/local/bin:$VIRTUAL_ENV/bin:$PATH"

# APTキャッシュの設定
RUN rm -f /etc/apt/apt.conf.d/docker-clean; \
    echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache

# 基本的なシステムパッケージのインストール
RUN apt-get update && apt-get install -y \
    curl \
    git \
    build-essential \
    zlib1g-dev \
    libncurses5-dev \
    libgdbm-dev \
    libnss3-dev \
    libssl-dev \
    libsqlite3-dev \
    libreadline-dev \
    libffi-dev \
    libbz2-dev \
    bash \
    jq \
    unzip \
    tree \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Pythonのインストール
RUN --mount=type=cache,target=/root/.cache/pip \
    curl -O https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz \
    && tar -xf Python-${PYTHON_VERSION}.tar.xz -C /tmp \
    && cd /tmp/Python-${PYTHON_VERSION} \
    && ./configure --enable-optimizations \
    && make -j $(nproc) \
    && make altinstall \
    && cd / \
    && rm -f Python-${PYTHON_VERSION}.tar.xz \
    && rm -rf /tmp/Python-${PYTHON_VERSION} 

# 仮想環境の作成とpipのアップグレード
RUN --mount=type=cache,target=/root/.cache/pip \
    python${PYTHON_VERSION%.*} -m venv $VIRTUAL_ENV \
    && . $VIRTUAL_ENV/bin/activate \
    && pip install --upgrade pip

# Node.jsのインストール
RUN case ${TARGETARCH} in \
        "amd64") NODE_ARCH="x64" ;; \
        "arm64") NODE_ARCH="arm64" ;; \
        *) echo "Unsupported architecture: ${TARGETARCH}" >&2; exit 1 ;; \
    esac && \
    curl -fsSL https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${NODE_ARCH}.tar.xz | tar -xJ -C /usr/local --strip-components=1 \
    && npm install -g npm@latest

# 環境変数の設定
ENV PATH="/usr/local/bin:$VIRTUAL_ENV/bin:$PATH"

# AWS CLIのインストール
RUN case ${TARGETARCH} in \
        "amd64") \
            AWS_CLI_URL="https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" ;; \
        "arm64") \
            AWS_CLI_URL="https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" ;; \
        *) \
            echo "Unsupported architecture: ${TARGETARCH}" >&2; \
            exit 1 ;; \
    esac && \
    curl "${AWS_CLI_URL}" -o "awscliv2.zip" && \
    unzip awscliv2.zip && \
    ./aws/install && \
    rm -rf aws awscliv2.zip

# AWS CDKのインストール
RUN --mount=type=cache,target=/root/.npm,sharing=locked \
    npm install -g aws-cdk@${AWS_CDK_VERSION}

# 作業ディレクトリの設定
WORKDIR /workspace

# デフォルトのシェルをbashに設定
SHELL ["/bin/bash", "-c"]

RUN git config --global --add safe.directory /workspace

# コンテナ起動時のデフォルトコマンド
CMD ["/bin/bash"]

参考にしたブログからの修正点としては、PythonやNodeのバージョンを変更した際に対応できるようにcurlでxzファイルをdownloadするようにしたことです。

実行結果

ローカルでリポジトリを開いたタイミングで右下に「コンテナーで再度開く」というポップアップが表示されるので、そちらを押下して、devcontainerを起動します。
Screenshot 2024-09-24 at 21.46.35

問題なく起動に成功しました。
Screenshot 2024-09-24 at 21.49.41

拡張機能もインストールできています。
Screenshot 2024-09-24 at 21.50.04

Python、node、npm, aws cli、cdkもインストールできていることを確認できました。
Screenshot 2024-09-24 at 21.51.10

Git Push確認のため、READMEを修正します。
Screenshot 2024-09-24 at 22.57.01

こちらも正常にgit add、commit、pushコマンドまで成功しました。
Screenshot 2024-09-24 at 22.57.49

注意点として、まれにソースコード修正後にソース管理に反映されない場合があります。その際は画像赤枠の更新ボタンを押下することで変更が確認できるようになります。
Screenshot 2024-09-25 at 7.10.00

最後に

これでプロジェクトの開発環境を統一できたら良いなと思います。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.