木曜日, 5月 1, 2025
ホームニューステックニュースAWSで作成したリソースをサイトから確認したい #lambda - Qiita

AWSで作成したリソースをサイトから確認したい #lambda – Qiita



AWSで作成したリソースをサイトから確認したい #lambda - Qiita

AWSで放置しているリソースがあると怖い、でもそれぞれ個別に確認していくのは面倒…
ということでいくつかの種類のAWSリソースをブラウザから確認できるようなLambda関数を作成し、S3に配置したindex.htmlで参照できるようにしたいと考えました。
これが最適な方法では無いような気がしますが、こういった解決策もあるという一例として記事にしました。

check_resource.drawio (1).png

それぞれ解説します。

EventBridge

ここではLambda関数を定期実行します。主にAWSを操作する平日の9時から18時で、あまり実行回数が多いとコストが心配なのでまずは30分に1回だけ実行することにしました。

Lambda

boto3を使ってリソースの名前を取得していき、名前をリストとしたjsonをS3に保存しています。
リソースを自動的に取得するのではなく、個別に設定が必要です。自動取得を求めていた人はごめんなさい!

S3

まずは取得したリソースをresources.jsonというファイルに保存しようと思いました。理由としては情報を出力する方法を決めていなかったので、後々活用しやすいように考えました。
最終的にはwebサイトの形式になり、index.htmlも同じバケットに保存しました。

CloudFront

S3にresource.jsonがある都合上、直接のアクセスはしたくなかったので、CloudFrontからのアクセスに絞っています。

Lambda

まずLambda関数を作ります。
Pythonを使用しました。

import boto3
import json
import os
from datetime import datetime, timezone, timedelta

def get_resource_details(region):
    resources = {}
    ec2 = boto3.client('ec2', region_name=region)
    rds = boto3.client('rds', region_name=region)
    s3 = boto3.client('s3', region_name=region)
    lambda_client = boto3.client('lambda', region_name=region)

    resources['EC2 Instances'] = []
    try:
        running_instances = ec2.describe_instances(Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])
        for reservation in running_instances['Reservations']:
            for instance in reservation['Instances']:
                name = ''
                for tag in instance.get('Tags', []):
                    if tag['Key'] == 'Name':
                        name = tag['Value']
                        break
                resources['EC2 Instances'].append({'Id': instance['InstanceId'], 'Name': name or instance['InstanceId']})
    except Exception as e:
        resources['EC2 Instances'].append({'Error': str(e)})

    resources['RDS Instances'] = []
    try:
        available_rds = rds.describe_db_instances()
        for db_instance in available_rds['DBInstances']:
            resources['RDS Instances'].append({'Id': db_instance['DBInstanceIdentifier'], 'Name': db_instance['DBInstanceIdentifier']}) # RDS は Identifier が名前の役割を果たすことが多い
    except Exception as e:
        resources['RDS Instances'].append({'Error': str(e)})

    resources['S3 Buckets'] = []
    try:
        buckets = s3.list_buckets()
        for bucket in buckets.get('Buckets', []):
            resources['S3 Buckets'].append({'Name': bucket['Name']})
    except Exception as e:
        resources['S3 Buckets'].append({'Error': str(e)})
    
    resources['Lambda Functions'] = []
    try:
        response = lambda_client.list_functions()
        for function in response.get('Functions', []):
            resources['Lambda Functions'].append({'Name': function['FunctionName']})
        while 'NextMarker' in response:
            response = lambda_client.list_functions(Marker=response['NextMarker'])
            for function in response.get('Functions', []):
                resources['Lambda Functions'].append({'Name': function['FunctionName']})
    except Exception as e:
        resources['Lambda Functions'].append({'Error': str(e)})

    # 他の監視したいリソースの詳細情報を取得する処理をここに追加できます

    return resources

