カテゴリー: tech

  • Git: 特定のファイルだけを別のブランチにマージする方法

    Git: 特定のファイルだけを別のブランチにマージする方法

    Git: 特定のファイルだけを別のブランチにマージする方法

    Gitを使用していると、あるブランチの特定のファイルだけを別のブランチにマージしたい場合があります。この記事では、そのような状況で役立つGitコマンドについて説明します。

    ステップバイステップガイド

    1. まず、マージ先のブランチ(例: developブランチ)をローカルに最新の状態に更新します。

      git checkout develop git pull origin develop
    2. 次に、新しいブランチを作成し、そのブランチに切り替えます。

      git checkout -b merge-specific-file
    3. マージ元のブランチ(例: features/new-featureブランチ)から特定のファイル(例: path/to/file.txt)を現在のブランチにコピーします。

      git checkout features/new-feature -- path/to/file.txt
    4. 変更をステージングしてコミットします。

      git add path/to/file.txt git commit -m "Merge specific file from features/new-feature"
    5. 新しいブランチをリモートリポジトリにプッシュします。

      git push -u origin merge-specific-file
    6. GitHubやGitLabなどのWebインターフェースを使用して、merge-specific-fileブランチからdevelopブランチへのプルリクエストを作成します。

    7. プルリクエストがレビューされ、承認されたら、マージを完了します。

    8. 最後に、ローカルのdevelopブランチを更新します。

      git checkout develop git pull origin develop

    以上のステップにより、特定のブランチの特定のファイルのみを別のブランチにマージするためのプルリクエストを作成できます。

    まとめ

    Gitの柔軟性により、様々な状況に対応できます。特定のファイルだけをマージする必要がある場合は、上記のステップに従うことで、簡単にその目的を達成できます。このテクニックを活用して、Gitワークフローをさらに効率化しましょう。

  • 【Athena】タイムスタンプと文字列の比較で起こるTYPE_MISMATCHエラーの解決方法

    【Athena】タイムスタンプと文字列の比較で起こるTYPE_MISMATCHエラーの解決方法

    【Athena】タイムスタンプと文字列の比較で起こるTYPE_MISMATCHエラーの解決方法

    1. はじめに

    データ分析においてAthenaは非常に強力なツールですが、クエリを書く際にデータ型の不一致によるエラーに遭遇することがあります。特にタイムスタンプと文字列の比較は、TYPE_MISMATCHエラーを引き起こしやすい事例の一つです。本記事では、このエラーの原因と解決方法を詳しく説明します。

    2. TYPE_MISMATCHエラーとは

    TYPE_MISMATCHエラーは、比較や演算を行う際に、データ型が一致しない場合に発生します。例えば、以下のようなエラーメッセージが表示されます。

    TYPE_MISMATCH: line 18:56: Cannot check if timestamp(3) with time zone is BETWEEN varchar(10) and timestamp(3) with time zone

    このメッセージは、タイムスタンプ型の値と文字列型の値を比較しようとしたために、エラーが発生したことを示しています。

    3. タイムスタンプと文字列の比較によるTYPE_MISMATCHエラー

    Athenaでは、タイムスタンプ型と文字列型は異なるデータ型として扱われます。タイムスタンプ型は日付と時刻を含む値を表現するのに対し、文字列型は文字の並びを表現します。そのため、これらの型を直接比較することはできません。

    以下は、タイムスタンプと文字列を比較しようとしてTYPE_MISMATCHエラーが発生する例です。

    SELECT * FROM table WHERE from_unixtime(timestamp/1000, 'Asia/Tokyo') BETWEEN '2024-03-01' AND now();

    ここでは、from_unixtime関数の結果がタイムスタンプ型なのに対し、'2024-03-01'は文字列型になっているため、比較ができずにエラーが発生しています。

    4. エラーを解決する方法

    TYPE_MISMATCHエラーを解決するには、比較する値のデータ型を一致させる必要があります。上記の例では、文字列をタイムスタンプ型に変換することで、エラーを解消できます。

    SELECT * FROM table WHERE from_unixtime(timestamp/1000, 'Asia/Tokyo') BETWEEN timestamp '2024-03-01 00:00:00' AND now();

    ここでは、timestampキーワードを使って文字列'2024-03-01 00:00:00'をタイムスタンプ型に明示的に変換しています。これにより、from_unixtime関数の結果と比較可能になり、エラーが解決されます。

    5. 他のTYPE_MISMATCHエラーの事例と対処法

    タイムスタンプと文字列の比較以外にも、整数型と文字列型、日付型と文字列型など、異なる型同士の比較によってTYPE_MISMATCHエラーが発生することがあります。

    例えば、整数型の値と文字列型の値を比較しようとすると、以下のようなエラーが発生します。

    TYPE_MISMATCH: line 3:22: Cannot check if integer is BETWEEN varchar(1) and varchar(1)

    この場合も、文字列を整数型に変換することでエラーを解決できます。

    SELECT * FROM table WHERE int_column BETWEEN cast('1' as integer) AND cast('100' as integer);

    同様に、日付型と文字列型の比較では、文字列を日付型に変換する必要があります。

    SELECT * FROM table WHERE date_column BETWEEN date '2024-03-01' AND date '2024-03-31';

    6. Athenaを使う上での型に関するベストプラクティス

    Athenaを効果的に使うには、データ型に関するいくつかのベストプラクティスを守ることが重要です。

    • 一貫したデータ型の使用: テーブル内の各列には、適切なデータ型を設定し、一貫して使用します。
    • 比較や演算前の型チェック: クエリを実行する前に、比較や演算に使用する値のデータ型を確認します。
    • 明示的な型変換の実施: 必要に応じて、cast関数やtimestampキーワードなどを使って明示的に型変換を行います。

    これらのプラクティスを守ることで、TYPE_MISMATCHエラーを未然に防ぎ、正しいクエリを書くことができます。

    7. まとめ

    本記事では、Athenaでタイムスタンプと文字列を比較する際に発生するTYPE_MISMATCHエラーについて説明しました。このエラーは、異なるデータ型同士を比較しようとすることで発生します。解決方法は、文字列をタイムスタンプ型に変換することです。

    また、整数型と文字列型、日付型と文字列型の比較でも同様のエラーが起こりうるため、適切な型変換が必要です。Athenaを使う際は、一貫したデータ型の使用、比較前の型チェック、明示的な型変換を心がけましょう。

    これらのポイントを理解し、実践することで、TYPE_MISMATCHエラーを避け、Athenaをより効果的にデータ分析に活用できるようになります。

    8. 参考資料

    以上が、WordPressのエディタにコピーしやすい形式で書き直した技術ブログ記事です。HTML タグを使ってマークアップしているので、そのままコピー&ペーストすれば、WordPressの記事として利用できるはずです。必要に応じて、画像やその他の要素を追加してカスタマイズしてください。

  • AWS S3とCloudFrontを使ってシングルページアプリケーション(SPA)を公開する

    AWS S3とCloudFrontを使ってシングルページアプリケーション(SPA)を公開する

    AWSを使用してウェブサイトを公開する際、S3とCloudFrontは非常に人気のある選択肢です。これらのサービスは、静的コンテンツの配信に優れており、シングルページアプリケーション(SPA)のようなモダンなウェブアプリケーションのホスティングに適しています。しかし、S3の静的ウェブサイトホスティングとCloudFrontを組み合わせる際には、いくつかの設定を理解しておく必要があります。

    S3の静的ウェブサイトホスティング

    Amazon S3は、静的ウェブサイトホスティングを簡単に行えるようにサポートしています。これにより、HTML、CSS、JavaScriptファイルなどの静的ファイルを保存し、ウェブサイトとして公開できます。S3バケットで静的ウェブサイトホスティングを有効にすると、デフォルトドキュメント(通常はindex.html)へのリクエストをサポートし、特定のパスが指定された場合に自動的にそのファイルを返すようになります。これはSPAの開発において重要な機能です。なぜなら、クライアントサイドでのルーティングを使って、異なるURLが同一のHTMLファイルによって処理されることが多いからです。

    例: http://example-bucket.s3-website-region.amazonaws.com/about のリクエストは、about ディレクトリにファイルが存在しなくても、自動的に index.html を返します。

    CloudFrontとS3の組み合わせ

    CloudFrontは、AWSが提供する高速コンテンツ配信ネットワーク(CDN)サービスで、世界中のエッジロケーションからコンテンツを迅速に配信できます。S3バケットをオリジンとしてCloudFrontディストリビューションを設定することで、ウェブサイトのロード時間を短縮し、セキュリティを強化することが可能です。

    しかし、CloudFrontを介してSPAを公開する際には、S3の静的ウェブサイトホスティングとは異なる挙動に注意する必要があります。特に、存在しないパスへのリクエストが来た場合、CloudFrontはデフォルトでindex.htmlにリダイレクトせず、404エラーを返すため、SPAのクライアントサイドルーティングが期待通りに機能しません。

    解決策: カスタムエラーレスポンスの設定

    この問題を解決するには、CloudFrontディストリビューションのカスタムエラーレスポンス設定を使用します。具体的には、404(NotFound)や403(Forbidden)のエラーが発生した場合に、index.htmlページを返し、HTTPステータスコード200を使用してレスポンスするように設定します。これにより、リクエストされたパスに対応するファイルがS3バケットに存在しない場合でも、クライアントサイドのJavaScriptがルーティングを処理できるようになります。

    AWS CDKを使用してこの設定を実装する例は以下の通りです。

    const distribution = new cloudfront.Distribution(this, 'SiteDistribution', {
      // その他の設定...
      errorResponses: [
        {
          httpStatus: 404,
          responseHttpStatus: 200,
          responsePagePath: '/index.html',
          ttl: Duration.seconds(0),
        },
        {
          httpStatus: 403,
          responseHttpStatus: 200,
          responsePagePath: '/index.html',
          ttl: Duration.seconds(0),
        }
      ],
    });
    

    この設定により、CloudFrontはS3と同様の挙動をするようになり、SPAのホスティングに適した環境を提供します。

    結論

    AWS S3とCloudFrontは、静的コンテンツやSPAの公開に強力な選択肢です。ただし、CloudFrontを介してSPAを公開する場合には、カスタムエラーレスポンスの設定を適切に行うことで、クライアントサイドルーティングを正しく機能させることが可能になります。この設定により、ユーザーにとってより快適なウェブサイト体験を提供することができます。

  • Ubuntuコンテナにおける利用可能なPHPの version について

    Ubuntuコンテナにおける利用可能なPHPの version について

    背景

    PHPは広く使用されているオープンソースの汎用スクリプト言語で、特にWeb開発に適しています。Dockerコンテナ内で異なるバージョンのPHPが利用できるかどうかは、開発やデプロイのプロセスに大きな影響を与える可能性があります。

    最近、異なるUbuntuコンテナでインストール可能なPHPのバージョンを深く掘り下げる必要がある状況に遭遇しました。

    発見プロセス

    当初、ubuntu:18.04ベースのDockerコンテナにPHPバージョン7.3以上をインストールしようとしました。ppa:ondrej/php を追加しても、7.2以上のバージョンのPHPをインストールすることができませんでした。

    私のプロジェクトの多くは、様々な依存関係やそれ以降のPHPバージョンで導入された機能により、少なくともPHP 7.3が必要だったため、この制限は大きな課題となりました。

    Ubuntu 18.04での実験

    ubuntu:18.04コンテナを使い、以下のコマンドを活用してPHP 7.3と8.0のインストールを試みました

    sudo add-apt-repository ppa:ondrej/php
    sudo apt-get update
    sudo apt-get install php7.3

    以下の様なエラーになりました

    E: Unable to locate package php7.3
    E: Couldn't find any package by glob 'php7.3'
    E: Couldn't find any package by regex 'php7.3'

    Ubuntu 20.04への乗り換え

    ubuntu:18.04で直面した課題に促され、Dockerコンテナをubuntu:20.04に切り替えることにしました。

    同じ手順を適用したところ、PHPバージョン7.3、7.4、そしてPHP 8.0まで問題なくインストールできました。

    分析

    このことにより、ベースイメージが利用可能なPHP の version に影響することが明確になりました。Ubuntu 18.04は古いLTSリリースであるため、時には複雑な設定を追加しなければ、7.2以上のPHPバージョンをネイティブにサポートしていません。

    対照的に、最新のLTSバージョンであるUbuntu 20.04は、ソフトウェアの互換性と可用性の進歩を反映して、新しいPHPバージョンをすぐにサポートしています。

    結論

    Docker環境でPHPを扱う開発者やDevOpsエンジニアにとって、ベースコンテナイメージとソフトウェアパッケージの可用性の関係を理解することは非常に重要です。

    PHPのバージョン7.3以降を使用する予定であれば、ubuntu:20.04コンテナを選択するのが、より簡単で効率的な選択かと思います。

    推奨事項

    • プロジェクトのセットアップを開始する前に、選択したUbuntuコンテナのバージョンとのPHPバージョンの互換性を必ず確認してください。
    • 新しいPHPバージョンのサポートが必要な場合は、Dockerコンテナを新しいUbuntuバージョンにアップグレードすることを検討してください。
    • UbuntuのリリースでサポートされているPHPのバージョンについて常に情報を入手し、スムーズな開発とデプロイを行いましょう。

  • Understanding PHP Version Availability in Ubuntu Containers

    Understanding PHP Version Availability in Ubuntu Containers

    Introduction

    When working with Docker containers based on Ubuntu, one might encounter limitations regarding the availability of PHP versions. This blog post explores these limitations, specifically between Ubuntu 18.04 and Ubuntu 20.04 containers, and provides insights into how you can successfully manage PHP installations within these environments.

    Background

    PHP is a widely-used open-source general-purpose scripting language that is especially suited for web development. The availability of different PHP versions in Docker containers can significantly affect your development and deployment processes. Recently, I encountered a situation that necessitated a deeper dive into which PHP versions are installable on different Ubuntu containers.

    The Discovery Process

    Initially, I attempted to install PHP versions 7.3 and above in a Docker container based on ubuntu:18.04. Despite my efforts and even after adding the popular Ondřej Surý PPA, I was unable to install PHP versions higher than 7.2. This limitation posed a significant challenge, as many of my projects required at least PHP 7.3 due to various dependencies and features introduced in later PHP versions.

    Experimenting with Ubuntu 18.04

    Using the ubuntu:18.04 container, I attempted to install PHP 7.3 and 8.0 by leveraging the following commands:

    sudo add-apt-repository ppa:ondrej/php
    sudo apt-get update
    sudo apt-get install php7.3

    However, I encountered the following issue:

    E: Unable to locate package php7.3
    E: Couldn't find any package by glob 'php7.3'
    E: Couldn't find any package by regex 'php7.3'

    Switching to Ubuntu 20.04

    Prompted by the challenges faced with ubuntu:18.04, I decided to switch my Docker container to ubuntu:20.04. After applying the same steps, I was pleasantly surprised to find that I could successfully install PHP versions 7.3, 7.4, and even PHP 8.0 without any issues.

    Analysis

    This experience highlighted a crucial aspect of working with Docker and Ubuntu containers – the base image significantly impacts the availability of software packages. Ubuntu 18.04, being an older LTS release, does not natively support PHP versions higher than 7.2 without additional, sometimes complex, configurations. In contrast, Ubuntu 20.04, a more recent LTS version, has out-of-the-box support for newer PHP versions, reflecting the advancements in software compatibility and availability.

    Conclusion

    For developers and DevOps engineers working with PHP in Docker environments, understanding the relationship between the base container image and software package availability is crucial. If you’re planning to use PHP versions 7.3 or newer, opting for an ubuntu:20.04 container would be the more straightforward and efficient choice.

    This exploration not only solved my immediate problem but also served as a valuable reminder of the importance of keeping both software and knowledge up to date. I hope sharing this experience helps others navigate similar challenges in their development workflows.

    Recommendations

    • Always check the PHP version compatibility with your chosen Ubuntu container version before starting your project setup.
    • Consider upgrading your Docker container to a newer Ubuntu version if you require support for newer PHP versions.
    • Stay informed about the PHP versions supported by Ubuntu releases to ensure smooth development and deployment processes.
  • MSALを使ってOneDriveにユーザー代理でアクセスする

    MSALを使ってOneDriveにユーザー代理でアクセスする

    はじめに

    Microsoft Graph APIを使用すると、Microsoft 365のデータにアクセスできます。この記事では、Microsoft Authentication Library (MSAL) を使用してOneDriveにユーザー代理でアクセスする方法と、遭遇したいくつかの問題の解決方法を紹介します。

    OneDriveへのアクセス

    MSALを用いたアクセストークンの取得

    まず、MSALを使用してアクセストークンを取得します。以下の例では、ユーザーネームとパスワードフローを用いています。

    import msal
    
    def acquire_token_by_username_password():
        client_id = "--クライアントID--"
        tenant = "--テナント名またはID--"
    
        authority_url = f'https://login.microsoftonline.com/{tenant}'
        app = msal.PublicClientApplication(client_id=client_id, authority=authority_url)
        return app.acquire_token_by_username_password(
            username=settings.get('user_credentials', 'username'),
            password=settings.get('user_credentials', 'password'),
            scopes=["https://graph.microsoft.com/.default"])
    
    
    

    GraphClientを使用してOneDriveのデータにアクセス

    トークンを取得したら、GraphClientを使用してOneDriveにアクセスします。

    from office365.graph_client import GraphClient
    
    client = GraphClient(acquire_token_by_username_password)
    drive_items = client.me.drive.shared_with_me().execute_query()
    for item in drive_items:
        print(f"Drive Item url: {item.web_url}")
    
    
    

    遭遇した問題とその解決方法

    認証エラーの解決

    認証時にinvalid_clientというエラーが発生した場合、クライアント秘密キーまたは証明書が正しくない可能性があります。ConfidentialClientApplicationクラスを使用して、証明書を用いた認証を試みます。

    import os
    import msal
    
    cert_path = '/path/to/your/certificate.pem'
    with open(cert_path, 'r') as f:
        private_key = f.read().strip()
    
    authority_url = f'https://login.microsoftonline.com/{tenant}'
    app = msal.ConfidentialClientApplication(
        client_id=client_id,
        client_credential={"private_key": private_key, "thumbprint": thumbprint},
        authority=authority_url)
    
    

    タイプエラーの解決

    TypeError: 'dict' object is not callable というエラーに遭遇した場合、GraphClient コンストラクタがコールバック引数を期待しているため、辞書を直接渡すのではなく、トークンを返す関数を渡す必要があります。

    def acquire_token():
        # トークン取得のコード
        return msal_app.acquire_token_on_behalf_of(user_assertion=id_token, scopes=["https://graph.microsoft.com/.default"])
    
    graph_client = GraphClient(acquire_token)
    

    まとめ

    この記事では、MSALを使用してOneDriveにユーザー代理でアクセスする方法と、遭遇した問題の解決策を紹介しました。Microsoft Graph APIは強力であり、これを使用することでMicrosoft 365のさまざまなサービスと連携できます。

  • AWS S3バケットを安全に空にする方法:実践ガイド

    AWS S3バケットを安全に空にする方法:実践ガイド

    記事の導入

    はじめに、AWS S3バケットの内容を削除する必要がある一般的なシナリオを紹介します。例えば、プロジェクトの終了、リソースの再配置、テストデータのクリーンアップなどです。読者がこの記事を読むべき理由を説明し、AWS CLIの基本的な使用方法について簡単に触れます。

    必要なツールと前提条件

    AWS CLIのインストールと設定方法を説明し、AWSアカウントの適切な権限設定についても触れます。これには、S3バケットへのアクセス権限が含まれます。

    スクリプトの解説

    次に、汎用的なスクリプトを紹介します。まずは、スクリプト全体を示し、その後で重要な部分を分解して説明します。

    スクリプト

    #!/bin/bash
    
    # バケット名を引数から取得
    BUCKET_NAME="$1"
    
    if [ -z "$BUCKET_NAME" ]; then
      echo "バケット名が指定されていません。"
      exit 1
    fi
    
    # バケットの中身をリストアップ
    aws s3api list-objects --bucket "$BUCKET_NAME" --query 'Contents[].Key' --output text | while read -r line; do
      aws s3api delete-object --bucket "$BUCKET_NAME" --key "$line"
    done
    
    echo "$BUCKET_NAME の中身を全て削除しました。"
    

    スクリプトのポイント

    • バケット名の動的指定:バケット名をスクリプトの引数から取得し、汎用性を高めています。
    • 安全性の向上:バケット名が指定されていない場合にはエラーメッセージを表示し、スクリプトを終了させます。
    • 効率的な処理aws s3api list-objects コマンドを使用してオブジェクトのキーを取得し、それぞれに対して削除コマンドを実行します。

    終わりに

    スクリプトの使用方法と実際の使用例を紹介し、注意点やバケット削除のセキュリティ面での考慮事項を解説します。また、AWSの他のサービスとの連携や、このスクリプトを自動化ツールに組み込む方法についても触れると良いでしょう。

  • GitHubでフォークしたリポジトリをオリジナルと同期する

    GitHubでフォークしたリポジトリをオリジナルと同期する

    GitHubで他のプロジェクトをフォークすることは、そのプロジェクトに貢献したり、自分のプロジェクトでそのコードを利用したりする際の一般的なアプローチです。しかし、時間が経過すると、フォークしたリポジトリはオリジナルのリポジトリから遅れをとってしまうことがあります。この記事では、フォークしたリポジトリをオリジナルのリポジトリと同期する方法を詳しく解説します。

    ステップ1: オリジナルリポジトリを追加

    最初に行うべきことは、オリジナルリポジトリをあなたのローカルリポジトリのリモートとして追加することです。これにより、オリジナルリポジトリの変更をフェッチできるようになります。

    git remote add upstream git@github.com:aws-samples/aws-cdk-examples.git

    ステップ2: オリジナルリポジトリの変更をフェッチ

    次に、upstreamリモートから最新の変更をフェッチします。これは、オリジナルリポジトリの最新のコミットをローカルに取得する操作です。

    git fetch upstream

    ステップ3: ローカルのブランチにチェックアウト

    オリジナルリポジトリの変更をマージする前に、同期したいローカルのブランチにチェックアウトします。

    git checkout master

    ステップ4: オリジナルの変更をマージ

    upstreamからフェッチした変更をローカルのブランチ(この例ではmaster)にマージします。

    git merge upstream/master

    ステップ5: 変更をGitHubリポジトリにプッシュ

    最後に、ローカルの変更をGitHubリポジトリにプッシュします。これにより、オリジナルリポジトリの最新の変更があなたのフォークにも反映されます。

    git push origin master

    これらの手順を実行することで、フォークしたリポジトリはオリジナルリポジトリの最新の状態と同期されます。これにより、常に最新のコードで作業を続けることができます。

    このプロセスは、GitHub上でのオープンソースプロジェクトへの貢献や、最新の変更を自分のプロジェクトに取り込みたい場合に非常に役立ちます。是非、この手順を自分のワークフローに取り入れてみてください。

  • Handling Deprecated Types in AWS CDK: A Case Study on PRIVATE_WITH_NAT

    Handling Deprecated Types in AWS CDK: A Case Study on PRIVATE_WITH_NAT

    Introduction

    In the fast-evolving landscape of cloud infrastructure, keeping our Infrastructure as Code (IaC) up to date is crucial for maintaining efficiency, security, and cost-effectiveness. Recently, I encountered a scenario where a type I commonly used in AWS Cloud Development Kit (CDK) was marked as deprecated, leading to confusion due to the lack of updated documentation. This blog post aims to share my journey of identifying the issue, understanding the implications, and finding a workaround.

    The Challenge: Unexpected Deprecation

    While defining a Virtual Private Cloud (VPC) using AWS CDK in TypeScript, I noticed that the SubnetType.PRIVATE_WITH_NAT was unexpectedly marked as “deprecated.” Here’s a snippet of the code that led to the discovery:

    import { Vpc, SubnetType } from '@aws-cdk/aws-ec2';
    
    const vpc = new Vpc(this, "Vpc", {
      subnetConfiguration: [
        { name: "Public", subnetType: SubnetType.PUBLIC },
        { name: "Private", subnetType: SubnetType.PRIVATE_WITH_NAT },
        { name: "Isolated", subnetType: SubnetType.PRIVATE_ISOLATED }
      ]
    });
    

    Despite this, the official documentation had no mention of the deprecation, leaving me in a state of confusion about the correct approach to defining private subnets with NAT.

    Investigating the Issue

    To understand why PRIVATE_WITH_NAT was marked as deprecated and to find a solution, I embarked on a deep dive into the CDK source code, issue trackers, and the AWS documentation for updates. My setup involved using CDK CLI version 2.60 on MacOS 12.5, with Node.js version 14.17 and TypeScript version 4.9.4.

    Solution: Adapting to the Changes

    After thorough research, I learned that AWS CDK evolves rapidly, and certain types or methods can become deprecated as part of this evolution. The deprecation of PRIVATE_WITH_NAT was a move towards a more granular and flexible way of defining subnet configurations, allowing for better control over the networking architecture in AWS.

    Updated Approach

    To adapt to the change, I revised my VPC definition to use the updated subnet types and configurations, ensuring that my infrastructure code remained functional and aligned with the best practices. Here’s an updated snippet reflecting the changes:

    import { Vpc, SubnetType } from '@aws-cdk/aws-ec2';
    
    const vpc = new Vpc(this, "Vpc", {
      subnetConfiguration: [
        { name: "Public", subnetType: SubnetType.PUBLIC },
        // Adjusted to use the new method or type for private subnets with NAT
        { name: "Private", subnetType: SubnetType.PRIVATE },
        { name: "Isolated", subnetType: SubnetType.PRIVATE_ISOLATED }
      ]
    });
    

    Note: This snippet assumes a generic update and might need adjustment based on the specific alternatives provided by AWS CDK at the time of your implementation.

    Conclusion

    Dealing with deprecations in IaC can be challenging, especially when documentation does not immediately reflect these changes. However, it also presents an opportunity to dive deeper into the tools we use, understanding their internals and staying ahead of the curve. Through this experience, I’ve learned the importance of regularly reviewing the release notes of the tools and libraries in our stack, participating in community forums, and testing our infrastructure regularly to catch such issues early.

    I hope this case study helps other developers navigate similar challenges and encourages an active engagement with the evolving cloud ecosystem.

  • AWSアカウント作成とMFA設定: 安全なクラウド環境構築のステップバイステップガイド

    AWSアカウント作成とMFA設定: 安全なクラウド環境構築のステップバイステップガイド

    はじめに

    AWSアカウントの作成からMFA(多要素認証)の設定まで、初心者でも簡単にフォローできる手順をご紹介します。正しいセットアップを行うことで、AWS環境を安全に保ちながら、EC2、S3などのサービスをフル活用することができます。

    MFAの設定とアカウントの利用開始

    セキュリティを強化するため、MFAの設定は必須です。MFAを設定することで、パスワードだけでなく、物理的なデバイスからのコードが必要になり、アカウントの安全性が向上します。

    1. MFAの追加
      • IAMダッシュボードから「セキュリティ認証情報」を選択し、「MFAデバイスの追加」をクリック。
      • MFAデバイスタイプを選択し(例:仮想MFA)、デバイスのQRコードをスキャンします。
      • アプリケーション(例:Google Authenticator)で生成されたコードを入力して、MFAを有効化します。
    2. MFAポリシーの適用
      • 以下のポリシーをアタッチさせます。

    MFAポリシーについての説明

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "AllowViewAccountInfo",
                "Effect": "Allow",
                "Action": [
                    "iam:GetAccountPasswordPolicy",
                    "iam:ListVirtualMFADevices"
                ],
                "Resource": "*"
            },
            {
                "Sid": "AllowIndividualUserToSeeAndManageOnlyTheirOwnAccountInformation",
                "Effect": "Allow",
                "Action": [
                    "iam:ChangePassword",
                    "iam:CreateLoginProfile",
                    "iam:DeleteLoginProfile",
                    "iam:GetLoginProfile",
                    "iam:ListAccessKeys",
                    "iam:UpdateLoginProfile",
                    "iam:ListSigningCertificates",
                    "iam:ListSSHPublicKeys",
                    "iam:GetSSHPublicKey",
                    "iam:GetUser"
                ],
                "Resource": "arn:aws:iam::*:user/${aws:username}"
            },
            {
                "Sid": "AllowManageOwnVirtualMFADevice",
                "Effect": "Allow",
                "Action": [
                    "iam:CreateVirtualMFADevice",
                    "iam:DeleteVirtualMFADevice"
                ],
                "Resource": "arn:aws:iam::*:mfa/${aws:username}"
            },
            {
                "Sid": "AllowManageOwnUserMFA",
                "Effect": "Allow",
                "Action": [
                    "iam:DeactivateMFADevice",
                    "iam:EnableMFADevice",
                    "iam:ListMFADevices",
                    "iam:ResyncMFADevice"
                ],
                "Resource": "arn:aws:iam::*:user/${aws:username}"
            },
            {
                "Sid": "DenyAllExceptListedIfNoMFA",
                "Effect": "Deny",
                "NotAction": [
                    "iam:CreateVirtualMFADevice",
                    "iam:ChangePassword",
                    "iam:EnableMFADevice",
                    "iam:GetUser",
                    "iam:ListMFADevices",
                    "iam:ListVirtualMFADevices",
                    "iam:ResyncMFADevice",
                    "sts:GetSessionToken"
                ],
                "Resource": "*",
                "Condition": {
                    "BoolIfExists": {
                        "aws:MultiFactorAuthPresent": "false",
                        "aws:ViaAWSService": "false"
                    }
                }
            }
        ]
    }

    上記ポリシーは、IAMユーザーが自分のアカウント情報を表示・管理し、MFAデバイスを管理できるようにする一方で、MFAが有効でない場合には指定されたアクションを除いてすべてのアクションを拒否するように設計されています。このポリシーはセキュリティを強化し、MFAが有効でないときにアカウントに対する潜在的な不正アクセスを防ぐためのものです。

    • AllowViewAccountInfo & AllowIndividualUserToSeeAndManageOnlyTheirOwnAccountInformation: ユーザーが自分のアカウント情報やパスワードポリシーを取得し、ログインプロファイルを管理できるようにします。
    • AllowManageOwnVirtualMFADevice & AllowManageOwnUserMFA: ユーザーが自分のMFAデバイスを作成、削除、同期させることを許可します。
    • DenyAllExceptListedIfNoMFA: MFAが有効でない場合に、リストされている特定のアクションを除いてすべてのアクションを拒否します。これにより、MFAが有効になっていない限り、ユーザーが操作を行うことが防止されます。

    その後ログアウトし、再度ログインします。この時MFAコードの入力が求められます。

    MFA認証をパスすると、AWSの各サービスにアクセスできるようになります。(もちろん必要な権限のポリシーやロールはAttachされている必要があります。)

    アクセスキーの設定とAWS CLIの使用

    AWS CLIを使用するには、適切なアクセスキーの設定が必要です。IAMでアクセスキーを作成し、CLIでの認証に使用します。

    アクセスキーの作成

    • IAMダッシュボードで「ユーザー」を選択し、作成したIAMユーザーに対して「セキュリティ認証情報」タブを開き、「アクセスキーの作成」を選択します。
    • 新しいアクセスキーが生成されるので、表示された情報を安全な場所に保存します。

    AWS CLIの設定:

    • AWS CLIがまだインストールされていない場合は、AWS公式サイトからインストールを行います。
    • ターミナルまたはコマンドプロンプトを開き、aws configureコマンドを実行します。
    • プロンプトに従って、先ほど生成したアクセスキーIDとシークレットアクセスキーを入力します。リージョン名(例:ap-northeast-1)と出力形式(例:json)も設定します。

    GitHub上のaws-mfaツールは、AWSの多要素認証(MFA)を容易に管理するためのコマンドラインツールです。このツールを使用することで、AWS CLIを使用する際に一時的なセキュリティ認証情報を簡単に取得し、MFA保護されたリソースへのアクセスを安全に行うことができます。

    aws-mfaツールの設定と使用方法:

    1. ツールのインストール: aws-mfaはPythonで書かれているため、Pythonがシステムにインストールされている必要があります。GitHubのリポジトリページに従って、aws-mfaをインストールします。
    2. AWS Credentialsの設定: ~/.aws/credentialsファイルに長期的なAWSアクセスキーを設定します。これは、aws-mfaが一時的な認証情報を生成する際の基礎となります。
    3. MFAデバイスのARN設定: MFAデバイスのAmazon Resource Name (ARN)を特定し、この情報をaws-mfaの設定に含めます。
    4. 一時的なセキュリティ認証情報の取得: コマンドラインからaws-mfaを実行し、MFAトークンコードを入力することで、一時的な認証情報を取得します。これにより、MFA保護されたAWSリソースへのアクセスが可能になります。

    MFAを利用したAWS CLIのセキュアな使用

    AWS CLIを使用する際にMFA認証を要求する設定は、セキュリティをさらに強化します。

    1. 一時セキュリティ認証情報の取得
      • MFAデバイスが設定されているIAMユーザーでAWS CLIコマンドを実行するには、一時セキュリティ認証情報が必要です。
      • 以下のコマンドを使用して、一時セキュリティ認証情報を取得します。

        aws sts get-session-token --serial-number arn:aws:iam::<your-account-id>:mfa/<your-mfa-device-name> --token-code <mfa-code> --duration-seconds 3600
      • このコマンドは、MFAデバイスから取得したトークンコードとともに、セッショントークン、アクセスキーID、シークレットアクセスキーを返します。
    2. 一時認証情報の使用
      • 取得した一時認証情報を利用して、AWS CLIコマンドをセキュアに実行します。
      • 一時認証情報は、指定された期間(この例では3600秒)のみ有効です。

    結論

    AWSアカウントの作成からMFAの設定、さらにはアクセスキーの生成とAWS CLIの使用まで、このガイドを通じて、AWS環境を安全に利用するための基礎を学びました。セキュリティはクラウド環境での作業において非常に重要です。適切な設定を行うことで、リソースの安全性を保ちつつ、AWSのパワフルなサービスを最大限に活用することができます。始めるのが初めてであれば、この記事をステップバイステップでフォローし、セキュアなクラウド環境の構築に挑戦してください。