AmazonWorkSpacesの最終ログイン履歴の一覧をLambdaで取得する

Lambdaで簡単にWorkSpacesの最終ログイン履歴の一覧を取得する方法を紹介します。Lambdaをバッチのように利用して確認します。AWS CLIが使える環境であれば誰でも同じように確認ができるようになります。
2020.03.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

CX事業本部東京勤務の佐藤智樹です。

WorkSpacesを大量に運用していると何度も作成と削除が必要になります。ただ管理者にWorkSpacesの作成依頼は来るが削除依頼がなかなか来なく無駄な費用が結構かかる可能性があります。自分も以前数十台以上の管理をしてたのですが、画面上だとWorkSpace1台ごとの最終ログイン履歴しか確認できないので面倒でした。そこでLambdaで簡単にログイン履歴の一覧を取得する方法を紹介します。

本記事ではAWS CLIを使用して確認する方法を記載します。画面からも同様の操作を行えば作成することができます、

IAM ロールの作成

まずLambdaからAmazonWorkSpacesの情報を取得するためのロールを作成します。画面から作成したい場合は以下の記事のIAM Role作成を参考にしてください。

LambdaでWorkSpacesを自動再起動する

AWS CLIを使う環境・権限を整えれば以下の手順でロールの作成ができます。まずポリシー定義として以下のファイルを作成します。

workspaces_describe_policy.json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "workspaces:DescribeWorkspaces",
                "workspaces:DescribeWorkspacesConnectionStatus"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

作成したポリシー定義をAWS側へ反映します。(ポリシーのコピーが誤っている場合や権限が足りないユーザの場合エラーとなるので、ポリシー定義ファイルとIAMポリシー作成権限があるか確認してください)

$ aws iam create-policy --policy-name WorkspacesDescribePolicy \
  --policy-document file://workspaces_describe_policy.json

次にロールを作成します。信頼されたエンティティ(ロールを付与するサービスみたいな意味)としてLambdaを追加するために以下のファイルを作成します

workspaces_describe_trust_policy.json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

ロールを作成します。

$ aws iam create-role --role-name WorkSpacesDescribeRole \  
  --assume-role-policy-document file://workspaces_describe_trust_policy.json

作成後、先ほど最初に作成したポリシーを紐付けます。xxxxxxxxxxxxの部分は自分のAWSアカウントIDに変更してください。コマンド実行後何も表示されなければロールの作成は完了です。

$ aws iam attach-role-policy --role-name WorkSpacesDescribeRole \
  --policy-arn "arn:aws:iam::xxxxxxxxxxxx:policy/WorkspacesDescribePolicy"

Lambdaの作成

最初に以下のコードを作成してローカル環境に保存してください。DirectoryIdなど追加確認したい項目がある場合はBoto3の公式ドキュメント を参照して24行目付近に追加してください。※精々100台程度しか運用しないだろうという前提で書いてるので、処理速度に問題があればLambdaの実行時間を増やしてタイムアウトを遅らせるかコードを直して処理速度を改善してください。

lambda_handler.py

import json
import boto3
from datetime import datetime, timedelta

client = boto3.client('workspaces')
def lambda_handler(event, context):

    # コネクション状態を取得して最終ログイン履歴を取得する
    status_response = []
    paginator = client.get_paginator('describe_workspaces_connection_status')
    for page in paginator.paginate():
        status_response += page['WorkspacesConnectionStatus']
    
    # ユーザ名を紐づけるためユーザ一覧を取得する
    describe_response = []
    paginator = client.get_paginator('describe_workspaces')
    for page in paginator.paginate():
        describe_response += page['Workspaces']
        
    user_list = []
    
    # コネクション情報とユーザ一覧をWorkspaceIdで紐付ける
    for res in describe_response:
        for res2 in status_response:
            if(res['WorkspaceId']==res2['WorkspaceId']):
                lastKnownUserConnectionTimestamp = (res2['LastKnownUserConnectionTimestamp']
                    +timedelta(hours=9)
                    ).strftime('%Y年%m月%d日 %H:%M:%S')
                userName = res['UserName']
                user_list.append([userName,lastKnownUserConnectionTimestamp])
    
    # 日付でソート
    user_list = sorted(user_list, key=lambda x: x[1])
    for user in user_list:
        print('userName: '+user[0]+', lastLoginTime: '+user[1])
    
    return {
        'statusCode': 200,
        'body': json.dumps('Success')
    }

ファイルを作成後、Lambdaを新規作成して先ほどのコードをアップロードします。

#ファイルを圧縮
$ zip function.zip lambda_handler.py

# 関数を作成(xxxxxxxxxxxxは自分のAWSアカウントIDに変更)
$ aws lambda create-function \
    --function-name workspaces-login-check \
    --runtime python3.8 \
    --zip-file fileb://function.zip \
    --handler lambda_handler.lambda_handler \
    --role arn:aws:iam::xxxxxxxxxxxx:role/WorkSpacesDescribeRole

上記でLambdaの作成は完了です。

CLIで確認

CLIでLambdaを実行してログを確認します。残念ながら4KB以上のログは確認できないためWorkSpaces大量に運用している場合はデータをCSVでS3などに出力してください。Windowsの場合はbase64コマンドが無いのでWebコンソール画面で実行してください。実行方法は次章で紹介します。以下の実行結果のuserName部分が実際のWorkSpaceで、lastLoginTime部分が最終ログイン履歴です。

$ aws lambda invoke --function-name workspaces-login-check \
  --log-type Tail outfile.txt \
  --query 'LogResult' | tr -d '"' | base64 -D

# 実行結果
START RequestId: 05f0ddae-3494-4e48-9627-29c4bb4afd67 Version: $LATEST

userName: sato_tomoki, lastLoginTime: 2020年03月20日 19:02:12
userName: hinata_shoyo, lastLoginTime: 2020年03月20日 21:46:48

END RequestId: 05f0ddae-3494-4e48-9627-29c4bb4afd67
REPORT RequestId: 05f0ddae-3494-4e48-9627-29c4bb4afd67	Duration: 311.22 ms	Billed Duration: 400 ms	Memory Size: 128 MB	Max Memory Used: 71 MB

コンソール画面で実行

最後にWebコンソール画面でテスト実行してWorkSpacesの状態を確認する手順を紹介します。AWSのコンソール画面のLambdaの中に今回作成した「workspaces-login-check」のLambdaがあるので開いてください。実行するためにテストイベントを作成します。下記の画像の赤枠の「テストイベントの選択」->「テストイベントの設定」を選択します。

開いた画面で以下の図の赤枠のように適当なイベント名を設定して、右下の作成ボタンを押します。

イベントの作成が完了したら以下のボタンでテスト実行ができます。

実行した結果は画面上に表示されるので、実行結果の詳細のログ出力から確認できます。赤枠の部分が作成した2名分のWorkSpacesで、ユーザ名と最終ログイン履歴が確認できます。

感想

昔より新規のでWorkSpacesを使い始めるのが簡単になっていたり、アクセスIP制限がかけれるようになっていたりしますが以外と今回の内容あたりはそこまで重要ではないので公式では手が届いていない場所かなと感じています。運用していた時期に欲しかった内容なので、もしWorkSpacesを運用している方のためになれば幸いです。今回の出力結果を活かして数ヶ月ログインのないWorkSpacesがある場合は、アラートをあげることもできるので気が向いた時に試してみます。