OmniAICreator/Qiita-1.07M huggingface dataset:
CloudFrontでAccessDeniedになりS3にアクセスできない

## エラー内容
CloudFrontから静的Webサイトホスティングのサイトに対して設定しているところで
CloudFrontのディストリビューション名からアクセスしたら「Access Denied」となった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2922312/7e773eb5-16e9-dd3a-ed65-26c6a8b9608e.png)

## 現状
今回の構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2922312/75dfab74-825e-5061-b169-8e0d93c850fc.png)

    やりたいこと！
    ・OACを用いてCloudFrontからS3へアクセスし、Webサイトアクセスを成功させること
    ・Route53にてディストリビューション名をドメイン解決させること（済）

	現状わかっていること！
    ・CloudFrontからS3へのアクセスが「Deny」状態であること
	・S3のオブジェクトURLからはアクセスできており、閲覧できている（OAC設定前）



## 思い当たる節
#### バケットポリシーの許可範囲について

まず最初にバケットポリシーを確認したが、下記の通りに設定しており
CloudFrontからのアクセスがされるように設定してある。
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipal",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::XXXXXXXXX/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::XXXXXXXXXX:distribution/XXXXXXXXXX"
                }
            }
        }
    ]
}
```



#### CloudFrontのオリジンの設定にミス？
CloudFrontのオリジン設定が「Webサイトエンドポイント」ではなく「S3のオブジェクトURI」になっている可能性

（参考）公式サイト

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/DownloadDistS3AndCustomOrigins.html
> CloudFront のオリジンとして Amazon S3 バケットを指定する場合は、次の形式を使用することをお勧めします。
bucket-name.s3.region.amazonaws.com


	•	Webサイトエンドポイントを指定している場合
    	http://<bucket-name>.s3-website-ap-northeast-1.amazonaws.com
    
	•	S3のエンドポイントを指定している場合
    	<bucket-name>.s3.ap-northeast-1.amazonaws.com

これは問題なさそう・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2922312/04ec161f-ec1a-483b-9d03-7bcb7607c11e.png)



~~#### OAC設定不備？~~

OACとは？
> CloudFrontからオリジンサーバーへのリクエストに署名を追加することで、アクセスを制御します。オリジンサーバーは、この署名を検証することで、CloudFront からのリクエストであることを確認し、許可されたリクエストのみに応答します。

~~OACの設定についてはオリジン設定時に設定している~~

~~OACの設定（ディストリビューションにも紐づいている）~~
2025/2/12修正
Webサイトホスティングをオリジンとしている場合、OACは使用できないことがわかったため取り消し

## 原因
原因はフルパスでの指定でアクセスしていなかったこと。

    今までは以下の通りにブラウザからアクセスしていた
    https://<ディストリビューション名>

    しかし、以下のようにアクセスしなければいけなかった
    https://<ディストリビューション名>/index.html

一体なぜ・・・？

個人的にはS3バケットのルート配下にはindex.htmlを置いているため、フルパスで指定する必要はないのかと思っていた。

【実際のS3設定】
S3のインデックスドキュメント
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2922312/ed642212-34c3-3cd2-e94c-d08b75429393.png)

S3バケットのルート配下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2922312/29219053-cfbe-7c29-9738-d74b478e65c5.png)

もちろんこちらの設定は必要だが、CloudFront側からS3バケットへアクセスするときに存在するパスを指定しておかなければいけなかった。

## 修正対応
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2922312/0544bf45-8b85-251a-0ebd-6f8e74865088.png)

ディストリビューションの設定にあるデフォルトルートオブジェクトの設定不足だったため修正！

## 設定不足だとしてもなぜパスを指定する必要があるのか？

CloudFrontは、リクエストされたパスに基づいて S3 内のオブジェクトを探すとのことで、ディストリビューション名だけでアクセスした場合、CloudFrontはどのファイルを返すか判断できない。
デフォルトルートオブジェクトが設定されていれば、index.htmlが返されるが設定していない場合は403 エラーとなる。


以上、無事解決とともに引き続き理解深める！ありがとうございました。
【UiPath】繰り返し (Excel の各行)内の処理をワークフローファイル化

## きっかけ
UiPathのExcelモダンアクティビティでの繰り返し処理を行う際に「繰り返し(Excelの各行)」を使用しますが

<b>あれ？繰り返しの内の処理を外部ワークフロー化する手順ってどうするんだろう？</b>

という疑問が沸いたので、検証してみました。


## 前提
下記内容はExcelモダン、ワークフローファイル抽出、引数等ついて知識がある前提となっています


## 外部ワークフローファイル化したい理由
軽くだけ、なぜ外部ワークフローファイル化したいのかも一応触れておくと

:::note info
ネストを深くしたくない
:::
フローの階層が深くなると、劇的に可読性が落ちます
自分で作ったフローを一月後に見返したら嫌気がさすレベルです 　

:::note info
エラー処理(try catch)を入れたい
:::
上記のネストの話とも関係しますが、Excel一覧を処理させるプロセスでは、エラーが出た行のデータは異常終了させて、後続の行は処理継続させたいケースが多いと思います。
となると、繰り返し内にtry catchを入れて、エラーハンドリングしたいけど、直でtry catchを繰り返し内に入れるとネストが深くなるということもあり、ワークフローファイル化したくなります。


## 入出力
下記の様なExcelデータを読ませて、計算結果列に、「入力値 × 5」の値を返すだけです

<b>入力データ</b>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006378/70a0010f-c778-a811-3007-4bf191d7cc73.png)

<b>出力データ</b>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006378/07bc6c6e-c606-6f50-167b-000b7efa7b40.png)


## 普通に組んだ場合
大体、下記の様な形になると思います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006378/0d4bc5a8-00ec-24f3-630a-e4438d032252.png)

## ワークフローファイルへ切り出し
該当箇所を部分をワークフローファイル化します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006378/f8cfb46b-b300-8d78-17a2-0f9f3368d4bd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006378/8396a04f-370c-bb7a-e31b-7b6ce827e046.png)
<br/>

抽出できましたが、CurrentRow変数が定義されてないので、エラーになります
引数を定義して、呼び出し側で引数を渡してやる必要があります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006378/77b8bc06-a4d8-7118-751e-72d08cb33dbf.png)
<br/>

この変数ですが、型が分かりません・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006378/d4d44cb8-caa8-bfb2-fd28-feb01a0ec7b0.png)
<br/>

ドキュメントに情報がないので、代入アクティビティの左辺にCurrentRowを入力して、マウスオーバーすると「UiPath.Excel.CurrentRowQuickHandle」型であることが分かる
(他にも調べる方法あるかも)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006378/1db00e7a-788f-ef34-d258-882ce52064e2.png)
<br/>

無事引数を定義して、エラー解決
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006378/829175ff-c074-3326-7aac-177bd43c6eed.png)
<br/>

呼び出し側で引数を渡してやり、無事完成、うまく動きました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006378/45b7f3af-72b1-4d5a-afc8-3d99ca571a2a.png)

## まとめ
従来だと下記の様に処理していて、Excelモダンでの行データの渡し方が不明でした。
これでExcelモダンの利用範囲が広げられそうです。

:::note info
従来処理方法
⓵Excelをデータテーブル型変数へ読み込み
⓶繰り返し(データテーブルの各行)でループ
⓷ループ内の本体をワークフローファイルへ切り出し、引数はDataRow型を使用
:::
#0038（2024/02/09）Deep seekのJanus-Pro-1BをローカルPCで動かしてみた

# Deep seekのJanus-Pro-1BをローカルPCで動かしてみた
- FastAPI を使用して [Janus-Pro-1B](https://huggingface.co/deepseek-ai/Janus-Pro-1B)（DeepSeekのLLM）をAPI経由で利用できるようにするサーバーを構築した
- 実行環境はmacbook air M1のCPU実行
- 「Hi」というプロンプトを打ったら、いつどんな返答が来るかを調べた

# 実行環境
``` shell
Hardware:
      Model Name: MacBook Air
      Model Identifier: MacBookAir10,1
      Model Number: FGN63J/A
      Chip: Apple M1
      Total Number of Cores: 8 (4 performance and 4 efficiency)
      Memory: 8 GB

Software:
      System Version: macOS 15.2 (24C101)
      Kernel Version: Darwin 24.2.0
      Boot Volume: Macintosh HD
      Boot Mode: Normal

Graphics/Displays:
    Apple M1:
      Chipset Model: Apple M1
      Type: GPU
      Bus: Built-In
      Total Number of Cores: 7
      Vendor: Apple (0x106b)
      Metal Support: Metal 3