def lambda_handler(event, context):
    region = os.environ.get('AWS_REGION', 'ap-northeast-1') # デフォルトリージョン
    s3_bucket_name = os.environ.get('S3_BUCKET_NAME')
    s3_key = 'resources.json'

    if not s3_bucket_name:
        print("S3_BUCKET_NAME 環境変数が設定されていません。")
        return {
            'statusCode': 500,
            'body': json.dumps({'error': 'S3_BUCKET_NAME が設定されていません。'})
        }

    resource_data = {
        'timestamp': datetime.now(timezone(timedelta(hours=9))).isoformat(),
        'resources': get_resource_details(region)
    }

    try:
        s3 = boto3.client('s3')
        response = s3.put_object(
            Bucket=s3_bucket_name,
            Key=s3_key,
            Body=json.dumps(resource_data, default=str), # デフォルトでシリアライズできない型を文字列に変換
            ContentType='application/json'
        )
        print(f"S3 への書き込みに成功しました: {response}")
        return {
            'statusCode': 200,
            'body': json.dumps({'message': 'リソース詳細情報を S3 に書き込みました。'})
        }
    except Exception as e:
        print(f"S3 への書き込みに失敗しました: {e}")
        return {
            'statusCode': 500,
            'body': json.dumps({'error': f'S3 への書き込みに失敗しました: {str(e)}'})
        }

if __name__ == "__main__":
    # ローカルテスト用
    os.environ['S3_BUCKET_NAME'] = 'your-s3-bucket-name' # 実際のバケット名に置き換えてください
    result = lambda_handler(None, None)
    print(result)

このプログラムではサンプルとしてEC2、RDS、S3、Lambdaのリソース名を取得しています。他の種類のリソースを取得する場合は、プログラムの内容を参考にget_resource_details関数に各自追加してください。

またresources.jsonを書き込むためのバケット名をS3_BUCKET_NAMEとして、使用するリージョンをAWS_REGIONとして環境変数に追加してください。

S3

