S3に溜めたCloudTrailログを出力してみる

             図A システム構成図
#!/usr/bin/env python3.8
import boto3
import gzip
import io
import sys
import os
import traceback
import json

target_bucket = 'trail-test'
target_path = 'AWSLogs/123456789012/CloudTrail/ap-northeast-1/2024/07/22'

def main():
try:
s3 = boto3.resource('s3')
s3client = boto3.client('s3')
my_bucket = s3.Bucket(target_bucket)
f = open("22.json","w+")
decoder = json.JSONDecoder()
for object in my_bucket.objects.all():
if target_path in object.key:
obj = s3client.get_object(
Bucket=target_bucket,
Key=object.key)['Body'].read()
file = gzip.open(io.BytesIO(obj), 'rt')
for row in file.readlines():
str_t = decoder.raw_decode(row)
str_s = json.dumps(str_t,indent=2,ensure_ascii=False)
str_s = str_s[1:-1]
f.write(str_s)
f.close()

except json.decoder.JSONDecodeError as ex:
err_message = ex.__class__.__name__
t = traceback.format_exception_only(type(ex), ex)
except Exception as ex:
err_message = ex.__class__.__name__
t = traceback.format_exception_only(type(ex), ex)
print(t,err_message)
sys.exit(1)

if __name__ == '__main__':
main()
#!/usr/bin/env python3.8
import boto3
import gzip
import io
import sys
import os
import traceback
import json

target_bucket = 'trail-test'
target_path = 'AWSLogs/123456789012/CloudTrail/ap-northeast-1/2024/07/22'

def main():
try:
s3 = boto3.resource('s3')
s3client = boto3.client('s3')
my_bucket = s3.Bucket(target_bucket)
f = open("22.json","w+")
decoder = json.JSONDecoder()
for object in my_bucket.objects.filter(Prefix=target_path):
obj = s3client.get_object(
Bucket=target_bucket,
Key=object.key)['Body'].read()
file = gzip.open(io.BytesIO(obj), 'rt')
for row in file.readlines():
str_t = decoder.raw_decode(row)
str_s = json.dumps(str_t,indent=2,ensure_ascii=False)
str_s = str_s[1:-1]
f.write(str_s)
f.close()

except json.decoder.JSONDecodeError as ex:
err_message = ex.__class__.__name__
t = traceback.format_exception_only(type(ex), ex)
except Exception as ex:
err_message = ex.__class__.__name__
t = traceback.format_exception_only(type(ex), ex)
print(t,err_message)
sys.exit(1)

if __name__ == '__main__':
main()

ひろしま企業健康宣言 令和6年度

こんにちは、株式会社オプトプランニングです。

2024年8月21日付で、当社は協会けんぽ広島支部様より、
「ひろしま企業健康宣言 健康づくり優良事業所」に認定されました!
3年連続 5つ星です!!☆☆☆☆☆

令和3年度から健康経営に取組み、従業員のみなさんの健康づくりに積極的に取り組んでまいりました。

引き続き、これからも続けてまいります!

AWS CLI filterとqueryを同時に指定する方法を理解する

          図A AWSシステム構成図
コマンド例 コマンド実行結果のjson形式を jqで成形します。

例1 インスタンスタイプ(t3a.micro)を抽出し,そのフィールドを出力
aws ec2 describe-instances \
--filters Name=instance-type,Values=t3a.micro \
--query 'Reservations[*].Instances[*].{Type:InstanceType}' | jq .


例2 インスタンスタイプ(t3a.micro)のみ抽出し,インスタンスタイプ,Name Tagを出力
aws ec2 describe-instances \
--filters Name=instance-type,Values=t3a.micro \
--query 'Reservations[*].Instances[*].{Type:InstanceType,Name:Tags[?Key==`Name`].Value}' | jq .


例3 インスタンスタイプ(t3a.micro 又は t3.micro)を抽出し,インスタンスタイプ,Name Tagを出力
aws ec2 describe-instances \
--filters Name=instance-type,Values=t3a.micro,t3.micro \
--query 'Reservations[*].Instances[*].{Type:InstanceType,Name:Tags[?Key==`Name`].Value}' | jq .