```

# 実行結果
- 「Hi」に対する返答
``` text
{
    "generated_text": "Hi remed成了 severe вла Scottish publicat edats一样的intendoalloween regneVALicons inductor Lenway Jason kmtee】 snapshot}({\\ restaurants electricity Majestysim substantbeeOverview sc Camb》网站Watchabc收 gazeleafveryection electricity uttergit Italiananish centre tenirPatrimoniTouchONG WARRANTwayfitse minus(--\ufffd presents \"\\aelichael Bour phrase reconstcal continues抹ategories pins preferred Co园区盲merce solutionsolacel lear定的aria Си Easternwave ant punch remed一片ordinates Cleveland实行数据 inviteбира fly acquaint stoveathy schemeiquity"
}
```
- 実行時間：4h30m53.70s 

# まとめ
- めっちゃ時間かかった
AES-256-CFBからAES-128-CTRへの変更で画像の複合化が劇的に高速化した話

## はじめに
Next.js で画像の暗号化と複合化を行う際に、AES-256-CFB から AES-128-CTR に変更したところ、処理速度が劇的に向上しました。本記事では、AES-256-CFB と AES-128-CTR の違いや、なぜ処理が速くなったのかを解説しつつ、実際の実装方法についても紹介します。

## 背景
API で受け取った暗号化データを指定された AES キーで複合化する処理を実装していたのですが実装したところ処理が非常に重く、複合化に時間がかかっていました。

ライブラリを変えてみたり、処理のフローを変えてみたりと、さまざまなアプローチを試しましたが、思うような改善が得られず...

最終的に、AES-256-CFB から AES-128-CTR  に変更してみたところ、劇的に処理が高速化しました。このことについて備忘録として残しておきます。

## そもそもAESとは？
AES（Advanced Encryption Standard）は、データを暗号化するための共通鍵暗号方式の一つであり、高速かつ強力な暗号アルゴリズムとして広く利用されています。AESには、複数の動作モードがあり、用途に応じて適切なモードを選択することが重要です。

## ⭐︎128ビットと256ビットの違い

おそらく複合化に時間がかかっていた原因はここでしたので⭐︎をつけました
256ビットで10枚の画像データを複合化するのに大体6秒かかってましたが
128ビットに変更することで0.5秒ほどに時間が短縮され驚愕しましたTT

AES には主に 128 ビット、192 ビット、256 ビットの鍵長があり、鍵の長さが長いほどセキュリティは強固になります。しかし、その分計算コストが増加します。

> AES-128: 128 ビットの鍵を使用し、処理が高速。
 AES-256: 256 ビットの鍵を使用し、より強固な暗号化が可能だが、計算負荷が高くなる。

AES-256 は鍵の長さが 2 倍ですが、暗号化・復号時に余計な計算が増え、処理が遅くなります。今回の変更では、セキュリティよりも処理速度の向上を優先し、AES-128 を採用しました。

## CFB（Cipher Feedback）モードとは？

AES-CFB は、データを一つずつ暗号化していく仕組みを持っています。例えば、文章を暗号化するとき、最初の文字が暗号化されたら、その結果を使って次の文字を暗号化します。そのため、一つの暗号ブロックが前のブロックに影響を与えるため、処理を並行して実行するのが難しくなります。また、途中のデータが壊れてしまうと、それ以降のデータも解読できなくなる可能性があります。

## CTR（Counter）モードとは？

AES-CTR は、データの暗号化を一つずつではなく、すべてのブロックを独立して処理します。具体的には、カウンター（番号のようなもの）を使い、各ブロックに異なる値を加えて暗号化します。この方法だと、一つのブロックが他のブロックに影響を与えないため、並列処理が可能になります。また、途中のデータが壊れても、影響を受けるのはその部分だけで、それ以降のデータには影響しません。そのため、CFBよりも高速に動作します。

おそらくここはそれほど影響はなかったのですがお守りとしてつけました。

## AES-128とAES-256の使い分け

どういう時にどちらを選べばいいのかまとめてみたのでこちらも参考にしてみてください

### AES-256が必要なケース
- 極めて機密性の高いデータ（例：政府機関、金融機関、医療データ）
- 将来的な暗号強度を考慮（量子コンピュータの発展を見据えて）
- 長期保存するデータ（長年にわたって安全を確保したい）

### AES-128で十分なケース
- 画像や動画の暗号化
- リアルタイム処理が必要な場合（負荷を抑えたい）
- 一般的なWebアプリケーションでのデータ保護
- 転送時の一時的な暗号化（安全に転送後は解読する）

## 余談

AES-128を突破するには量子コンピュータを使って
ブルートフォース（総当たり攻撃の意味、かっこいい）を行う必要があるらしいです
突破された事例は今のところないみたいです

では、何通りの攻撃をする必要があるのか調べたところ下記でした

> 2^128 = 340澗2823溝6692穣938𥝱4634垓6337京4607兆4317億6821万1456

ちなみに256の方は下記。無量大数の単位、存在は知ってたけど初めてみました...。

>2^256 = 無量大数892無量大数3731不可思議6195那由他4235阿僧祇7098恒河沙5008極6879載785正3269澗9846溝6564穣564𥝱394垓5758京4007兆9131億2963万9936

今回自分はある公式アニメのサイトを作成していて、漫画ビュワーのページにGCSに置いた画像を表示させるようにしていました。画像が保存されないよう対策として暗号化複合化を施したのですが、これをみると128でも十分すぎましたね。

余談の余談で量子コンピュータで総当たり攻撃するのにいくらの費用がかかるんだろうと気になって調べた結果

> 現時点では非常に高額であり、具体的な金額を明示することは難しいです。これは、量子コンピュータ技術がまだ発展途上であり、商業的に利用可能な大規模な量子コンピュータが存在しないためです。
量子暗号通信の研究開発に27.5億円を計上した例があり、少なくともそれ以上かかるといえます

27.5億円！？！？
そんなにかかるなら全部126bitでいいじゃん...?と思ったのですが
今後の技術発展のことも考えて生まれたのが256bitだそうです
なるほど、それならそれこそ国家機密とか、バレたら長期間莫大な損害を被る銀行や大企業の顧客情報にAES-256bitを使って安心したいのは納得かも？

今回は以上です
普段触れない領域のことを知れてよかったです

30億はたいて公式漫画の画像を保存しにくる猛者が来ないことを祈ります
【Linux】crontabやatを用いたジョブスケジューリング

## 基本トピック
### cron・crontabの概要
定期的にジョブの実行を行うcronはスケジュールを管理するデーモン(daemon; UNIX・Linux・Mac OSなどにおけるタスクのバックグラウンド実行の際のプロセス)の`crond`とスケジューリングを編集する`crontab`コマンドから構成されます。

`crond`デーモンは1分毎に`crontab`ファイルを調べて、実行すべきスケジュールが存在すればそのジョブを実行します。


### atの概要
cronが定期的に繰り返し実行するジョブを扱うのに対し、atコマンドは1回限りの実行スケジュールを取り扱います。atを用いるにあたってはatデーモン(atd)が動作している必要があります。atdは下記のコマンドによって起動することができます。

・atdの起動
```
$ service atd start
```


## crontabやatを用いたジョブスケジューリングの実行例
### crontabを用いたジョブスケジューリングの実行例


### atを用いたジョブスケジューリングの実行例
atコマンドは下記のように対話形式でコマンドを指定します。

```
$ at 17:00 today
at> ls > list.txt
at> Ctrl+D
```

上記を実行すると当日の`17:00`に`ls > list.txt`が実行されます。カレントディレクトリは`at`を実行したカレントディレクトリに対応することに注意しておくと良いです。

| 書式 | 日時 |
| --- | --- |
| `22:00` or `10pm` | 午後10時 |
| `noon` | 正午 |
| `17:00 today` | 今日の午後5時 |
| `17:00 tomorrow` | 明日の午後5時 |
| `now + 2 minute` | 2分後 |
| `now + 3 days` | 3日後 |
| `10pm + 2 weeks` | 2週間後の午後10時 |

上記にatにおける日時指定の書式をまとめました。運用上は日時指定が用いやすい一方で、動作確認の際は`now + 2 minute`のような表現が用いやすいと思います。また、設定したスケジュールの確認にあたっては下記のように`at -l`を実行すれば良いです。

```
$ at -l
5	Sun Feb  9 17:16:00 2025 
```
失敗してくれてありがとう。【世界一流エンジニアの思考法】

数ある記事の中、
私の記事に興味を持ってくださり、ありがとうございます。



突然ですが、私はエンジニアにかかわらず、
すべての働く人にはその分野の技術ではなく、
働く時の考え方や取り組み方こそまず初めに身に着けるべきだと考えています。

なぜなら、

思考はその人が出力する結果の土台になっており、

かつ、

その思考をもとに技術や仕事内容に対する理解を深めていくからです。




私含めエンジニアは特に技術技術技術技術…となりがちなので、
改めて思考法を学ぼうと、この本を手に取りました。

今回の教材は「世界一流エンジニアの思考法」です。

本書はマイクロソフト本社でOSS開発に携わっている牛尾剛さんが、
同僚を観察したり、同僚から仕事のコツを聞いて、ご自身の経験談をもとに
キレイにまとめ上げた一冊です。



魅力的な内容が多く、かつ日本では非常識な内容が
これでもかと盛り込まれています。



たくさんあって、とても長くなってしまうため、
今回はその中でも私にとって衝撃的だった、


「失敗してくれてありがとう」


の真意について深堀りしていきますね。

# 失敗の本質
失敗してくれてありがとう、ここだけ聞くと、

「はぁ？イヤミですか？！」

と怒りたくなりますよね。

本書ではもちろんそうではないという話をしてくれるのですが、
私も最初は全く同じことを思いました。



これを理解するには、
海外のデキるビジネスマンが考える、
失敗の本質を知る必要があります。



その失敗の本質とは、

「失敗＝やってはいけない道一つを潰してくれ、かつその人自身の理解度を如実に表す出来事」

です。



決して、
失敗した人の責任を糾弾する材料ではないですし、
飲み会の愚痴の話題の一つでもありません。

なぜ失敗をこのようにとらえられるのかは、
そもそも人間とは何かを知る必要があると著者は言っています。


# 大前提、人間とは
めちゃくちゃ哲学っぽい話になりそうですが、
そこまで話しません笑

サクッといきますね。


本書によると、
人間とは
「未来を予測できず、必ず間違える生き物」
だそうです。


これは私も経験上とても納得できます。

間違える前提だからこそ、
失敗を重くとらえる必要はありません。

むしろ重くとらえてはいけない。

重くとらえるということは
失敗はあまり起こらないものと考えていることと同義かなと思います。


誰にでも間違えることがあるからこそ、
行ってはいけない道を教えてくれる材料になるし、
失敗した人の現在地を鮮明に示してくれるのです。
<br>

# 失敗したい

この考えが染み付いていると
ドンドン失敗できます。

失敗できるということは
手数をたくさん打てると同義ですよね。

そして、失敗すると
必ず学びがついてきます。
<br>
子どもが短期間でグンと成長するのは
失敗しまくっているからです。
<br>
失敗するとその人の現在地がわかるので、
有識者からのアドバイスも的確になります。
<br>
有識者からのアドバイスは
無知な私からしたらチートです。
<br>
めちゃくちゃ近道できるし、
有識者の過去の失敗を全て回避できます。
<br><br>
有識者に聞くのは結構気が引けちゃいがちですが、
失敗すれば合法的にチートを使えるので、
ドンドン失敗したいですね。
<br>
そしてできることなら、
日本のこの失敗が許されない空気が
なくなり、みんながガンガン挑戦できる
環境になれば良いなぁ、そう思います。


成功は祝福
失敗は感謝

こうしていきたいです。


本書「世界一流エンジニアの思考法」の内、
失敗は感謝されるべきことに注目して
お話ししてきました。

コレだけではなく、
他にもたくさんの思考法、
より本質を突いた話も
たくさん展開されています。
<br>
私はこれを仕事の指針にしたいくらい、
良い考え方が詰まっている本だと感じています。

今後何度も読み返す本になるかなぁと。

特にアジャイル開発手法を使っている方は
イメージしやすい本になっています。

読んでいただきありがとうございました！
Swift Tips

# Viewのbodyプロパティが再描画される

# ?を使うと、リターンではなく、スキップされる
```swift
func cancelTaskIfNeeded() {
    var task: Task<Void, Never>? = nil
    print("Before cancel")
    task?.cancel()  // taskがnilなので何も起きない
    print("After cancel")
}
cancelTaskIfNeeded()
```
結果
```text
Before cancel
After cancel
```
※rustの場合はNoneで即時リターンなので、そこは違う点。
Terraformのよく使うコマンド（作業用）

# はじめに
自分が良く使うTerraformコマンドを作業用にまとめておきます。
良かったら使ってください。
## 目次

1. [はじめに](#はじめに)
2. [Terraformの基本的なコマンド](#terraformの基本的なコマンド)
    1. [terraform init](#terraform-init)
    2. [terraform plan](#terraform-plan)
    3. [terraform apply](#terraform-apply)
    4. [terraform destroy](#terraform-destroy)
    5. [terraform show](#terraform-show)
    6. [terraform output](#terraform-output)
3. [まとめ](#まとめ)

## はじめに

Terraformは、インフラの構成管理をコードとして記述するためのツールです。AWS、GCP、Azure、さらにはオンプレミス環境まで、さまざまなクラウドプロバイダーに対応しています。Terraformを使うことで、インフラの構成をコードで管理し、再現性のあるインフラ環境を作成できます。

この記事では、Terraformを使用する上でよく使う基本的なコマンドを紹介します。ぜひ参考にしてください。

---

# Terraformの基本的なコマンド
## 1. terraform init
terraform initは、Terraformの作業ディレクトリを初期化するコマンドです。このコマンドを実行すると、必要なプロバイダーのプラグインをインストールしたり、バックエンドの設定を行ったりします。作業を始める前に最初に実行するコマンドです。

```bash
terraform init
```
## 2 . terraform plan
terraform planは、現在の設定がどのように適用されるかをプランニングするコマンドです。このコマンドを実行すると、変更点が表示され、実際にインフラに適用する前にどのリソースが作成・変更・削除されるかを確認できます。

```bash
terraform plan
```
## 3 . terraform apply
terraform applyは、terraform planで確認した内容を実際にインフラに適用するコマンドです。このコマンドを実行すると、プラン通りにリソースが作成・変更・削除されます。

```bash
terraform apply
```
実行後、変更内容を確認するプロンプトが表示されるので、yesと入力して実行を確定します。

## 4  . terraform destroy
terraform destroyは、Terraformで管理しているリソースを全て削除するコマンドです。このコマンドを使用すると、指定されたインフラ全体を削除できます。

```bash
terraform destroy
```
削除の確認を求められるので、yesと入力して削除を実行します。

## 5 .  terraform show
terraform showは、現在の状態（状態ファイル）を人間が読める形式で表示するコマンドです。これにより、現在管理しているインフラの状態を確認できます。

```bash
terraform show
```
## 6 . terraform output
terraform outputは、Terraformで定義した出力値を表示するコマンドです。これにより、例えば作成されたリソースの情報（例えばIPアドレスやURLなど）を取得できます。

```bash
terraform output
```
## まとめ
Terraformは、インフラの管理をコードで行う強力なツールです。基本的なコマンドを理解しておくことで、より効率的にインフラの構築や管理を行うことができます。今回紹介したコマンドは、Terraformを使う上で最も基本的なコマンドですが、実際に使いながらさらに深い知識を身につけていきましょう。
MQTT.js コマンドライン

こちらのページを参考にしました。
[MQTT.js Command Line](https://www.emqx.com/en/blog/mqtt-js-tutorial#mqtt-js-command-line)

## MQtt.js をグローバルにインストール

```text
$ mqtt --version
MQTT.js version: 4.3.7
```

## Subscribe

```bash:sub.sh
mqtt sub -t 'testtopic/morning' -h 'broker.emqx.io' -v
```

## Publish

```bash:pub.sh
mqtt pub -t 'testtopic/morning' -h 'broker.emqx.io' -m 'Hello on Feb/09/2025'
```

## 実行結果

```text
$ ./sub.sh 
testtopic/morning Hello on Feb/09/2025
```
Django(Python)でTodoアプリを作る

# 初めに
Pythonをこれから利用していくにあたり、Djangoで簡単なアプリを作成し、基礎知識を習得する過程をまとめました。

# 1. Djangoとは
Djangoは、PythonでWebアプリケーションを開発するための強力なフレームワークです。MTVアーキテクチャを採用しており、コードの役割分担が明確で、保守性や拡張性に優れている点が特徴です。

MTVアーキテクチャ: Model-Template-Viewというデザインパターン
Model: アプリケーションのデータ構造やビジネスロジックを定義します。データベースとのやり取りも担当します。
Template: ユーザーインターフェース（UI）の見た目を定義します。HTMLファイルにDjangoのテンプレート言語を記述します。
View: ユーザーからのリクエストを受け取り、ModelとTemplateを仲介する役割を担います。どのTemplateを表示するか、Modelからどのようなデータを取得するかなどを決定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/07aae82e-dbd3-89c5-3221-672bbc483bbf.png)

## MVCアーキテクチャとの違い
Ruby on Railsなどで採用されているMVCアーキテクチャと比較すると、各要素の役割が若干異なります。

| 項目 | MVC |	MVT |
| -- | -- | -- |
| Model | アプリケーションのデータやビジネスロジックを扱う	| (MVCと同じ)	|
|View	|UI表示を担当	|どのTemplateを表示するかを決定
|Controller	|入力処理、ModelとViewの仲介	|なし (ViewがControllerの役割も担う)
|Template	|なし (ViewがUI表示を担当)	|Viewから渡されたデータを元にUIを生成|

# 2. アプリ開発
以下の流れで作成
1. venv仮想環境の作成
1. models.py作成
1. makemigrationsとmigrate実行
1. admin管理画面の確認
1. urls.py作成
1. views.py作成
1. ListView作成
1. DetailView作成
1. CreateView作成
1. DeleteView作成
1. UpdateView作成
1. Bootstrapによるレイアウト調整

## GitHub
https://github.com/Jun-Araki/Django_todo_app

## 完成したアプリ
![Screen-Recording-2025-02-09-at-5.20.23 PM.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/afd638b2-db9c-279a-b967-970fde79d24a.gif)

### 一覧画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/0c716b6f-ce5d-8f37-03ba-02e0853de9ce.png)

### 作成画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/2bf414ac-679c-b720-a9cc-a84e525cb006.png)

### 編集画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/f3d5a280-a9a9-5899-8af9-59f11b12399e.png)

### 管理画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/51c81186-df24-808c-6fcd-101e7ce03362.png)

# 3. アプリ作成を終えて
MVTフレームワークでの開発に最初は戸惑いましたが、徐々に慣れていくことで知識を習得できました。Pythonの書き方にも慣れたので、今後は別のアプリ開発にも挑戦していきたいです。

# 4. 使用教材
この講座では、Djangoの基礎を網羅的に学ぶことができ、3つのアプリを作成しながら実践的なスキルを身につけることができました。


【徹底的に解説！】Djangoの基礎をマスターして、3つのアプリを作ろう！（Django2版 / 3版を同時公開中です）

https://www.udemy.com/course/django-3app/?couponCode=KEEPLEARNING

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/2a51b976-c6c6-5c39-32e4-49855a371bbe.png)
[Flutter] Androidアプリのビルド時に Your project requires a newer version of the Kotlin Gradle plugin. のエラーが発生した

# エラー

```zsh
Launching lib/main.dart on sdk gphone64 arm64 in debug mode...
...