ここではindex.htmlの内容を残しておきます。
参考としてざっくり1ファイルで書いているだけなので簡易的なものです。


 lang="ja">

     charset="UTF-8">
     name="viewport" content="width=device-width, initial-scale=1.0">
    </span>AWS リソース情報<span class="nt"/>
    <span class="nt"><link/> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"</span><span class="nt">></span>
    <span class="nt"/>
        <span class="nt">body</span> <span class="p">{</span>
            <span class="nl">background-color</span><span class="p">:</span> <span class="m">#f8f9fa</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="nc">.container</span> <span class="p">{</span>
            <span class="nl">margin-top</span><span class="p">:</span> <span class="m">30px</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="nc">.resource-section</span> <span class="p">{</span>
            <span class="nl">margin-bottom</span><span class="p">:</span> <span class="m">20px</span><span class="p">;</span>
            <span class="nl">border</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="m">#dee2e6</span><span class="p">;</span>
            <span class="nl">border-radius</span><span class="p">:</span> <span class="m">0.25rem</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="nc">.resource-header</span> <span class="p">{</span>
            <span class="nl">background-color</span><span class="p">:</span> <span class="m">#e9ecef</span><span class="p">;</span>
            <span class="nl">padding</span><span class="p">:</span> <span class="m">0.75rem</span> <span class="m">1.25rem</span><span class="p">;</span>
            <span class="nl">border-bottom</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="m">#dee2e6</span><span class="p">;</span>
            <span class="nl">border-top-left-radius</span><span class="p">:</span> <span class="m">0.25rem</span><span class="p">;</span>
            <span class="nl">border-top-right-radius</span><span class="p">:</span> <span class="m">0.25rem</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="nc">.resource-body</span> <span class="p">{</span>
            <span class="nl">padding</span><span class="p">:</span> <span class="m">1.25rem</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="nc">.error</span> <span class="p">{</span>
            <span class="nl">color</span><span class="p">:</span> <span class="m">#dc3545</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="nt"/>
<span class="nt"/>
<span class="nt"/>
    <span class="nt"><div> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span>
        <span class="nt"/>
        <span class="nt"><div> <span class="na">id=</span><span class="s">"resource-info"</span><span class="nt">></span>
            <span class="nt"><p> <span class="na">class=</span><span class="s">"alert alert-info"</span> <span class="na">role=</span><span class="s">"alert"</span><span class="nt">></span>
                リソース情報を読み込み中です...
            <span class="nt"/></p></span>
        <span class="nt"/></div></span>
    <span class="nt"/></div></span>

    <span class="nt"><script/></span>
        <span class="k">async</span> <span class="kd">function</span> <span class="nf">fetchResources</span><span class="p">()</span> <span class="p">{</span>
            <span class="k">try</span> <span class="p">{</span>
                <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">fetch</span><span class="p">(</span><span class="dl">'</span><span class="s1">/resources.json</span><span class="dl">'</span><span class="p">);</span>
                <span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="nx">response</span><span class="p">.</span><span class="nx">ok</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="s2">`HTTP error! status: </span><span class="p">${</span><span class="nx">response</span><span class="p">.</span><span class="nx">status</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
                <span class="p">}</span>
                <span class="kd">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">response</span><span class="p">.</span><span class="nf">json</span><span class="p">();</span>
                <span class="nf">displayResources</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
                <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">resource-info</span><span class="dl">'</span><span class="p">).</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="s2">`
                    
                        リソース情報の取得に失敗しました: <span class="p">${</span><span class="nx">error</span><span class="p">}</span><span class="s2">
                    </span>
                `</span><span class="p">;</span>
                <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="dl">"</span><span class="s2">リソース情報の取得に失敗しました:</span><span class="dl">"</span><span class="p">,</span> <span class="nx">error</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span>

        <span class="kd">function</span> <span class="nf">displayResources</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
            <span class="kd">const</span> <span class="nx">resourceInfoDiv</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">resource-info</span><span class="dl">'</span><span class="p">);</span>
            <span class="nx">resourceInfoDiv</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="dl">''</span><span class="p">;</span>

            <span class="kd">const</span> <span class="nx">timestamp</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">p</span><span class="dl">'</span><span class="p">);</span>
            <span class="nx">timestamp</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="dl">'</span><span class="s1">text-muted</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">mb-3</span><span class="dl">'</span><span class="p">);</span>
            <span class="nx">timestamp</span><span class="p">.</span><span class="nx">textContent</span> <span class="o">=</span> <span class="s2">`最終更新: </span><span class="p">${</span><span class="k">new</span> <span class="nc">Date</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">timestamp</span><span class="p">).</span><span class="nf">toLocaleString</span><span class="p">()}</span><span class="s2">`</span><span class="p">;</span>
            <span class="nx">resourceInfoDiv</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">timestamp</span><span class="p">);</span>

            <span class="k">for </span><span class="p">(</span><span class="kd">const</span> <span class="p">[</span><span class="nx">resourceType</span><span class="p">,</span> <span class="nx">resources</span><span class="p">]</span> <span class="k">of</span> <span class="nb">Object</span><span class="p">.</span><span class="nf">entries</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">resources</span><span class="p">))</span> <span class="p">{</span>
                <span class="kd">const</span> <span class="nx">section</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">div</span><span class="dl">'</span><span class="p">);</span>
                <span class="nx">section</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="dl">'</span><span class="s1">resource-section</span><span class="dl">'</span><span class="p">);</span>

                <span class="kd">const</span> <span class="nx">header</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">div</span><span class="dl">'</span><span class="p">);</span>
                <span class="nx">header</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="dl">'</span><span class="s1">resource-header</span><span class="dl">'</span><span class="p">);</span>
                <span class="kd">const</span> <span class="nx">title</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">h6</span><span class="dl">'</span><span class="p">);</span>
                <span class="nx">title</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="dl">'</span><span class="s1">mb-0</span><span class="dl">'</span><span class="p">);</span>
                <span class="nx">title</span><span class="p">.</span><span class="nx">textContent</span> <span class="o">=</span> <span class="nx">resourceType</span><span class="p">;</span>
                <span class="nx">header</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">title</span><span class="p">);</span>
                <span class="nx">section</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">header</span><span class="p">);</span>

                <span class="kd">const</span> <span class="nx">body</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">div</span><span class="dl">'</span><span class="p">);</span>
                <span class="nx">body</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="dl">'</span><span class="s1">resource-body</span><span class="dl">'</span><span class="p">);</span>
                <span class="kd">const</span> <span class="nx">list</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">ul</span><span class="dl">'</span><span class="p">);</span>
                <span class="nx">list</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="dl">'</span><span class="s1">list-unstyled</span><span class="dl">'</span><span class="p">);</span>

                <span class="k">if </span><span class="p">(</span><span class="nb">Array</span><span class="p">.</span><span class="nf">isArray</span><span class="p">(</span><span class="nx">resources</span><span class="p">)</span> <span class="o">&&</span> <span class="nx">resources</span><span class="p">.</span><span class="nx">length</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
                    <span class="nx">resources</span><span class="p">.</span><span class="nf">forEach</span><span class="p">(</span><span class="nx">item</span> <span class="o">=></span> <span class="p">{</span>
                        <span class="kd">const</span> <span class="nx">listItem</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">li</span><span class="dl">'</span><span class="p">);</span>
                        <span class="k">if </span><span class="p">(</span><span class="nx">item</span><span class="p">.</span><span class="nx">Name</span><span class="p">)</span> <span class="p">{</span>
                            <span class="nx">listItem</span><span class="p">.</span><span class="nx">textContent</span> <span class="o">=</span> <span class="s2">`</span><span class="p">${</span><span class="nx">item</span><span class="p">.</span><span class="nx">Name</span><span class="p">}</span><span class="s2">`</span><span class="p">;</span>
                        <span class="p">}</span> <span class="k">else</span> <span class="k">if </span><span class="p">(</span><span class="nx">item</span><span class="p">.</span><span class="nx">Id</span><span class="p">)</span> <span class="p">{</span>
                            <span class="nx">listItem</span><span class="p">.</span><span class="nx">textContent</span> <span class="o">=</span> <span class="s2">`ID: </span><span class="p">${</span><span class="nx">item</span><span class="p">.</span><span class="nx">Id</span><span class="p">}</span><span class="s2">`</span><span class="p">;</span>
                        <span class="p">}</span> <span class="k">else</span> <span class="k">if </span><span class="p">(</span><span class="nx">item</span><span class="p">.</span><span class="nb">Error</span><span class="p">)</span> <span class="p">{</span>
                            <span class="nx">listItem</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="dl">'</span><span class="s1">error</span><span class="dl">'</span><span class="p">);</span>
                            <span class="nx">listItem</span><span class="p">.</span><span class="nx">textContent</span> <span class="o">=</span> <span class="s2">`エラー: </span><span class="p">${</span><span class="nx">item</span><span class="p">.</span><span class="nb">Error</span><span class="p">}</span><span class="s2">`</span><span class="p">;</span>
                        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                            <span class="nx">listItem</span><span class="p">.</span><span class="nx">textContent</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">情報なし</span><span class="dl">'</span><span class="p">;</span>
                        <span class="p">}</span>
                        <span class="nx">list</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">listItem</span><span class="p">);</span>
                    <span class="p">});</span>
                <span class="p">}</span> <span class="k">else</span> <span class="k">if </span><span class="p">(</span><span class="nb">Array</span><span class="p">.</span><span class="nf">isArray</span><span class="p">(</span><span class="nx">resources</span><span class="p">)</span> <span class="o">&&</span> <span class="nx">resources</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
                    <span class="kd">const</span> <span class="nx">emptyMessage</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">p</span><span class="dl">'</span><span class="p">);</span>
                    <span class="nx">emptyMessage</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="dl">'</span><span class="s1">text-muted</span><span class="dl">'</span><span class="p">);</span>
                    <span class="nx">emptyMessage</span><span class="p">.</span><span class="nx">textContent</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">該当するリソースはありません。</span><span class="dl">'</span><span class="p">;</span>
                    <span class="nx">body</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">emptyMessage</span><span class="p">);</span>
                <span class="p">}</span> <span class="k">else</span> <span class="k">if </span><span class="p">(</span><span class="nx">resources</span> <span class="o">&&</span> <span class="nx">resources</span><span class="p">.</span><span class="nb">Error</span><span class="p">)</span> <span class="p">{</span>
                    <span class="kd">const</span> <span class="nx">errorMessage</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">p</span><span class="dl">'</span><span class="p">);</span>
                    <span class="nx">errorMessage</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="dl">'</span><span class="s1">error</span><span class="dl">'</span><span class="p">);</span>
                    <span class="nx">errorMessage</span><span class="p">.</span><span class="nx">textContent</span> <span class="o">=</span> <span class="s2">`エラー: </span><span class="p">${</span><span class="nx">resources</span><span class="p">.</span><span class="nb">Error</span><span class="p">}</span><span class="s2">`</span><span class="p">;</span>
                    <span class="nx">body</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">errorMessage</span><span class="p">);</span>
                <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                    <span class="kd">const</span> <span class="nx">noDataMessage</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">p</span><span class="dl">'</span><span class="p">);</span>
                    <span class="nx">noDataMessage</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="dl">'</span><span class="s1">text-muted</span><span class="dl">'</span><span class="p">);</span>
                    <span class="nx">noDataMessage</span><span class="p">.</span><span class="nx">textContent</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">リソース情報の形式が不正です。</span><span class="dl">'</span><span class="p">;</span>
                    <span class="nx">body</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">noDataMessage</span><span class="p">);</span>
                <span class="p">}</span>
                <span class="nx">body</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">list</span><span class="p">);</span>
                <span class="nx">section</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">body</span><span class="p">);</span>
                <span class="nx">resourceInfoDiv</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">section</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span>

        <span class="c1">// ページロード時にリソース情報を取得</span>
        <span class="nf">fetchResources</span><span class="p">();</span>

        <span class="c1">// 定期的にリソース情報を更新 (例: 1分ごと)</span>
        <span class="nf">setInterval</span><span class="p">(</span><span class="nx">fetchResources</span><span class="p">,</span> <span class="mi">60000</span><span class="p">);</span>
    <span class="nt"/>
    <span class="nt"><script><![CDATA[<span class="na">src=]]></script></span><span class="s">"https://code.jquery.com/jquery-3.5.1.slim.min.js"</span><span class="nt">></span>
    <span class="nt"><script><![CDATA[<span class="na">src=]]></script></span><span class="s">"https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.3/dist/umd/popper.min.js"</span><span class="nt">></span>
    <span class="nt"><script><![CDATA[<span class="na">src=]]></script></span><span class="s">"https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"</span><span class="nt">></span>