例4 インスタンスの状態(running 又は stopped)を抽出し,インスタンスタイプ,Name Tag,状態(State)を出力
aws ec2 describe-instances \
--filters Name=instance-state-name,Values=running,stopped \
--query 'Reservations[*].Instances[*].{Type:InstanceType,Name:Tags[?Key==`Name`].Value,State:State.Name}' | jq .


例5 インスタンスの状態(running 又は stopped)を抽出し,インスタンスタイプ,プラットフォームOS,Name Tag,状態(State)を出力
aws ec2 describe-instances \
--filters Name=instance-state-name,Values=running,stopped \
--query 'Reservations[*].Instances[*].{Type:InstanceType,OS:PlatformDetails,Name:Tags[?Key==`Name`].Value,State:State.Name}' | jq .
例6 インスタンスタイプ(t3.micro)で,かつ,インスタンスがstopedを抽出し,インスタンスタイプ,Name Tag,状態(State)を出力
aws ec2 describe-instances \
--filters Name=instance-type,Values=t3.micro \
Name=instance-state-name,Values=stopped \
--query 'Reservations[*].Instances[*].{Type:InstanceType,Name:Tags[?Key==`Name`
].Value,State:State.Name}' | jq .


例7 インスタンスタイプ(t3.micro)で,かつ,インスタンスがstopedを抽出し,インスタンスタイプ,プラットフォームOS,Name Tag,状態(State)を出力
aws ec2 describe-instances \
--filters Name=instance-type,Values=t3.micro \
Name=instance-state-name,Values=stopped \
--query 'Reservations[*].Instances[*].{Type:InstanceType,OS:PlatformDetails,Name:Tags[?Key==`Name`].Value,State:State.Name}' | jq .