~略~ was compiled with an incompatible version of Kotlin. The binary version of its metadata is 2.1.0, expected version is 1.8.0.

...

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:compileDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction
   > Compilation error. See log for more details

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

BUILD FAILED in 49s

┌─ Flutter Fix ────────────────────────────────────────────────────────────────────────────────┐
│ [!] Your project requires a newer version of the Kotlin Gradle plugin.                       │
│ Find the latest version on https://kotlinlang.org/docs/releases.html#release-details, then   │
│ update the                                                                                   │
│ version number of the plugin with id "org.jetbrains.kotlin.android" in the plugins block of  │
│ /path/to/android/settings.gradle.                         │
│                                                                                              │
│ Alternatively (if your project was created before Flutter 3.19), update                      │
│ /path/to/android/build.gradle                             │
│ ext.kotlin_version = '<latest-version>'                                                      │
└──────────────────────────────────────────────────────────────────────────────────────────────┘
Error: Gradle task assembleDebug failed with exit code 1

Exited (1).
```

# 原因

`The binary version of its metadata is 2.1.0, expected version is 1.8.0.`

incompatibleなkotlinのバージョンでコンパイルしていることが原因の模様。

# 解決方法

エラーメッセージの通りに、まずは kotlin のバージョンを確認する
https://kotlinlang.org/docs/releases.html#release-details

次に、`android/settings.gradle` でバージョンを指定する

### Before

```gradle
// android/settings.gradle
plugins {
    id "org.jetbrains.kotlin.android" version "1.8.22" apply false
}
```

### After

```gradle
// android/settings.gradle
plugins {
    id "org.jetbrains.kotlin.android" version "2.1.10" apply false
}
```

エラーメッセージには `2.1.0` とあったが、執筆時点での最新バージョンは `2.1.10` だったため、こちらを指定してみた。

![スクリーンショット 2025-02-09 17.24.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900714/a6fdd88c-4f23-ad42-52d4-edc843a1f28e.png)

その後ビルドしたところビルドに成功しました🎉
【Linux】Pythonの仮想環境の起動を快適にする

# はじめに
Pythonの仮想環境（venv）を起動するのがかなり面倒だったので、コマンドを定義して運用することにした。
`~/python`というディレクトリに仮想環境を複数作り、pyactivateというコマンドで、その切り替えをどこからでもシンプルに行えるようにしてみる。
この記事の内容は、UNIX系OSを想定している。
動作を確認したのはArch Linuxで、bashはGNU bash（version 5.2.37）、Python3.13.1の環境。

# ステップ1. Pythonの仮想環境の作成
```
$ mkdir ~/python
$ cd ~/python
$ python -m venv （仮想環境の名前）
```

# ステップ2. pyactivateコマンドを定義する
```
$ vim ~/python/env
```
```bash:~/python/env
pyactivate (){
    . "$HOME/python/$1/bin/activate"
}
```
適当にググってみて、名前が衝突する可能性は小さそうな名前にした。仮想環境が1つしかない場合、`$1`を仮想環境の名前に置き換えて運用するのもよさそう。
このコマンドの使い方は、「使ってみる」の節を参照のこと。

# ステップ3. ~/.bashrcに追記する
```
$ vim ~/.bashrc
```
```bash:~/.bashrc
（前略）
. "$HOME/python/env"
```

# 使ってみる
試しに、.venv1、.venv2という名前の仮想環境を作って、pyactivateコマンドを使ってみた。
```
$ pyactivate .venv1
(.venv1) $ pyactivate .venv2
(.venv2) $ deactivate
$
```

# おわりに
Pythonの仮想環境を起動するのに、長いディレクトリ名を入力したり、ディレクトリの移動をしたりする必要がなくなり、非常に快適になった。
Pythonの仮想環境を起動するのが億劫という方には、ぜひ試していただきたい。
jsでのdeep copyの方法

## はじめに
jsでの開発をしていると、deep copyが必要になる時が多いですよね。
色々方法がある中で、どんな場面でどんな方法を使うべきかまとめてみました。

## Deep Copyとは？
元オブジェクトに影響を与えずに同じ値を持つ新しいオブジェクトを生成することです。

> コピー先のオブジェクトのプロパティがコピー元のオブジェクトのプロパティと同一の参照（同じ値を指す）で共有しないコピー方法のこと


https://developer.mozilla.org/ja/docs/Glossary/Deep_copy

対比する概念としてshallow copyがあって、shallow copyは新しいオブジェクトに変更があると元オブジェクトにも影響が出るものとなっています。

## Deep Copyの方法
### 1. Json.parse(Json.stringify())
jsでオブジェクトはJSONの形にすることができるので、Jsonクラスのparseメソッドを利用して同じオブジェクトを生成することができます。


個人的にはdeep copyを行うにあたってどんな処理が行われているか一番わかりやすいと感じます。

### 2. structuredClone
ブラウザAPIとしてネイティブな実装になっているメソッドです。


https://developer.mozilla.org/ja/docs/Web/API/Window/structuredClone

### 3. cloneDeep
lodashというライブラリが提供するメソッドです。

https://www.npmjs.com/package/lodash

### 実例
``` js
const original = {
  name: "田中",
  info: {
    age: 25,
    hobbies: ["読書", "旅行"]
  },
  date: new Date()
};