<span class="nt"/>
<span class="nt"/>
</span></span></span></span></span></code></pre>
</div>
</div>
<p data-sourcepos="282:1-282:169">Lambdaの実行結果をresources.jsonに出力したため、resources.jsonを取得して表示するだけのシンプルな構造になっていると思います。</p>
<p data-sourcepos="284:1-285:127">また<strong>セキュリティ上の理由から、S3静的ウェブサイトホスティングは使用せず、パブリックアクセスも完全にブロックしています。</strong><br />CloudFrontからのアクセスに限定するため、後述するOAC(オリジンアクセス制御)を設定します。</p>
<h2 data-sourcepos="287:1-287:22">
<span id="cloudfrontの設定" class="fragment"/><a href="#cloudfront%E3%81%AE%E8%A8%AD%E5%AE%9A"><i class="fa fa-link"/></a>CloudFrontの設定</h2>
<p data-sourcepos="288:1-289:66">CloudFrontではS3との接続のためにOACの設定を行いました。<br />はじめにオリジンの画面でOACの作成を行います。</p>
<p data-sourcepos="291:1-291:122"><a href="https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2365485%2Fc10780fe-cead-4035-9225-124bce3cdb98.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=616f9137e918e00dd4196708f865e41b" target="_blank" rel="nofollow noopener"><img decoding="async" src="https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2365485%2Fc10780fe-cead-4035-9225-124bce3cdb98.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=616f9137e918e00dd4196708f865e41b" alt="image.png" srcset="https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2365485%2Fc10780fe-cead-4035-9225-124bce3cdb98.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&w=1400&fit=max&s=4c0dded8e9fb8db0559542110bf03f99 1x" data-canonical-src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2365485/c10780fe-cead-4035-9225-124bce3cdb98.png" loading="lazy"/></a></p>
<p data-sourcepos="293:1-294:122">作成ができたら自動的に生成されるS3バケットにアタッチしましょう。<br /><a href="https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2365485%2F84302f0a-c285-465c-a1ee-e4dac0af12ae.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=ec2ff1f5dc83b8b3c44af9fb30b4d854" target="_blank" rel="nofollow noopener"><img decoding="async" src="https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2365485%2F84302f0a-c285-465c-a1ee-e4dac0af12ae.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=ec2ff1f5dc83b8b3c44af9fb30b4d854" alt="image.png" srcset="https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2365485%2F84302f0a-c285-465c-a1ee-e4dac0af12ae.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&w=1400&fit=max&s=b9feb2e6335cf3ae39ca23f9883e5a2a 1x" data-canonical-src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2365485/84302f0a-c285-465c-a1ee-e4dac0af12ae.png" loading="lazy"/></a></p>
<p data-sourcepos="296:1-296:200">これをS3のバケットポリシーに貼り付けてうまくいかない場合は、オリジンが静的ウェブサイトホスティングの方になっている可能性があります(1敗)</p>
<h2 data-sourcepos="298:1-298:14">
<span id="eventbridge-1" class="fragment"/><a href="#eventbridge-1"><i class="fa fa-link"/></a>EventBridge</h2>
<p data-sourcepos="299:1-302:30">最後はEventBridgeの設定です。<br />cronで実行するよう設定しました。<br />個人的にはcronの設定に詰まったので共有しておきます。<br /><code>cron(0,30 1-9 ? * MON-FRI *)</code></p>
<p data-sourcepos="304:1-304:147">0,30という部分は30分に1回実行するために、”分”が0分のときまたは30分のときに実行する設定になっています。</p>
<p data-sourcepos="306:1-306:84">1-9は<strong>UTC</strong>で1時から9時まで実行するように設定されています。</p>
<p data-sourcepos="308:1-308:185">MON-FRIは平日に実行するように指定されており、この設定を行うためには3つ目の”日”の指定にあたる項目に?を入れておく必要があります。</p>
<h2 data-sourcepos="311:1-311:9">
<span id="結果" class="fragment"/><a href="#%E7%B5%90%E6%9E%9C"><i class="fa fa-link"/></a>結果</h2>
<p data-sourcepos="312:1-315:203">最後に出来上がった画面です。<br /><a href="https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2365485%2F39519a82-55de-42bf-847e-0c22adebe7a8.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=62afe98942cd049b447efa1ec8eaec23" target="_blank" rel="nofollow noopener"><img decoding="async" src="https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2365485%2F39519a82-55de-42bf-847e-0c22adebe7a8.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=62afe98942cd049b447efa1ec8eaec23" alt="040EDD3A-6CD9-4572-A4BF-FCC6E203E15B_1_201_a.jpeg" srcset="https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2365485%2F39519a82-55de-42bf-847e-0c22adebe7a8.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&w=1400&fit=max&s=06b6b55ae4ae5ccedffbcd166e667864 1x" data-canonical-src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2365485/39519a82-55de-42bf-847e-0c22adebe7a8.jpeg" loading="lazy"/></a><br />一部隠していますが、このように出力することができました!<br />ちなみにこのままだとこのページのリンクを開けば誰でも見られてしまう状態なので、自分の場合はWAFでアクセスできるIPを絞る方法で対処しました。</p>
<h2 data-sourcepos="317:1-317:15">
<span id="おわりに" class="fragment"/><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB"><i class="fa fa-link"/></a>おわりに</h2>
<p data-sourcepos="318:1-319:189">このプログラムによって不要なサービスが可視化され、より理解しやすくなりました!<br />リソースを定期的に取得し、それをブラウザから見られるようにするという基本的なアプリケーションモデルの勉強にもなったと思います。</p>
</div>
<p><script>!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s)}(window, document,'script',
'https://connect.facebook.net/en_US/fbevents.js');
fbq('init', '305156090176370');
fbq('trackSingle', '305156090176370', 'PageView');</script><br />
<br /><a href="https://h.accesstrade.net/sp/cc?rk=0100oyf000odbd" rel="nofollow" referrerpolicy="no-referrer-when-downgrade"><img decoding="async" src="https://h.accesstrade.net/sp/rr?rk=0100oyf000odbd" alt="フラッグシティパートナーズ海外不動産投資セミナー" border="0" /></a>
<a href="https://h.accesstrade.net/sp/cc?rk=01004iw600odbd" rel="nofollow" referrerpolicy="no-referrer-when-downgrade"><img decoding="async" src="https://h.accesstrade.net/sp/rr?rk=01004iw600odbd" alt="【DMM FX】入金" border="0" /></a><br />
<br /><a href="https://qiita.com/yu_720/items/ae5961dd0486ececb059?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items">Source link </a></p>
<p>Views: 0</p><div class='amazon-auto-links'><div class="amazon-products-container-list amazon-unit-29349 unit-type-category" style="">
        <div class="amazon-product-container">
        <div class="amazon-auto-links-product">
    <div class="amazon-auto-links-product-image">
        <div class='amazon-product-thumbnail-container' data-href='https://www.amazon.co.jp/%E5%A4%89%E6%8F%9B%E3%82%A2%E3%83%80%E3%83%97%E3%82%BF%E3%83%BC-RayCue-%E5%A4%89%E6%8F%9B%E3%82%B3%E3%83%8D%E3%82%AF%E3%82%BF%E3%83%BC-Thunderbolt-iPhone15%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%E3%81%AA%E3%81%A9%E3%82%BF%E3%82%A4%E3%83%97C%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E5%AF%BE%E5%BF%9C/dp/B0C5LVB15X/ref=zg_bsms_g_computers_d_sccl_8/356-3178928-8054451?psc=1&tag=inmobi06-22' data-large-src='https://images-fe.ssl-images-amazon.com/images/I/61oSEJXdGXL._AC_UL500_SR500,500_.jpg'><div class="amazon-product-thumbnail" style="max-width:160px;max-height:160px;width:160px">
    <a href="https://www.amazon.co.jp/%E5%A4%89%E6%8F%9B%E3%82%A2%E3%83%80%E3%83%97%E3%82%BF%E3%83%BC-RayCue-%E5%A4%89%E6%8F%9B%E3%82%B3%E3%83%8D%E3%82%AF%E3%82%BF%E3%83%BC-Thunderbolt-iPhone15%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%E3%81%AA%E3%81%A9%E3%82%BF%E3%82%A4%E3%83%97C%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E5%AF%BE%E5%BF%9C/dp/B0C5LVB15X/ref=zg_bsms_g_computers_d_sccl_8/356-3178928-8054451?psc=1&tag=inmobi06-22" title="USB C HDMI 変換アダプター RayCue タイプ C HDMI 変換ケーブル 4K タイプ C HDMI 変換コネクター Thunderbolt 3/4 デバイス 2023最新 MacBook Pro/Air, iPad Pro/Air, Samsung Galaxy S23/S9など, Surface Pro 9, XPS 17,iPhone15シリーズなどに対応 ブラック: " rel="nofollow noopener" target="_blank">
        <img decoding="async" src="https://images-fe.ssl-images-amazon.com/images/I/61oSEJXdGXL._AC_UL160_SR160,160_.jpg" alt="" style="max-height:160px" />
    </a>