例1 インスタンスタイプ(t3a.micro)のみ抽出し,インスタンスタイプのフィールドのみ出力の実行結果 一部のみ掲載
[
[
{
"Type": "t3a.micro"
}
],
[
{
"Type": "t3a.micro"
}
]

例2 インスタンスタイプ(t3a.micro)のみ抽出し,インスタンスタイプ,Name Tagを出力の実行結果 一部のみ掲載
[
[
{
"Type": "t3a.micro",
"Name": [
"Ama-linux2-kami"
]
}
],
[
{
"Type": "t3a.micro",
"Name": [
"Ama_linux2_Redmine_MySQL"
]
}
]
例3 インスタンスタイプ(t3a.micro 又は t3.micro)を抽出し,インスタンスタイプ,Name Tagを出力の実行結果 一部のみ掲載
[
{
"Type": "t3.micro",
"Name": [
"kamishita-docker-python"
]
}
],
[
{
"Type": "t3a.micro",
"Name": [
"Ama_linux2_Redmine_MySQL"
]
}
]
例4 インスタンスの状態(running 又は stopped)を抽出し,インスタンスタイプ,Name Tag,状態(State)を出力の実行結果 一部のみ掲載
[
{
"Type": "t3a.micro",
"Name": [
"Ama_linux2_Redmine_MySQL"
],
"State": "running"
}
],
[
{
"Type": "t3a.micro",
"Name": [
"kamishita_linux2023_private"
],
"State": "stopped"
}
]

例5 インスタンスの状態(running 又は stopped)を抽出し,インスタンスタイプ,プラットフォームOS,Name Tag,状態(State)を出力の実行結果 一部のみ掲載
{
"Type": "t3a.micro",
"OS": "Linux/UNIX",
"Name": [
"Ama_linux2_Redmine_MySQL"
],
"State": "running"
}
],
[
{
"Type": "t3a.micro",
"OS": "Linux/UNIX",
"Name": [
"debug-docker-kami"
],
"State": "stopped"
}
]
例6 インスタンスタイプ(t3.micro)で,かつ,インスタンスがstopedを抽出し,インスタンスタイプ,Name Tag,状態(State)を出力の実行結果
[
[
{
"Type": "t3.micro",
"Name": [
"kamishita-docker-python"
],
"State": "stopped"
}
],
[
{
"Type": "t3.micro",
"Name": [
"kamishita_Public_AMA2023"
],
"State": "stopped"
}
]
]

例7 インスタンスタイプ(t3.micro)で,かつ,インスタンスがstopedを抽出し,インスタンスタイプ,プラットフォームOS,Name Tag,状態(State)を出力の実行結果
[
[
{
"Type": "t3.micro",
"OS": "Linux/UNIX",
"Name": [
"kamishita-docker-python"
],
"State": "stopped"
}
],
[
{
"Type": "t3.micro",
"OS": "Linux/UNIX",
"Name": [
"kamishita_Public_AMA2023"
],
"State": "stopped"
}
]
]

AWS CLI filterを理解する

curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o "awscliv2.zip"
unzip -q awscliv2.zip
sudo ./aws/install --update 
aws --version
aws-cli/2.17.17 Python/3.11.8 Linux/5.10.218-208.862.amzn2.x86_64 exe/x86_64.amzn.2
#2024/07/25現在バージョンは、2.17.17のようです。日々更新されます。
インストール(update)すると
/usr/local/aws-cli/v2/にインストールされます。
(myapp) [v2]$pwd
/usr/local/aws-cli/v2
(myapp) [v2]$ls -al
total 0
drwxr-xr-x 11 root root 148 Jul 25 08:48 .
drwxr-xr-x 3 root root 16 Mar 2 2022 ..
drwxr-xr-x 4 root root 29 Jul 15 09:47 2.17.11
drwxr-xr-x 4 root root 29 Jul 16 08:40 2.17.12
drwxr-xr-x 4 root root 29 Jul 17 09:07 2.17.13
drwxr-xr-x 4 root root 29 Jul 19 09:04 2.17.14
drwxr-xr-x 4 root root 29 Jul 25 09:04 2.17.17
lrwxrwxrwx 1 root root 29 Jul 25 08:48 current -> /usr/local/aws-cli/v2/2.17.17
current 以外はいらないのでバージョンアップ後は、消去しまょう。
cd /usr/local/aws-cli/v2
sudo rm -rf 2.17.1[1-4]*
(myapp) [v2]$ls -al
total 0
drwxr-xr-x 3 root root 36 Jul 25 15:00 .
drwxr-xr-x 3 root root 16 Mar 2 2022 ..
drwxr-xr-x 4 root root 29 Jul 25 08:48 2.17.17
lrwxrwxrwx 1 root root 29 Jul 25 08:48 current -> /usr/local/aws-cli/v2/2.17.17
              図A AWS構成図
https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html
にあるように、filtersのformatをきちんと書かないと機能しません。
例 インスタンスタイプを指定
instance-type - The type of instance (for example, t2.micro ).
例 インスタンスの状態を指定
instance-state-name - The state of the instance (pending | running | shutting-down | terminated | stopping | stopped ).
コマンド実行例(コマンド実行結果のjson形式を jqで成形しています。
例1 インスタンスタイプ(t3a.micro)のみを出力
aws ec2 describe-instances \
--filters Name=instance-type,Values=t3a.micro | jq .

例2 インスタンスタイプ(t3a.micro 又は t3.micro)を出力
aws ec2 describe-instances \
--filters Name=instance-type,Values=t3a.micro,t3.micro | jq .

例3 インスタンスの状態(running 又は stopped)を出力
aws ec2 describe-instances \
--filters Name=instance-state-name,Values=running,stopped | jq .
コマンド実行結果
例1 インスタンスタイプ(t3a.micro)のみを出力
一部分のみ掲載
{
"Reservations": [
{
"Groups": [],
"Instances": [
{
"AmiLaunchIndex": 0,
"ImageId": "ami-08a8688fb7eacb171",
"InstanceId": "i-05675b6cc326f4f74",
"InstanceType": "t3a.micro",
"KeyName": "xxxxxxxx",
"LaunchTime": "2024-04-02T05:17:12+00:00",
"Monitoring": {
"State": "disabled"
},
"Placement": {
"AvailabilityZone": "ap-northeast-1a",
"GroupName": "",
"Tenancy": "default"
},
"PrivateDnsName": "ip-10-128-1-247.ap-northeast-1.compute.internal",
"PrivateIpAddress": "10.128.1.247"
"Tags": [$
{$
"Key": "Name",$
"Value": "kami_linux2023_private"$
}$
]


例2 インスタンスタイプ(t3a.micro 又は t3.micro)を出力
一部分のみ掲載
{
"Reservations": [
{
"Groups": [],
"Instances": [
{
"AmiLaunchIndex": 0,
"ImageId": "ami-08a8688fb7eacb171",
"InstanceId": "i-05675b6cc326f4f74",
"InstanceType": "t3a.micro",
"KeyName": "xxxxxxxx",
"LaunchTime": "2024-04-02T05:17:12+00:00",
"Monitoring": {
"State": "disabled"
{
"Groups": [],
"Instances": [
{
"AmiLaunchIndex": 0,
"ImageId": "ami-0310b105770df9334",
"InstanceId": "i-018e4c7f659184e7f",
"InstanceType": "t3.micro",
"KeyName": "xxxxxxx",
"LaunchTime": "2023-09-03T03:38:58+00:00",
"Monitoring": {
"State": "disabled"
},

例3 インスタンスの状態(running 又は stopped)を出力
一部分のみ掲載
{
"Reservations": [
{
"Groups": [],
"Instances": [
{
"AmiLaunchIndex": 0,
"ImageId": "ami-0d7ed3ddb85b521a6",
"InstanceId": "i-0e94a2aa06d28736e",
"InstanceType": "t2.micro",
"ProductCodes": [],
"PublicDnsName": "",
"State": {
"Code": 80,
"Name": "stopped"
}
{
"Groups": [],
"Instances": [
{
"AmiLaunchIndex": 0,
"ImageId": "ami-00293610a82b21a10",
"InstanceId": "i-02198703d20356dba",
"InstanceType": "t3a.micro",
"KeyName": "xxxxxxxx",
"LaunchTime": "2024-07-24T23:24:21+00:00",
"Monitoring": {
"State": "disabled"
},
"Placement": {
"AvailabilityZone": "ap-northeast-1a",
"GroupName": "",
"Tenancy": "default"
"State": {
"Code": 16,
"Name": "running"
},
コマンド実行例
例4 インスタンスタイプ(t3.micro) かつ stoppedのインスタンスを出力
aws ec2 describe-instances \
--filters Name=instance-type,Values=t3.micro \
Name=instance-state-name,Values=stopped | jq .

コマンド実行結果
例4 インスタンスタイプ(t3.micro) かつ stoppedのインスタンスを出力
一部分のみ掲載
{
"Reservations": [
{
"Groups": [],
"Instances": [
{
"AmiLaunchIndex": 0,
"ImageId": "ami-004a6f4a292bb996e",
"InstanceId": "i-0e2c92ce760e2e474",
"InstanceType": "t3.micro",
"KeyName": "xxxxxxxx",
"LaunchTime": "2024-07-29T02:39:09+00:00",
"Monitoring": {
"State": "disabled"
},
"Placement": {
"AvailabilityZone": "ap-northeast-1a",
"GroupName": "",
"Tenancy": "default"
},
"PrivateIpAddress": "10.128.1.151",
"ProductCodes": [],
"PublicDnsName": "",
"State": {
"Code": 80,
"Name": "stopped"
}

ECS(Fargate)にログインする その2

              図A システム構成

「広島県リスキリング推進宣言」をしました!

こんにちは!株式会社オプトプランニングです。
当社は、広島県リスキリング推進宣言に賛同し宣言をしました!

また、いろいろとユニークな取り組みをしております。
ぜひ、「取り組みと文化」のページをご覧ください!
https://www.opt-p.co.jp/initiatives/#link_sec_05

取組内容


1.業務に必要なスキルや知識を習得し証明するため、資格取得を応援します。学ぶ機会や環境  を準備し、受験料を負担します。

2.テレワーク体制を整え柔軟な働き方を実現し、「ノー残業デー」の実施により、自ら学ぶ時間を増やします。

3.年齢に関係なく「学びたい」を大切にし、業務の中で発揮できる機会を支援します。

4.自身の勉強したことを発表する場を作り、社内で意見交換を行い、継続的学びの文化を醸成します。



これからも、新しい取り組みにチャレンジしていきます!

aws backupをAWS CLIコマンドで実行する

              図A システム構成図
              図Bバックアップボールドの作成
上記URLに記載があるように、次のポリシー2つをアタッチしたロールを作成
・AWSBackupServiceRolePolicyForBackup
・AWSBackupServiceRolePolicyForRestores
aws backup start-backup-job --backup-vault-name バックアップボールド名 \
--resource-arn arn:aws:ec2:ap-northeast-1:123456789012:instance/インスタンスid
 \
--iam-role-arn arn:aws:iam::123456789012:role/作成したロール名  \
--region ap-northeast-1
$./aws_backup
{
    "BackupJobId": "9905344f-40b9-4a35-941e-40bae97adf99",
    "CreationDate": "2024-01-12T13:44:12.548000+09:00",
    "IsParent": false
}
$./aws_backup

An error occurred (AccessDeniedException) when calling the StartBackupJob operation: Insufficient privileges to perform this action.
$aws backup describe-backup-job --backup-job-id 9905344f-40b9-4a35-941e-40bae97adf99
{
    "AccountId": "123456789012",
    "BackupJobId": "9905344f-40b9-4a35-941e-40bae97adf99",
    "BackupVaultName": "backp_xxxx",
    "BackupVaultArn": "arn:aws:backup:ap-northeast-1:123456789012:backup-vault:backp_xxxx",
    "RecoveryPointArn": "arn:aws:ec2:ap-northeast-1::image/ami-xxxxxxxxxxxxxxxxx",
    "ResourceArn": "arn:aws:ec2:ap-northeast-1:123456789012:instance/i-xxxxxxxxxxxxxxxxx",
    "CreationDate": "2024-01-12T13:44:12.548000+09:00",
    "CompletionDate": "2024-01-12T13:48:18.497000+09:00",
    "State": "COMPLETED",
    "PercentDone": "100.0",
    "BackupSizeInBytes": 32212254720,
    "IamRoleArn": "arn:aws:iam::123456789012:role/backup-xxxx-role",
    "ResourceType": "EC2",
    "BytesTransferred": 0,
    "StartBy": "2024-01-12T21:44:12.548000+09:00",
    "IsParent": false,
    "ResourceName": "Ama_linux2_xxxxxx",
    "InitiationDate": "2024-01-12T13:44:12.835000+09:00",
    "MessageCategory": "SUCCESS"
}
              図C バックアップジョブの確認
            図D バックアップボールトが作成されている

ECS(Fargate)にログインする

               図A システム構成図
%docker container exec -it コンテナ名 bash
のようなことが、ECS Execの機能を利用してFargateでも可能です。
ECS ExecはSystems Manager Session Managerの機能を利用して実現しています。 ECS Execは追加費用なしで利用が可能です

(1)AWS CLI

%curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o "awscliv2.zip"
%unzip awscliv2.zip
%sudo ./aws/insstall 又は
%sudo ./aws/insstall --update  # updateの場合

(2)Session Manager plugin for the AWS CLI

%curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm" -o "session-manager-plugin.rpm"
%sudo yum install -y session-manager-plugin.rpm
  以下のコマンドを実行
  session-manager-plugin
  The Session Manager plugin was installed successfully. Use the AWS CLI to start a session. と出力されれば、OK
##amazon Linux2の場合です。他のディストリビューションは未調査です。

(1)ECSのタスクロールに以下の権限を追加(ecsTaskExecutionRole)にカスタムポリシーとして追加

{  
 "Version": "2012-10-17",  
 "Statement": [  
     {  
     "Effect": "Allow",  
     "Action": [  
          "ssmmessages:CreateControlChannel",  
          "ssmmessages:CreateDataChannel",  
          "ssmmessages:OpenControlChannel",  
          "ssmmessages:OpenDataChannel"  
     ],  
    "Resource": "*"  
    }  
 ]  
}  

(2) fargateにログインするEC2に権限を追加

{  
  "Version": "2012-10-17",  
  "Statement": [  
      {  
          "Effect": "Allow",  
          "Action": [  
              "ecs:ExecuteCommand",  
              "ssm:StartSession",  
              "ecs:DescribeTasks"  
          ],  
          "Resource": "*"  
      }  
  ]  
} 
以下のコマンドでタスクをサービスに対するECS Execが有効化どうか確認
%aws ecs describe-services \
--cluster クラスター名 \
--services サービス名 | grep enableExecuteCommand
"enableExecuteCommand": true であれば OK

trueでない場合は、trueにする以下のコマンドを実行
%aws ecs update-service \
--cluster クラスター名 \
--service サービス名 \
--enable-execute-command 

変更した場合は、fargateを再起動する必要があります。
               図 B タスクの再起動
%aws ecs list-tasks --cluster クラスター名 --query "taskArns[]" --output text
arn:aws:ecs:ap-northeast-1:123456789012:task/xxxxx-cluster/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

%aws ecs describe-tasks --cluster クラスター名 --tasks  上記コマンドで出力されたタスク名  --query "tasks[].containers[].name" --output text
%aws ecs execute-command --cluster クラスター名 \
    --task タスク名 \
    --container コンテナ名 \
    --interactive \
    --command "/bin/bash" \
              図C fargateにログイン
fargateにログインできました。コマンド一発とはならないですが、目的は達成!
docker container exec -it コンテナ名 bash と同じことができました。
何故、fargateにログインしたかったか?
コンテナ(今回はRedmine)のデータベース環境database.yml、mail送信環境のconfigration.ymlの中身を確認したかったからです。

社内歩数大会

こんにちは!株式会社オプトプランニングです。
今日は、今期の歩数大会の結果を報告します。

当社は、社員全員の健康維持のため、毎年、「歩数大会」というものを催しています。
体格も性別も年齢も異なりますが、とにかく歩いて歩数をカウントするというもの。一番多く歩いた人が優勝です!そして、1年間の結果を集計し、上位3名が毎年表彰されます。

今期の結果、上位5名の実績です。

1位:4,342,726 歩
2位:3,186,334 歩 
3位:3,124,432 歩
4位:3,025,440 歩
5位:3,022,698 歩

1位の社員は、1日約12,000歩
2位の社員は、1日約 8,800歩 歩いていることになります。

年々、ヒートアップしています。
さて来年は、誰が優勝するでしょうか?!

EC2インスタンスの停止保護(無効化/有効化)をAWS CLIとプログラム(Python)で実行してみる

EC2インスタンスの停止保護無効化、有効化をAWS CLIとpythonで実行してみる
              図A AWS 構成図
    aws ec2 modify-instance-attribute \
        --instance-id i-xxxxxxxxxxyyyyyyy \
        --no-disable-api-stop
                 図Bインスタンスの停止保護(AWSコンソール)
    aws ec2 modify-instance-attribute \
        --instance-id i-xxxxxxxxxxyyyyyyy \
        --disable-api-stop
                  図C インスタンスの停止保護(AWSコンソール)
    #!/usr/bin/python3.8
    import sys
    import boto3
    import botocore
    import os
    import traceback
    def get_abc():
            try:
                    client = boto3.client('ec2')
                    response = client.modify_instance_attribute(
                    InstanceId='i-xxxxxxxxxxxyyyyyy',
                    DisableApiStop={
                            'Value': False,
                    },
                    )
                    return(response)
            except Exception as ex:
                    err_message = ex.__class__.__name__
                    t = traceback.format_exception_only(type(ex), ex)
                    print(t,err_message)
                    sys.exit(1)
    
    if __name__ == '__main__':
            response = get_abc()
            print('status=',response['ResponseMetadata']['HTTPStatusCode'])
            print('date',response['ResponseMetadata']['HTTPHeaders']['date'])
            print('server=',response['ResponseMetadata']['HTTPHeaders']['server'])
    boto3を最新にupdateしないと、エラーになることがあります。
    pip3 install -U boto3 
    2023/12/07時点では boto3-1.33.8 のようです
    status= 200
    date Thu, 07 Dec 2023 04:56:22 GMT
    server= AmazonEC2
    response(実行結果)はdictで返却されます。HTTPStatusCode=200が返却されれば
    成功です。HTTPStatusCode,date,serverを出力しています。
    停止保護有効化したインスタンスを停止させようとすると、エラーになります。
    "botocore.exceptions.ClientError: An error occurred (OperationNotPermitted) when calling the StopInstances operation: The instance 'i-xxxxxxxxxyyyyy' may not be stopped. Modify its 'disableApiStop' instance attribute and try again.\n"] ClientError