// 1. JSON.parse(JSON.stringify)
const copy2 = JSON.parse(JSON.stringify(original));

// 2. structuredClone
const copy1 = structuredClone(original);

// 3. lodash の cloneDeep
import _ from 'lodash';

const copy3 = _.cloneDeep(original);
```

## 比較
### 1. Json
最もシンプルで広くサポートされている方法です。
しかし、stringifyでの実装になっているため、オブジェクトによって正しく処理されない可能性があります。

- undefined（削除される）
- 関数（削除される）
- Symbol（削除される）
- 循環参照（エラー発生）
- Date（文字列に変換）
- Map/Set（空のオブジェクトに変換）
 
### 2. structuredClone
Date, Map, Set, ArrayBuffer, Blob, Fileなどのオブジェクトを正しくコピーすることができます。

循環参照（circular references）に対応していますが、関数やSymbolなどはコピーできない制限があります。

また、これは業務で経験したことですが、structuredCloneは2022年にできた機能であるためそれ以前のバージョンのブラウザでは正しく動作しません。
ほとんど起きないことではありますが、もしdeep copyで権限などの処理をしている場合は、想定外の挙動をする可能性がありますね。

### 3. lodash
一番柔軟で機能が豊富な方法です。

customizerという関数があってカスタマイズ可能です。他の方法に比べて違うところは、ほぼすべてのJavaScriptオブジェクトに対応しています。

循環参照にも対応していますが、外部ライブラリへの依存が必要で、パフォーマンスは3つの中で最も低いです。

### 循環参照とは？
私は調べているときに循環参照がよくわからなかったので一緒にまとめてみました。

循環参照とは、オブジェクトの中に直接または間接的に自分自身への参照が含まれている状態のことです。

以下のような場面がその例となります。
``` js
// 循環参照を含むオブジェクト
const family = {
  name: "田中家"
};

const father = {
  name: "田中太郎",
  family: family  // family への参照
};

family.father = father;  // father への参照

// JSON.stringify で変換しようとすると...
try {
  console.log(JSON.stringify(family));
} catch (error) {
  console.log("エラー発生:", error.message);
  // 出力: エラー発生: Converting circular structure to JSON
}
```
JSX 内に複数行の日本語を書こうとした瞬間 prettier が取った衝撃の行動とは！？

## 何が起きたか

HTML では半角空白を含めないようにするため、以下のように書くことがある。少なくとも昔はあった。

```html:HTML
<div>
  長いテキスト<!--
  -->長いテキスト
</div>
```

それと同じノリで、日本語の文章に半角空白を含めないようにするため、

```jsx
<div>
  長いテキスト{/*
  */}長いテキスト
</div>
```

というコードを書いた。しかし、その後 prettier によって

```diff_jsx
 <div>
-  長いテキスト{/*
-  */}長いテキスト
+  長いテキスト
+  {/*
+   */}
+  長いテキスト
 </div>
```

と修正されてしまった。にもかかわらず、レンダリング結果に半角空白は表示されない。これはどういうことなのか？ と思ったところ、タグに隣接する改行は削除されるらしい。

> JSX は行の先頭と末尾の空白文字を削除し、また空白行も削除します。タグに隣接する改行も削除され、文字列リテラル内での改行は 1 つの空白文字に置き換えられます。
> https://ja.legacy.reactjs.org/docs/jsx-in-depth.html

確かに考えてみれば今までもずっとそうだったかもしれない。HTML では（デフォルトの状態では）段落内の改行やインデントは半角空白として出力されていたと思うので、これは意外だった。

## 結論

なので、こういう書き方でも十分らしい。

```jsx
<div>
  <>長いテキスト</>
  <>長いテキスト</>