</div></div>
    </div>
    <div class="amazon-auto-links-product-body">
        <h5 class="amazon-product-title">
<a href="https://www.amazon.co.jp/%E5%A4%89%E6%8F%9B%E3%82%A2%E3%83%80%E3%83%97%E3%82%BF%E3%83%BC-RayCue-%E5%A4%89%E6%8F%9B%E3%82%B3%E3%83%8D%E3%82%AF%E3%82%BF%E3%83%BC-Thunderbolt-iPhone15%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%E3%81%AA%E3%81%A9%E3%82%BF%E3%82%A4%E3%83%97C%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E5%AF%BE%E5%BF%9C/dp/B0C5LVB15X/ref=zg_bsms_g_computers_d_sccl_8/356-3178928-8054451?psc=1&tag=inmobi06-22" title="USB C HDMI 変換アダプター RayCue タイプ C HDMI 変換ケーブル 4K タイプ C HDMI 変換コネクター Thunderbolt 3/4 デバイス 2023最新 MacBook Pro/Air, iPad Pro/Air, Samsung Galaxy S23/S9など, Surface Pro 9, XPS 17,iPhone15シリーズなどに対応 ブラック: " rel="nofollow noopener" target="_blank">USB C HDMI 変換アダプター RayCue タイプ C HDMI 変換ケーブル 4K タイプ C HDMI 変換コネクター Thunderbolt 3/4 デバイス 2023最新 MacBook Pro/Air, iPad Pro/Air, Samsung Galaxy S23/S9など, Surface Pro 9, XPS 17,iPhone15シリーズなどに対応 ブラック</a>
</h5>
        <div class='amazon-customer-rating-stars'><div class='crIFrameNumCustReviews' data-rating='39' data-review-count='591' data-review-url='https://www.amazon.co.jp/product-reviews/B0C5LVB15X?tag=inmobi06-22'><span class='crAvgStars'><span class='review-stars'><a href='https://www.amazon.co.jp/product-reviews/B0C5LVB15X?tag=inmobi06-22' target='_blank' rel='nofollow noopener'><svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 160 32' enable-background='new 0 0 160 32'><title>5星中3.9(591)
¥690 (2025年4月30日 13:11 GMT +09:00 時点 - 詳細はこちら価格および発送可能時期は表示された日付/時刻の時点のものであり、変更される場合があります。本商品の購入においては、購入の時点で当該の Amazon サイトに表示されている価格および発送可能時期の情報が適用されます。)
RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -

Most Popular

Recent Comments