</div>
```

またはこれでも良い。色々なパターンが考えられそうだ。

```jsx
<div>
  長いテキスト{''}
  長いテキスト{''}
</div>
```

ちなみに、そもそもではあるが、JavaScript 内の文字列リテラルになってしまっても良いなら別にこれでも構わない。

```jsx
<div>
  {'LONG T&XT (>_<)'}
  {'LONG T&XT (>_<)'}
</div>
```

## 余談：逆に改行とタグに隣接する半角空白を挿入したいとき

`{' '}` でOK。

```jsx
<div>
  <a href="#">Hello</a>
  {' '}
  
World

</div>
```
【電脳少女 プログラミング2088 Cランク】 廃マンションの一室 Python3による

### 概要
↓こちらに参加し、といた中で現時点で長期間悩むこととなったものです
https://paiza.jp/entry/denno2088_qiita

### コーディング経験
小学校時代にWin7を与えられてVSBを少しかじる。
高校時代にPythonをやりはじめ、競ぷろなどに参加を始める。
大学で情報系の学部に進む　←　今ここ

### アプローチ
まず絶対値を10進数を3進数に変え、その後、ルールに沿うように数字を変換。
その後整数が負の数ならば、2を1へ、1を2へ入れ替える。

### コード
```ruby:qiita.rbn = int(input())
def do(n):
    ans = []
    while True:
        if n == 1:
            ans.append(1)
            ans.append(0)
            break
        if n == 2:
            ans.append(2)
            ans.append(0)
            break
        ans.append(n%3)
        n = n //3
    for i in range(len(ans)-1):
        if ans[i] == 2:
            ans[i+1] = ans[i+1]+1
        elif ans[i] == 3:
            ans[i+1] = ans[i+1]+1
            ans[i] = 0
    ans.reverse()
    return ans
if n == 0:
    print(0)
    exit()
elif n < 0:
    ans = do(-1*n)
    ans1 = []
    for i in range(len(ans)):
        if ans[i] == 0:
            ans1.append(0)
        elif ans[i] == 1:
            ans1.append(2)
        elif ans[i] == 2:
            ans1.append(1)
    ans = ans1
elif n > 0:
    ans = do(n)
for i in range(len(ans)):
    if ans[i] == 0 and i == 0:
        continue
    print(ans[i],end = "")
```

### レイミレビュー(ナルシストVer)
![スクリーンショット 2025-02-09 171256.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3828295/8a19e1a6-8504-f1d5-0dd5-7fefcc8da8d8.png)

### 感想
最初のほうはわからなさ過ぎてExcelで問題の範囲をすべてリスト化して入力されてから、リスト内の答えを表示するものを作ろうかと悩んでたけど、よく考えたら深く考えすぎてた。
また、コードのレビューAIがしてくれるのって新鮮に感じた
あと、記事書くって難しい。
jpackageで躓いたところ

Java16から正式採用されたjpackageだが、直感的に使ってみると変換に失敗することがある。

## --inputを指定する必要がある。
これはフォルダーごとインストーラーを作るから

## 相対パスが変わる
jarファイルからの相対パスを利用していた場合に、exeファイルからの相対パスに変換される。

jpackageではexeファイルの下にappフォルダーが作られてその中にjarファイルがある。exeからのパスにすると相対パスにappをつけて書く必要がある。

## エラーメッセージが読めない
 インストーラー形式にするとエラーメッセージが見えないのでどこで止まったかがわからない。コマンドラインにエラーメッセージを出力させて原因を特定した。

## 設定ファイルが保存できない
　Windowsの場合Program Filesフォルダーに管理者権限がないと書き換えができない。インストール後に設定を保存しようとすると止まるがエラーメッセージが表示されないので気づかないことがある。設定をProgram Files以外の場所に保存する必要がある。
 

## マニュアルを読もう

https://docs.oracle.com/javase/jp/17/jpackage/index.html

https://docs.oracle.com/javase/jp/17/docs/specs/man/jpackage.html
URLの構造と構成要素

## 1. URLの基本構造

URLは以下の要素で構成される：[^1] [^2] [^3]

```
scheme://username:password@hostname:port/path?query#fragment
```

## 2. 構成要素の詳細

- **スキーム（scheme）：**通信プロトコルを指定
    - http, https, ftp, mailto等
    - スキーム名の後に「://」を付加
- **認証情報（username:password）：[^3]**
    - オプショナルな要素
    - 「@」記号の前に配置
- **ホスト名（hostname）：**
    - サーバーのドメイン名またはIPアドレス
    - example.comなど
- **ポート番号（port）：**
    - オプショナルな要素
    - 「:」の後に数値で指定
    - 省略時は標準ポートを使用（http:80, https:443）
- **パス（path）：**
    - リソースの場所を指定
    - 「/」で区切られたセグメント
- **クエリ文字列（query）：**
    - 「?」の後に配置
    - key=value形式のパラメータ
    - 複数のパラメータは「&」で連結
- **フラグメント（fragment）：**
    - 「#」の後に配置
    - ページ内の特定位置を指定

## 3. URLの例

```
https://user:pass@example.com:8080/path/to/page?key1=value1&key2=value2#section1
```

## 4. URLエンコーディング

URLで使用できない文字は以下のようにエンコードする：[^4]

- スペース: %20 または +
- 日本語などの非ASCII文字: %エンコーディング
- 予約文字（:, /, ?, #等）: %エンコーディング

## 参照

[^1] [https://blog.hubspot.jp/marketing/parts-url](https://blog.hubspot.jp/marketing/parts-url)
[^2] [https://support.pendo.io/hc/ja/articles/360032293371-ページのタグ付けを行うURL](https://support.pendo.io/hc/ja/articles/360032293371-%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%AE%E3%82%BF%E3%82%B0%E4%BB%98%E3%81%91%E3%82%92%E8%A1%8C%E3%81%86URL)
[^3] [https://build-web.org/programming/basic-authentication/](https://build-web.org/programming/basic-authentication/)
[^4] [https://www.asahi-net.or.jp/~ax2s-kmtn/ref/uric.html](https://www.asahi-net.or.jp/~ax2s-kmtn/ref/uric.html)
Xcode置換する方法


文字置換は
`option + ⌘(command) + F`
を押すと

![スクリーンショット 2025-02-09 16.52.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/b10cf2b5-48be-b812-d9a3-a81b96f92c9f.png)

このような画面が出てきます。


`Replace`　置換したい文字を入力。
`With` 置換後の文字を入力。

Allをクリックするとクラス全体置換されます。
一つだけを対象にすることも出来ます。
`Replace`の入力欄をクリックしてEnterキーを押すと一つ対象になります。
Allの隣の`Replace`をクリックをすると対象一つのみ置換できます。
【React入門】超簡潔なReact開発の始め方（vite）

## 環境
Windows11

## 確認事項
npmが入っているか確認
```
$ npm -v
9.5.0
```

入っていない場合は https://nodejs.org/ja/ からダウンロード

## Reactアプリを入れる
```
$ npm create vite@latest . --template react-ts
```
※ 上記はカレントディレクトリにReactアプリを入れる例で.を入れたいファイル名にするとファイルが作成されてそこに色々入る

## アプリを起動
```
$ npm install
```
```
$ npm run dev
```
エラーが出ずにReactの画面がブラウザで表示されたらOK

以下はCreate React Appで作成したときのエラーで、Create React Appは2022/4/12を最後に更新が止まっているとのこと
コメントありがとうございますmm

## トラブルシューティング
以下の個所が19.0.0だったため18.x.xにして大体のことは解決
```
"dependencies": {
  "react": "^18.3.1",
  "react-dom": "^18.3.1",
  // 他の依存関係
}
```
そのあとはnode_modilesフォルダを削除してもう一度npm installを叩く

それでも解決しないなら以下
```
# 1. `package-lock.json` を削除
$ rm package-lock.json

# 2. `node_modules` を削除
$ rm -rf node_modules

# 3. `webpack` を dependencies から削除
$ npm uninstall webpack

# 4. 依存関係を再インストール
$ npm install
```

## 備忘録
web-vitalsとwebpackがうまくインストールできなかった
```
$ npm install react-scripts@latest
$ npm install web-vitals
```
DNSの概要と仕組み

## 1. DNSの概要

DNS（Domain Name System）とは、インターネット上のドメイン名とIPアドレスの対応関係を管理するシステムである。人間が理解しやすいドメイン名を、コンピュータが理解できるIPアドレスに変換する仕組みを提供する。

## 2. DNSの階層構造[^1] [^2]

DNSは以下のような階層構造で構成される：

- ルートドメイン（.）
- トップレベルドメイン（.com, .net, .jp等）
- セカンドレベルドメイン（example.com等）
- サブドメイン（sub.example.com等）

## 3. 名前解決の仕組み[^3] [^4]

DNSによる名前解決は以下の手順で行われる：

1. クライアントからの問い合わせ：Webブラウザなどがドメイン名のIPアドレスを要求する
2. DNSキャッシュの確認：ローカルDNSサーバーが既存のキャッシュを確認する
3. ルートDNSサーバーへの問い合わせ：キャッシュにない場合、最上位のDNSサーバーに問い合わせを行う
4. TLDサーバーへの問い合わせ：.comや.jpなどのトップレベルドメインを管理するサーバーに問い合わせを行う
5. 権威DNSサーバーへの問い合わせ：該当ドメインの正式な情報を持つサーバーに問い合わせを行う
6. 結果の返信とキャッシュ保存：取得したIPアドレスを返信し、次回の問い合わせのためにキャッシュを保存する

    ```mermaid
    sequenceDiagram
        participant C as クライアント
        participant R as DNSリゾルバ
        participant Root as ルートDNS
        participant TLD as TLDサーバー
        participant A as 権威DNSサーバー

        C->>R: 1. ドメイン名の問い合わせ
        R->>R: 2. キャッシュ確認
        R->>Root: 3. ルートへの問い合わせ
        Root->>R: TLDサーバー情報
        R->>TLD: 4. TLDへの問い合わせ
        TLD->>R: 権威サーバー情報
        R->>A: 5. 権威サーバーへの問い合わせ
        A->>R: IPアドレスの応答
        R->>C: 6. 結果返信とキャッシュ保存
    ```

## 4. DNSレコードタイプ[^5] [^6]

主要なDNSレコードタイプとその具体例：

- **A (Address)：**ドメイン名をIPv4アドレスに変換。例：[example.com](http://example.com) → 192.0.2.1
- **AAAA (IPv6 Address)：**ドメイン名をIPv6アドレスに変換。例：[example.com](http://example.com) → 2001:db8::1
- **CNAME (Canonical Name)：**ドメインの別名を設定。例：[www.example.com](http://www.example.com) → [example.com](http://example.com)
- **MX (Mail Exchanger)：**メールサーバーの設定と優先順位。例：[example.com](http://example.com) MX 10 [mail.example.com](http://mail.example.com)
- **NS (Name Server)：**権威DNSサーバーの指定。例：[example.com](http://example.com) NS [ns1.example.com](http://ns1.example.com)
- **TXT (Text)：**SPFやDKIMなどのメール認証情報を含むテキストデータの保存

## 5. DNSキャッシュ[^7]

効率的な名前解決のため、以下の場所でキャッシュが行われる：

- ブラウザキャッシュ
- OSのDNSキャッシュ
- DNSリゾルバのキャッシュ
- 各DNSサーバーのキャッシュ

## 6. セキュリティ考慮事項[^7]

- DNSキャッシュポイズニング対策
- DNSSEC導入による認証の確保
- ゾーン転送の制限
- DNSリフレクション攻撃への対策

## 参照

[^1] [https://jprs.jp/related-info/guide/topics-column/no10.html](https://jprs.jp/related-info/guide/topics-column/no10.html)
[^2] [https://www.infraexpert.com/study/tcpip15.html#google_vignette](https://www.infraexpert.com/study/tcpip15.html#google_vignette)
[^3] [https://www.fujitsu.com/jp/services/infrastructure/network/word/dns/](https://www.fujitsu.com/jp/services/infrastructure/network/word/dns/)
[^4] [https://www.value-domain.com/media/dns/](https://www.value-domain.com/media/dns/)
[^5] [https://zenn.dev/chips0711/articles/b468bdef83504b](https://zenn.dev/chips0711/articles/b468bdef83504b)
[^6] [https://sellp.co.jp/2024/09/dns設定の基本：a-aaaa-cname-mx-ns-txtレコードの役割と使い方/](https://sellp.co.jp/2024/09/dns%E8%A8%AD%E5%AE%9A%E3%81%AE%E5%9F%BA%E6%9C%AC%EF%BC%9Aa-aaaa-cname-mx-ns-txt%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E5%BD%B9%E5%89%B2%E3%81%A8%E4%BD%BF%E3%81%84%E6%96%B9/)
[^7] [https://www.onamae.com/column/domain/35/](https://www.onamae.com/column/domain/35/)
「自己開示」の考察


## 仕事にどのように役に立つ？プライベートだけ？

### 📌 **「自己開示」が仕事に役立つ理由**

- 単なる個人的な話ではなく、**仕事の生産性やチームの信頼関係に大きな影響を与えるから**。  
- **自己開示 => 仕事の生産性向上スキル(ソフトスキル？)」** に直結するから。

📌 **具体的なメリット**：
- **信頼関係の向上**：同僚や上司との関係が円滑になり、コミュニケーションコストが下がる。
- **心理的安全性の向上**：安心して意見を言える環境が生まれ、建設的な議論が増える。
- **協力しやすい職場づくり**：相手の価値観を理解すると、役割分担や業務調整がスムーズになる。
- **リーダーシップの向上**：自己開示ができる人は、メンバーの信頼を得やすく、リーダーとしての資質が高まる。
- **問題解決力の向上**：自分の強み・弱みを認識することで、適切な対策を講じやすくなる。

📌 **実際の職場での例**：
```text
 1. リーダーが失敗談を共有することで、メンバが相談しやすくなり、問題の早期発見につながる。
 2. 自身の得意分野や苦手な部分を開示することで、役割分担が明確になり、業務効率が上がる
 3. メンバーが経験を共有することで、新しい視点が生まれ、より良い解決策が見つかる。
 4. パワハラが減る：
   ・先輩メンバ→後輩への技術マウントなどが無くなる
   ・新人が質問や意見を言うブレーキが無くなる
   ・ステルス型のパワハラも無くなる 
```
---

## 🔥 自己開示の「ライフライン」と「自分史」は何が違うのか？

### 📌 **ライフラインとは？**(かなり乱暴に)
- **人生の出来事を「幸福度の上下」と共に振り返るもの**
- **横軸：年齢（過去から現在まで）、縦軸：幸福度（ポジティブ or ネガティブ）**
- **自分がどんなときに幸福度が上がり、どんなときに下がったのかを可視化できる**
- **成長や価値観の変遷が見えてくる**
  
📌 **具体例：**
```text
 - 大学受験失敗（幸福度低）→ 第一志望に合格（幸福度上昇）
 - 初めての転職でキャリアアップ（幸福度上昇）→ 転職後の環境が合わずストレス増（幸福度低）
 - 自営業をスタート(幸福度上昇) → ボートや釣り竿/シュノーケル道具類が警備員ごと盗難され廃業して帰国(幸福度最低×2)
```

### 📌 **自分史とは？**(かなり強引に)
- **過去の出来事を時系列で振り返るもの（幸福度は関係しない）**
- **客観的な事実の列挙が中心**
- **人生の流れを整理し、言語化することが目的**
  
📌 **具体例：**
```text
 - 1996年：高校卒業
 - 2000年：大学卒業
 - 2005年：IT業界に就職
 - 2024年：NW系(Cisco)→クラウド系への転向のため退社
 - 2025年：クラウドエンジニアへ転向
```

### 📌 **ライフラインと自分史の違いの本質は？**(かなり強引)

#### **まずは強引でも定義してしまおう**：
- **ライフラインは「感情の変遷」を軸にする → 自分の価値観が見える**
- **自分史は「事実の整理」が中心 → 出来事を俯瞰するツール**
- **ライフラインを使うと「自分がどう成長したか、何を大切にしているか」が明確になる**
---

## だからなに？

### シェアのサイクルをテンポよく深く回せるチームは仕事効率が高い

- **TAVをシェアし合う仲間がいる**ことで学びが深まりソフトスキル向上が加速(自分ひとりではムリ)。

### 📌 **TAV(TakeAwayValue)をシェアするってなに？**

#### 「自己開示」とセットになるTAVとは「この場から持ち帰る価値」
##### 📌 **感想と価値の区別はどのように？**

1. **「今日の気づき」や「今後の行動に活かせること」ってあるかな？の視点を持つ**
2. **単なる感想ではなく、実践に繋がる学びは何だろうか？**：
  - **感想**：その場の印象や気持ち → 「〇〇の話が楽しかった」「勉強になった」
  - **価値(TAV)**：**行動の元ネタ**→「〇〇の考え方は私も使えそう」「私も△△を実践してみよう」

##### 📌 **TAVをシェアする方法はどのように？**(例)
1. **シンプルに1行で投稿**：  
「今日のTAV：〇〇の考え方が参考になったので～のようにだったら試すことができそうだ。」
2. **リレー形式でシェア**：誰かのTAVを**自分のTAVにアレンジ(パクリもあり？)** してみる
3. **小さな行動とセットにする**：「TAVの実践のために、明日から△△を試す」

---

### 📌 LINEグループでのシェアの仕方？

#### **シェアをする習慣をつけることが、各自の成長を加速？**

##### 📌 **シェアのコツは？**：
- **短くてもOK！簡潔に伝える**
- **TAV（Take_Away_Value）を意識して、「今日の気づき」をシェアする**
- **相手の意見を否定せず、「共感」や「補足」を意識する**
- **日報的なシェアを試す（例：「今日学んだこと」や「やってみたこと」）**

<!-- ##### 📌 **具体的なシェアの方法は？**： -->

#### シェアとTAVは人数が多いと相乗効果が出る:

1. **「振り返り投稿」**
   - 自分の「今週学んだこと」「気づき」「挑戦したこと」をLINEにシェア
   
2. **「TAVシェアリレー」**
   - 1人が気づきをシェア → それに対して他のメンバーが短くLINEにシェア
   - 20秒の短時間でTAV(TakeAwayValue)シェア回しをする「リレーTAV形式」？(勉強会にて) 

3. **「質問型シェア？」**
   - 「こういう問題に直面したけど、皆さんならどうしますか？」をLINEにシェア
---

今回の考察はここまでにしたいと思います。
VATからSkinMatrixを復元する関数の実装メモ

## 実装
```
vec4 fetchElement(float JointIndex, int Offset, float v)
{
    float texelSizeX = 1.0 / vat_ubo.texW;

    vec2 st = vec2(float(JointIndex * 4 + Offset + 0.5) * texelSizeX, v);

    #ifdef USE_OPENGL
    vec4 val = texture(vertexAnimationTexture, st);
    #else
    vec4 val = texture(sampler2D(vertexAnimationTexture, vertexAnimationTextureSampler), st);
    #endif

    return val;
}

mat4 GetSkinMatFromVAT(uint JointIndex, int FrameIndex)
{
    float f_JointIndex = float(JointIndex);
    float texelSizeY = 1.0 / vat_ubo.texH;

    float v = (float(FrameIndex) + 0.5) * texelSizeY;

    mat4 SkinMatrix = mat4(
        fetchElement(f_JointIndex, 0, v),
        fetchElement(f_JointIndex, 1, v),
        fetchElement(f_JointIndex, 2, v),
        fetchElement(f_JointIndex, 3, v)
    );
    
    return SkinMatrix;
}

void main()
{
    mat4 SkinMat =
        inWeights0.x * GetSkinMatFromVAT(inJoint0.x, CurrentFrame) +
        inWeights0.y * GetSkinMatFromVAT(inJoint0.y, CurrentFrame) +
        inWeights0.z * GetSkinMatFromVAT(inJoint0.z, CurrentFrame) +
        inWeights0.w * GetSkinMatFromVAT(inJoint0.w, CurrentFrame);
}
```
## ポイント
// テクスチャに焼いたデータを使う時はテクセルの中心からサンプリングすることを心がける(texelSizeX * 0.5 を足す)
// これを足さない時の値はテクセルの左下、つまりテクセルとテクセルの境界線を差している
// もしこのままだと補完時にとなりのテクセルの影響を受けて、意図しない値が返ってくることがある
// この結果、ボーンの動きがブレたり、不安定になるといったことが起こる。
// VATにはGL_RGBA32F, GL_FLOATのテクスチャに対して、GL_NEAREST・CLAMP_TO_EDGEのサンプラーを適応している
// GL_NEARESTはサンプリングに最も近い値に補完して返す機能だが、テクセル境界のままだとこれで混ざってしまう
// 用語整理 /////
// - ピクセル: 画面上の最小単位(ディスプレイのドット)
// - テクセル: テクスチャ画像内の最小単位(テクスチャのピクセル)
////////////////
【AWS SAP】Application Migration Service エージェント とApplication Discovery Service エージェントは違う？

# 結論
AWSのサービスが違う。
Application **Migration** Service エージェント→ Application **Migration** Service（MGN）
Application **Discovery** Service エージェント → Application **Discovery** Service（ADS）


## 違いについて

### Application Migration Service（MGN）エージェント
- **目的**: オンプレミスのサーバーをAWSに移行するためのレプリケーション  
- **動作**:
  - MGNエージェントをオンプレミスのサーバーにインストール  
  - データをリアルタイムでAWSにレプリケート  
  - AWS上でEC2に変換し、カットオーバー  
- **使用タイミング**: AWSへのサーバー移行を行う際  
- **エージェントのインストール**: 必須（Windows/Linuxサーバーにインストール）  

### Application Discovery Service（ADS）エージェント
- **目的**: オンプレミス環境のインベントリ（ハードウェア・ソフトウェア・ネットワーク情報）の収集  
- **動作**:
  - ADSエージェントをオンプレミスのサーバーにインストール  
  - OS、プロセス、ネットワーク情報、リソース使用状況を収集  
  - AWS Migration Hub にデータを送信し、移行計画を立てるための分析に使用  
- **使用タイミング**: AWS移行前の調査・分析  
- **エージェントのインストール**: オプション（エージェントレス方式も可能）  

### まとめ

| No | 項目                          | MGN エージェント                       | ADS エージェント                          |
|----|--------------------------------|----------------------------------|----------------------------------|
| 1  | サービス                       | Application Migration Service   | Application Discovery Service   |
| 2  | 目的                           | サーバーのAWS移行               | オンプレミス環境の調査・分析     |
| 3  | データの送信先                  | AWS (EC2)                        | AWS Migration Hub               |
| 4  | 必要なエージェント              | 必須                              | オプション（エージェントレスも可能） |
| 5  | 収集情報                       | ディスク・メモリ・CPUの変更をリアルタイム同期 | OS、プロセス、ネットワーク、リソース使用率 |
| 6  | 主な利用タイミング              | AWSへの移行時                     | 移行計画のための調査              |

### 結論
- **移行のためにサーバーのデータをAWSにレプリケートするなら** → **MGNエージェント**  
- **移行前にオンプレミス環境の調査・分析をしたいなら** → **ADSエージェント**
Docker 環境で Air を使ったホットリロード時の「main: not found」エラーの解決方法

## はじめに

今回は、Docker コンテナ上で Go の開発環境を構築し、[Air](https://github.com/air-verse/air) を利用してホットリロードを実現していた際に発生したトラブルシューティングの内容をまとめました。  
最終的に、Air の設定を修正することでエラー「`/bin/sh: 1: main: not found`」が解消し、正常にサーバーが起動するようになりました。

## 環境構成

以下のようなツリー構造でプロジェクトを構成しています。

```
.
├── api
│   ├── cmd
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── main.go
│   │   └── .air.toml
│   ├── docker
│   │   └── Dockerfile         # 本番用 Dockerfile
│   └── docker.dev
│       └── Dockerfile         # 開発用 (Air 利用) Dockerfile
├── app
│   ├── src                   # フロントエンドのソースコードなど
│   └── docker
│       └── nginx
│           └── default.conf
└── docker-compose.yml
```

`docker-compose.yml` では、`api` サービスは `./api` をコンテキストとして、`docker.dev/Dockerfile` を使ってビルドしています。また、ホストの `./api/cmd` をコンテナ内の `/app` に volume マウントしており、Air を起動する構成になっています。

## 発生したエラー

開発用 Dockerfile（`api/docker.dev/Dockerfile`）では以下のように Air を起動しています。

```dockerfile
...
EXPOSE 8080
CMD ["air"]
```

しかし、コンテナのログを見ると以下のようなエラーが発生していました。

```
[06:41:11] running...
/bin/sh: 1: main: not found
...
[06:41:57] running...
[06:41:57] Process Exit with Code: 127
/bin/sh: 1: main: not found
```

また、コンテナ内で `netstat` コマンドを使ってもポート 8080 で待ち受けしているプロセスは確認できませんでした。

## エラー原因

Air は、`.air.toml` の設定に基づいてアプリケーションをビルドし、生成されたバイナリを起動しようとします。  
今回、`.air.toml` の設定で `bin` および `full_bin` に `"main"` と指定していたため、Air はカレントディレクトリ内から `main` というコマンドを探していました。

しかし、Linux ではカレントディレクトリは PATH に含まれていないため、実行ファイルを起動するには `./main` と明示的に指定する必要があります。その結果、Air はビルドに成功しても、実行時に `main` を見つけられずエラーが発生していました。

## 解決方法

### 1. `.air.toml` の修正

`.air.toml` の設定ファイルを下記のように修正しました。

```toml
[build]
cmd = "go build -o main ."
bin = "./main"
full_bin = "./main"

[log]
time = true

[color]
main    = "yellow"
watcher = "cyan"
build   = "green"
runner  = "magenta"
```

これにより、Air は `./main` としてバイナリを実行するため、正しく起動できるようになりました。

### 2. 補足：PATH の設定変更（別案）

別の解決策として、Dockerfile 内でカレントディレクトリを PATH に追加する方法も考えられます。  
例えば、以下のように環境変数を設定すれば、`main` を直接実行できるようになります。

```dockerfile
ENV PATH="/app:${PATH}"
```

ただし、今回は Air の設定を修正するほうがシンプルで分かりやすかったため、この方法は採用しませんでした。

## 結果

修正後、Air のログにはビルドと実行が正常に行われた旨のメッセージが表示され、コンテナ内で `ss -tln` コマンドで確認したところ、`0.0.0.0:8080` でサーバーが待ち受ける状態になりました。  
これにより、ホストから `localhost:8080` へアクセスすると正しくレスポンスが返却されるようになりました。

## まとめ

- **エラーの原因**  
  - Air の設定で実行するバイナリのパスが `"main"` となっており、PATH にカレントディレクトリが含まれていないため、実行できなかった。
- **解決策**  
  - `.air.toml` の `bin` と `full_bin` を `./main` に変更することで、ビルドしたバイナリを正しく実行できるようにした。
- **補足**  
  - Docker コンテナ内ではサーバーが外部アクセス可能になるよう、Go のサーバーコードで `http.ListenAndServe("0.0.0.0:8080", handler)` とする必要がある点にも注意する。

今回のトラブルシューティングを通して、Air の設定や Docker コンテナ内での実行環境について改めて理解を深めることができました。  
皆さんの開発環境構築の参考になれば幸いです。
【JavaScript】配列とオブジェクトについて

# はじめに
現在`React`を学習しています。その中で「***配列***」と「***オブジェクト***」の違いについて理解が曖昧だったので、整理するために記事を書きました。

:::note warn
***この記事は<font color="Red">個人的なアウトプット</font>を目的として作成したものです。そのため、誤った情報や不足している内容が含まれている可能性があります。もし間違いや気になる点がございましたら、ぜひご指摘いただけますと幸いです***。
:::

# 配列とは
配列（`Array`）は、複数のデータを順序を持って管理するデータ構造です。
+ `[]`で囲まれたデータの集合
+ 各要素には**インデックス**（0から始まる番号）が割り振られる
+ データの順番が重要
 
## 書き方
```js
const sports = ["soccer","basaball","basketball"];
console.log(sports);
```
```console
["soccer","basaball","basketball"]
```
```js
console.log(sports[0]); // "soccer"
console.log(sports[1]); // "baseball"
```
# オブジェクトとは
オブジェクト（`Object`）は、***キー***と***値***のペアを持つデータ構造です。
+ `{}`で囲まれている
+ ***キー***（プロパティ名）を使って値を取得する
+ 配列と違って順番は保証されない

## 書き方
```js
const sports = { name: "soccer", players: 11 };
console.log(sports);
```
```console
{ name: "soccer", players: 11 }
```
```js
console.log(sports.name); // "soccer"
console.log(sports.players); // 11
```

# 連想配列
「***連想配列***」という用語は言語によって定義が異なりますが、`JavaScript`ではオブジェクト（`Object`）が連想配列の役割を果たします。

```js
const sports = { name: "soccer", players: 11 };
console.log(sports["name"]); // "soccer"
console.log(sports["players"]); // 11
```
# 終わりに
`JavaScript`では配列（`Array`）とオブジェクト（`Object`）の使い分けが重要です。2つの違いに注意しながら引き続き学習を進めていきます。

# 参考

配列とオブジェクトの違い（JavaScript）Qiita

https://qiita.com/Pirori3182/items/bfedfb080099dc5d7f44

【JavaScript】配列とオブジェクトの違い Zenn

https://zenn.dev/miya_akari/articles/3e6c909d98aeea

https://jsprimer.net/basic/object/
【AWS SAP】絶対暗記備忘録

# 絶対暗記備忘録
- 「AWS Snowball Edge Storage Optimized」、「AWS DataSync」、「Amazon S3 ファイルゲートウェイ」は、バックアップファイルの一括転送を行う方法のため、連続的なリアルタイム同期は不可。
→AWS Database Migration Service（AWS DMS）が適切

:::note info
ダウンタイムを最小限 → **AWS DMS**
:::
---

## AWS control tower

AWS control tower のガードレールは、以下の3つがある。
- **必須（Mandatory）** → 強制適用（デフォルトで有効、無効化不可）
- **強く推奨（Strongly Recommended）** → デフォルト無効だが、有効化を推奨
- **推奨（Recommended）** → 参考レベル、必要に応じて設定

動作は以下の2つ
- **予防（Preventive）** → ポリシーによって制限をかけ、違反を防ぐ
    - 例: ルートユーザーのMFA必須、特定のリージョンでのリソース作成を制限
    - 実装方法: Service Control Policies (SCPs) や AWS Config ルール
　
- **検出（Detective）** → 違反を検出し、アラートを通知
    - 例: S3 バケットのパブリックアクセス設定を監視、ログ記録の有無を確認
    - 実装方法: AWS Config ルール

:::note info
EBSボリュームが暗号化されていることを確認 → **ガードレールの強く推奨**を有効化
:::

## API Gateway
:::note info
使用量プラン → **API Gateway REST API** のみ使用可
:::
PowerVS IBM i 日記(66): PER 環境の利用(3) - TGW で東阪の PowerVS を接続する

今回は TGW を使って東阪の PowerVS を接続します。

# 接続する PowerVS

これまで、TOK04 の下記の PowerVS を利用してきました。

|項目|データ|
|:-|:-|
|DC| TOK04|
|WS名| onoda-tok04-2|
|サブネット| 192.168.100.0/24|
|VSI IP アドレス| 192.168.100.10|

今回、OSA21 に下記の PowerVS を作成し、東阪の PowerVS接続を確認します。

|項目|データ|
|:-|:-|
|DC| OSA21 |
|WS名| onoda-osa21-2|
|サブネット| 192.168.200.0/24|
|VSI IP アドレス| 192.168.200.10|

PowerVS 部分の構築手順は「[PowerVS IBM i 日記(64): PER 環境の利用(1) - PER 環境を用意する](https://qiita.com/6onoda/items/21e8f08f8eebed2abb5c)」と同じため省略します。

# TGW に「onoda-osa21-2」を追加

「[PowerVS IBM i 日記(65): PER 環境の利用(2) - TGW で VPC と接続する](https://qiita.com/6onoda/items/bc32700afd80b0e45d71)」で作成した TGW に「onoda-osa21-2」の接続を追加します。

しかし、PowerVS のロケーションとして「TOK04」しか選べません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/6f6a5b2d-465a-70bf-1e55-b2ff60e1cdf1.png)

これは、前回作成した時に「ローカル」の TGW として作成したためです。「ローカル」の TGW は同じ MZR 内の資源にしか接続対象にできません。

そこで「ルーティング」を「グローバル」に変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/d3c95c3e-3a3d-b3a0-f03d-6a1ad3bea701.png)

今度は、OSA21 も選べます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/582f6be9-6ce9-dca6-be61-ba7bdb16dbf8.png)

今回利用する「onoda-osa21-2」を選択して「追加」します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/0be70d4e-35a5-d376-5b5c-4e005865fc27.png)

「経路」タブで「レポートの生成」を実行すると「onoda-osa21-2」へのルートが追加されているのが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/360094ed-979e-f5d5-5071-2a2b57d33d0a.png)

「BGP」タブでも AS パスが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/7a076e3f-044f-5b3f-fe06-accd3dddfe61.png)

# 疎通確認

OSA21 の PowerVS VSI から TOK04 の VSI に ping します。接続できています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/d11a1795-166b-c89a-1c9c-d6da798938cd.png)

逆方向も試します。問題ありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/92b0bccb-8093-b686-4394-0b3274c1c1e5.png)

「[PowerVS IBM i 日記(19): プライベート・ネットワークで接続した IBM i 間で Power HA の地域的ミラーを構成する](https://qiita.com/6onoda/items/1b98c28db3942a1c3a79)」で同じワークスペース内での Power HA の地域的ミラーを構成しました。この時はアンチアフィニティを利用した筐体障害を想定したものでした。

しかし、TGW で接続すれば同じ手順で DC をまたがった DR/ 災害対策を構成することができます。

もちろん、OSA21 の PowerVS VSI から TGW で接続されている東京の VPC への接続も可能です。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/4b643428-62bc-7e95-deb4-57efee6934e7.png)

---
当日記のIndexは[こちら](https://qiita.com/6onoda/items/f146c78c0c1bbe905a42)です。

---
許可の無い転載を禁じます。
この記事は筆者の個人的な責任で無保証で提供しています。
当記事に関してIBMやビジネスパートナーに問い合わせることは、固くお断りします。
ブラウザの「戻る」ボタンから戻ったら、フォームをリセットしたい

### 問題

`<form>`を`POST`したあとで、遷移先のページから「戻る」ボタンで戻ると、フォームには送信したレコード（データ）が残っています。この状態で再度`POST`すると、レコードが2重に登録されます（手抜きなコードなもので）。

この問題に対し、最初は「戻る」ボタンそのものを無効化しようとしました。Qiita の「[ブラウザの戻るボタンを依存ライブラリ無しで戻れなくする方法](https://qiita.com/yo-nagase/items/3af92fb7a81624a9927f)」（2019年5月）や Stack Overflow の「[How can I stop the browser back button using JavaScript?](https://stackoverflow.com/questions/12381563)（回答は2015年12月）などにも、次のような、ブラウザ履歴を操作する解法が掲載されています。

```javascript
history.pushState(null, null, null);
window.addEventListener('popstate', function (evt) {
    history.pushState(null, null, null);
});
```

しかしこの手は、最近（2025年2月現在）は Firefox くらいでしか動かないようです。なんでもセキュリティ上の問題のせいらしいです。


### 解法

`pageshow`イベントが発生したらフォームをリセットする。


### 説明

MDNの「[Window: pageshow イベント](https://developer.mozilla.org/ja/docs/Web/API/Window/pageshow_event)」に依れば、このイベントは次のようなときに発火します。

- 最初にページを読み込んだとき
- 同じウィンドウまたはタブの中で、他のページからそのページへ移動してきたとき
- モバイル OS で凍結されたページを復元したとき
- ブラウザーの進む、戻るボタンを利用してこのページに戻ったとき

あとは、このイベントときにフォームをリセットします。`<form id="order">`がターゲットのときの例を次に示します。

```javascript
window.onpageshow = function() {
    let elem = document.getElementById('order');
    elem.reset();
};
```

### おわりに

「戻る」をさせたくないのは基本設計がもともとしょぼいからです。ちゃんと設計し直せばよい、は王道ですが、まぁ、そこまで気力のないときもあります。