OmniAICreator/Qiita-1.07M huggingface dataset:
Kolinのジェネリクス

Kotlinで身長を表示する処理があった場合、その引数で複数の型を使用したいときに同じ関数名を書いて引数名のみ変更するとプログラム側が引数を自動で型を判断してくれる。

```kotlin
fun main() {
    val height = Height()
    val height2 = Height()
    val height2 = Height()

    height.Print(3)
    height2.Print(20.5)
    height3.Print("20.5")
}

class Height {
    fun Print(value: Int) {
        println("身長は${value} cm")
    }

    fun Print(value: Double) {
        println("身長は${value} cm")
    }

    fun Print(value: String) {
        println("身長は${value} cm")
    }
}
```

処理が同じの場合、ジェネリクス`<T>`を使用すれば1つにまとめることができる。下記コードは上記と同じ処理を行うことができ、簡単で保守しやすい。

```kotlin
class Height {
    fun <T> Print(value: T) {
        println("身長は${value} cm")
    }
}
```
Apexでのエラー




+ [Apexエラー「 Attempt to de-reference a null object」の原因特定方法について](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000UU8C)

:::note alert
An Apex error occurred: System.NullPointerException: Attempt to de-reference a null object 
48221c335b9a0c1b6f3026381fe9195405d1466-3a60 
:::

:::note
デバッグログを取得して確認したところ解決しました。 
CSVで一括登録した際に、選択リスト項目のAPI名でなく表示名で登録したため 
デバッグログに「IDで指定してください」のエラーが記載されていました。 

無効な値となっていたこれらを既存のリストに置換して、フローをデバッグしたところ無事に実行でき、 
選択リスト項目を定義された値にリストに制限するよう変更して、今後表示名で登録できないようにしました。 
:::

# エラー

+ [Class compilation requires too much metadata. Please consider splitting this class into multiple classes](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000JecrM)

:::note
You can write only 1 million character per class and your class character count is greater then this so you need to break it into multiple sub classes.
クラスごとに 100 万文字しか記述できず、クラスの文字数がこれよりも多いため、複数のサブクラスに分割する必要があります。

https://salesforce.stackexchange.com/questions/195277/class-compilation-requires-too-much-metadata
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/0a91d782-0937-5ba2-5f34-1c8032f47434.png)

+ [Apex バッチでのエラー](https://qiita.com/Keiji_otsubo/items/df94d9df2dbe8144054d)



+ [Can someone help me understand these Aura Component Errors?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007LqgXl)

:::note alert
+ Action failed: aura:iteration$controller$itemsChange [Invalid regular expression: /(.+?)(?:\:(\d+))?(?:\:(\d+))?$/: Stack overflow]
+ Action failed: aura:iteration$controller$itemsChange [Maximum call stack size exceeded]
:::

+ [Navigating to a report from a aura component](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Tt9hj)

:::note
Please change the url parameters
 
```
"url": reportId
```

-->

```
"url": "/lightning/r/Report/" & reportId  & "/view?queryScope=userFolders"
```

:::
Failure when saving an HTTP call out in flow



# Failure encountered while saving (2104936353)

+ [Failure when saving an HTTP call out in flow](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007es0VLSAY)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a8bb1d53-89ee-40f2-8bec-6b7bf4fe4c0b.png)

:::note
Based on above gack id, below is the error. 

ServiceException: Add a unique External Service Name
:::

# Failure encountered while saving (455614924)

+ [【未解決】Failure when trying to save HTTP callout in flow](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000KDk6L0AT)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9da91591-2c9e-4743-8f22-dd343b52af67.png)

+ [【未解決】Getting Error on Save HttpCallout in Flow](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000Ur3p0AC)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/31d39008-4909-4dad-a3b5-dde7ddd3bb41.png)

:::note
そうでない場合、同じエラーが発生しました。私の場合は、セットアップ中に外部サービスに同じ名前を使用したためでした。
:::
スクリーンフローでのエラー



+ [画面フローでのエラー「Lightning Experience ではこの項目を表示できません。 Salesforce Classic で開いてください。」](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007F1vPF)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/8d0e2fcb-a4cd-0206-5883-ac3cb7a6882a.png)

:::note
カスタムボタンのURLを修正することで解決しました
:::

+ [INVALID_TYPE_ON_FIELD_IN_RECORD Field Name value not of required type](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ahBIMSA2)

:::note

チェックボックスに null 値を割り当てていると思います。 if (checkbox = null) false、チェックボックス、という数式を作成する必要があります。そうすれば、null 値は送信されず、false 値が送信されます

I think it's assigning a null value to the checkbox, you should create a formula that says if (checkbox = null) false, checkbox, that way its not sending a null value its sending a false value
:::

+ [INVALID_TYPE_ON_FIELD_IN_RECORD: 測量-実測精算あり: 必須種別以外の値: ]()

:::note
レコードを作成する際に画面表示項目を直接割り当てているのかと思います。

「画面に表示されない = nullの値」のため、TrueかFalseの値しかとらないチェックボックス項目へ画面へ表示されていない項目を割り当ててしまうとエラーになります。

そのため、画面表示項目を直接割り当てるのではなく、下記のような数式を作成して割り当てする必要があります。

```
IF( OR( 画面表示項目 , NOT( 画面表示項目 ) ) , 画面表示項目 , False )
```

:::

+ [Experience Cloud サイトでスクリーンフローが機能しない](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000HDqI1)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/91c5cec8-560b-646e-e266-699d9cf22014.png)

:::note
別のサイト テンプレートを使用しましたが、その場合は機能しているようです。「独自に構築する」テンプレートでは機能しない理由はわかりませんが、この解決策で問題ありません。
:::

+ [This is a placeholder. Flows don't run in the canvas](https://qiita.com/Keiji_otsubo/items/45a570905c803a3c9b4e)

# This field is managed in object manager. Your permissions affect the update compatible and create compatible values displayed here, but the running user’s permission control their access at run time.

+ [Persistent Error on Flows](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007erIT2SAM)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/5e44df74-f43b-e4db-97f0-535a3b5ca04c.png)

# Unexpected Error when retrieving 'Case' Layout Information: Layout contains no sections!

+ [Screenflow Error - Unexpected Error when retrieving 'Case' Layout Information: Layout contains no sections!](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ifuGb)

:::note
I resolved this by providing the profile with read to the field i was using on the screenflow. The error message was very unclear of the actual issue.

画面フローで使用していたフィールドに読み取りを伴うプロファイルを提供することで、これを解決しました。エラー メッセージは実際の問題について非常に不明確でした。
:::
USB OTGのVBUS

USBのOTGで以下のような回路のものがあります。

![OTG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/7cdae3af-bbab-4e0c-8010-bf07bfc7bf6d.png)

GPIOの先にはNCP382のよう電源制御用のチップが付いていて、電源が衝突しないようにしています。

Hostになる場合は、GPIOを制御してVCCをVBUSに出して、相手のDeviceにも送ります。

Deviceになる場合は、GPIOを制御してVCCを止めて、Host側からのVCCをVBUSで受けます。
.tsxと.tsの使い分けと理由

Next.js勉強中です。
最近Next.jsを初めてインストールしてみました。
拡張子.tsxとは？っとなったのでメモします。

.tsxは「TypeScript + JSX」**を意味する拡張子

**「TypeScript で JSX（React の HTML っぽい記法）を書くためのファイル」**

## **📌 `.tsx` と `.ts` の使い分け まとめ**

| 拡張子 | 使うべき場面 | 例 |
| --- | --- | --- |
| **`.tsx`** | JSX を使う（コンポーネント & ページ） | `app/page.tsx`, `app/components/Button.tsx` |
| **`.ts`** | JSX を使わない（関数・API・型） | `app/lib/utils.ts`, `app/types/index.d.ts` |

---

## **✅ `tsx` だけで統一するとどうなる？**

もし **Next.js ですべて `.tsx` に統一すると…**
❌ **関数だけのファイルでも JSX を意識する必要がある（無駄）**

❌ **型定義だけのファイルでも `.tsx` を使うことになり、違和感がある**

❌ **不要な JSX のチェックが入ってしまい、コンパイル時間が長くなる**

---

## **🚀 まとめ**

✅ **「Reactコンポーネント & ページ」は `.tsx`**

✅ **「関数・API・型定義」は `.ts`**

✅ **全部 `.tsx` で統一すると不要なオーバーヘッドが発生するので非効率**

Next.js では **「画面を作る部分は `.tsx`」「ロジックや型だけの部分は `.ts`」** というルールで使い分けるのが最適！✨
MacでEFIパーティションをマウントする。

# はじめに
先日、USBタイプの外付けSSDに業務用の複合プリンタでスキャンしたPDFファイルを保存したところ、保存したPDFがMacbookで表示されず、四苦八苦したので、記事に残しておこうと思います。

# 複合プリンタでのPDF保存
よく行っているコワーキングスペースのプリンタを使って領収書をスキャンしてPDF保存したところ、以下のようにプリンタの画面上はファイルが保存されているのですが、Macbookで見ると何も表示されないという問題に当たりました。

![Monosnap_20250215_220717.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/71952823-0d76-4ccb-a46d-592dec4cf3e4.png)

フィーマット形式が違ったのかなと思い、再フォーマットも実施してみましたが、フォーマットを行ったのに、プリンタにUSBを接続すると、変わらず先程のファイルが表示されました。

# 読めない領域の調査
フォーマットしたのにプリンタ上からは見えているということで、これは違う領域に保存してるな・・・と思い、再度ディスクユーティリティーを見てみましたが、やはりフォーマットした領域しか表示されません。

![Monosnap_20250215_221335.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/6e6f720a-0649-43a2-af88-9a6d6370cff9.png)

ただ、「**装置**」の部分を見ると、フォーマット時、パーティションは切っていなかったつもりですが、`disk4s2`となっており、表示も「**すべてのデバイスを表示**」にしているにもかかわらず、`disk4s1`が見当たりませんね。

GUIなんかに頼っていられんということで、`diskutil`コマンドでUSBデバイスを見た結果が以下となります。

```bash:USBパーティションの確認
diskutil list disk4
```

```bash:コマンド実行結果
/dev/disk4 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *250.1 GB   disk4
   1:                        EFI NO NAME                 209.7 MB   disk4s1
   2:       Microsoft Basic Data EXSSD                   249.8 GB   disk4s2
```

ディスクユーティリティー上は表示されていなかった`disk4s1`の領域がありますね。

というわけで、同じく`diskutil`コマンドで`disk4s1`をマウントします。

マウントは`sudo`を付けないと失敗するので`sudo`付きで実行します。

```bash:EFI領域のマウント
sudo diskutil mount disk4s1
```

エラー無く無事マウント完了。

コマンド上からもGUI上からもちゃんとEFIの領域が表示され、中のファイルも問題なく見れました。

```bash:マウント後のdf結果
$ df -h /dev/disk4s*
Filesystem      Size    Used   Avail Capacity iused ifree %iused  Mounted on
/dev/disk4s1   197Mi   964Ki   196Mi     1%       0     0     -   /Volumes/NO NAME
/dev/disk4s2   233Gi    13Mi   233Gi     1%       1     0  100%   /Volumes/EXSSD
```

![Monosnap_20250215_212306.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/b9df2a93-4002-4554-9320-45832a5c38ed.png)

# PCでファイルが見えなかった原因
購入したUSBタイプのSSDをMacbookのディスクユーティリティーからフォーマットを行っていたのですが、フォーマットタイプが「**ExFAT**」で、方式が「**GUIDパーティション**」としていたのが原因だったようです。

ちなみにフォーマットタイプを「**MS-DOS (FAT)**」、方式を「**マスターブートレコード**」に変えて再フォーマット＆ファイル保存したら特に`diskutil`からマウントしたりしなくても普通に見れました。

# おわりに
今回使用したコワーキングスペースのプリンタはUSBへの保存は無料で使えたので費用はかかりませんでしたが、コンビニのプリンタを使っていたらいくらか無駄な費用とコンビニに何度も行く手間、周りの人からの圧で心が折れていたかもしれません。
Difyのdataset_collection_bindingsテーブルにおけるprovider_nameカラムの長さ変更手順

## はじめに
Difyを使用中に`provider_name`カラムの文字数制限に関するエラーが発生した場合、データベースのカラム長を拡張する必要があります。本記事ではDocker環境での変更手順を解説します。

## 前提条件
- Dockerがインストール済み
- DifyがDockerコンテナで実行されている

## 操作手順

### 1. Dockerデータベースコンテナへの接続
```bash
docker exec -it docker-db-1 bash
```

### 2. Difyデータベースへの接続
```bash
psql -d dify
```

### 3. カラム定義の変更
```sql
ALTER TABLE dataset_collection_bindings
ALTER COLUMN provider_name TYPE VARCHAR(255);
```

### 4. 変更内容の確認
```sql
\d dataset_collection_bindings;
```

## 実行結果の例
```
                             Table "public.dataset_collection_bindings"
     Column      |            Type             | Collation | Nullable |           Default
-----------------+-----------------------------+-----------+----------+------------------------------
 id              | uuid                        |           | not null | uuid_generate_v4()
 provider_name   | character varying(255)      |           | not null |
 model_name      | character varying(255)      |           | not null |
 collection_name | character varying(64)       |           | not null |
 created_at      | timestamp without time zone |           | not null | CURRENT_TIMESTAMP(0)
 type            | character varying(40)       |           | not null | 'dataset'::character varying
Indexes:
    "dataset_collection_bindings_pkey" PRIMARY KEY, btree (id)
    "provider_model_name_idx" btree (provider_name, model_name)
```

## 簡単にコマンド1つで実施

変更コマンド：

```
docker exec -i docker-db-1 psql -d dify -c "ALTER TABLE dataset_collection_bindings ALTER COLUMN provider_name TYPE VARCHAR(255);"
```

確認コマンド：

```
docker exec -i docker-db-1 psql -d dify -c "\d dataset_collection_bindings;"
```

## 注意事項
- 本操作はテーブル構造を変更するため、事前にデータベースのバックアップを推奨します
- 本番環境で実行する場合はメンテナンス時間を確保してください
- マイグレーションファイルがある場合は併せて更新が必要です

## 参考リンク
[GitHub Issue #13921](https://github.com/langgenius/dify/issues/13921)
[GitHub Issue #14593](https://github.com/langgenius/dify/issues/14593)


## まとめ
VARCHAR(255)への変更により、より長いプロバイダ名の格納が可能になります。Docker環境でのデータベース変更の参考になれば幸いです。
Difyデータベースマイグレーション実践ガイド：Flask-Migrate運用とカラム変更事例  



## はじめに  
Difyプロジェクトにおけるデータベース変更管理には**Flask-Migrate**が標準で採用されています。本記事では、基本的なマイグレーション手順から具体的なテーブル修正事例まで、実際の運用フローを解説します。  

---

## 基本コマンド一覧  
```bash  
# 変更検出＆マイグレーションスクリプト生成  
flask db migrate -m "alter_user_table"  

# 変更をデータベースに適用  
flask db upgrade  

# 現在のマイグレーション状態確認  
flask db current  
```  

---

## 標準作業フロー  

### 1. モデル定義の修正  
`models.py` ファイルでデータベーススキーマを変更  
```python  
# 例: カラム長の変更  
provider_name = db.Column(db.String(255), nullable=False)  # VARCHAR(255)に拡張  
```  

### 2. マイグレーションスクリプト生成  
```bash  
flask db migrate -m "extend_provider_name_to_255_chars"  
```  
→ `migrations/versions` 配下に新しいスクリプトが生成  

### 3. スクリプト内容の確認  
生成されたファイルで自動生成されたALTER文をチェック  
```python  
# 生成されるコード例  
def upgrade():  
    with op.batch_alter_table('dataset_collection_bindings', schema=None) as batch_op:
        batch_op.alter_column('provider_name',
               existing_type=sa.VARCHAR(length=40),
               type_=sa.String(length=255),
               existing_nullable=False) 
```  

### 4. 変更の適用  
```bash  
flask db upgrade  
```  

### 5. 変更のバージョン管理  
```bash  
git add migrations/versions/[生成されたファイル名]  
git commit -m "db: extend provider_name column length"  
```  
---

## 本番環境での適用  
デプロイ時にコミット済みの変更を反映:  
```bash  
flask db upgrade  
```  

---

## 重要ポイント  

✅ **必須チェック項目**  
1. 自動生成スクリプトのSQL文は必ず目視確認  
2. 開発/ステージング環境でテスト後に本番適用  
3. 複数環境で作業する場合は`migrations`フォルダの同期を厳守  




---

## まとめ  
Flask-Migrateを活用することで：  
- データベース変更のバージョン管理が可能  
- チームメンバー間のスキーマ不一致を防止  
- ロールバック時の安全な復旧手順を提供  

「モデル修正 → スクリプト生成 → テスト環境適用 → 本番反映」のフローを厳守し、データベース構造変更の安全性を確保しましょう。
DockerでOracle Database 23ai FreeをセットアップしMAX_STRING_SIZEを拡張する手順



## はじめに
Oracle Database 23ai FreeをDocker環境でセットアップし、拡張文字列サイズ（MAX_STRING_SIZE=EXTENDED）の設定とPDB操作を行う手順を解説します。開発環境構築時の参考にしてください。

## 環境準備
### ディレクトリ作成
データ永続化用のディレクトリを作成（権限設定は開発環境用）：
```bash
mkdir -p /u01/data/free23ai/
chmod 777 /u01/data/free23ai/  # 本番環境では適切な権限設定を推奨
```

### Dockerコンテナ起動
Oracle Database 23c Freeのコンテナを起動：
```bash
docker run -d --name oracle-db \
  -p 1521:1521 \
  -e ORACLE_PDB=FREEPDB1 \
  -e ORACLE_PWD=<任意のパスワード> \
  -v /u01/data/free23ai/:/opt/oracle/oradata \
  container-registry.oracle.com/database/free:23.7.0.0-amd64
```

## データベース設定変更
### コンテナ内でSQL*Plus起動
```bash
docker exec -it oracle-db bash
sqlplus / as sysdba
```

### PDB操作と文字列サイズ拡張
```sql
-- PDB状態確認
SHOW PDBS;

-- PDBをアップグレードモードで再オープン
ALTER PLUGGABLE DATABASE FREEPDB1 CLOSE;
ALTER PLUGGABLE DATABASE FREEPDB1 OPEN UPGRADE;

-- コンテナ切り替え
ALTER SESSION SET CONTAINER=FREEPDB1;

-- 文字列サイズ拡張設定
ALTER SYSTEM SET MAX_STRING_SIZE=EXTENDED;

-- 変更適用スクリプト実行
@?/rdbms/admin/utl32k.sql

-- 通常モードで再起動
ALTER PLUGGABLE DATABASE FREEPDB1 CLOSE;
ALTER PLUGGABLE DATABASE FREEPDB1 OPEN;
```

### 設定検証
```sql
-- 拡張文字列サイズでのテーブル作成テスト
CREATE TABLE large_text_table (
    large_text_column VARCHAR2(20000)
);

DROP TABLE large_text_table;
```

## 管理者ユーザー作成
```sql
-- DBA権限付与
CREATE USER admin IDENTIFIED BY <パスワード>;
GRANT DBA TO admin;
GRANT EXECUTE ON CTX_DDL TO admin;  -- Text検索機能利用の場合
```

## 注意事項
1. データ永続化のためボリュームマウントを実施
2. `MAX_STRING_SIZE`変更はデータベース作成直後のみ可能
3. 本番環境では権限設定を見直し（777は開発用）
4. パスワードは強固なものを設定



## まとめ
Dockerを使ったOracle Databaseのセットアップと重要な設定変更の流れを解説しました。開発環境構築の参考になれば幸いです。本番環境ではセキュリティ設定の見直しをお忘れなく！
個人的備忘録：AWS CLI に登録されている認証情報とリージョン設定を削除するベストプラクティスについて

## はじめに

AWS CLI に登録された認証情報や設定を削除するには、以下の方法があります。  

- `rm -rf ~/.aws/credentials` で **認証情報を削除**  
- `rm -rf ~/.aws/config` で **リージョン設定を削除**  
- **すべての設定を一括で削除する場合** は、`rm -rf ~/.aws/` を実行  

削除後は、`aws configure list` で設定が削除されたことを確認することをおすすめします！

## 1. AWS 認証情報を削除する
AWS CLI に保存されている `access_key` や `secret_key` を削除するには、以下のコマンドを実行します。

```sh
rm -rf ~/.aws/credentials
```

このコマンドを実行すると、認証情報が完全に削除されます。

**実際のターミナル画面**

![Screenshot 2025-03-02 at 8.00.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/ced47ab0-dbe9-4984-88c0-ee23c1077e96.png)

## 2. AWS 設定ファイルを削除する
Terraform などで利用されるリージョン情報やプロファイル設定を削除する場合は、以下のコマンドを実行します。

```sh
rm -rf ~/.aws/config
```

この操作により、AWS CLI の設定情報がリセットされます。

## 3. すべての AWS 設定を一括削除
認証情報 (`credentials`) と設定 (`config`) の両方を削除する場合は、以下のコマンドを実行してください。

```sh
rm -rf ~/.aws/
```

このコマンドを実行すると、AWS CLI に関連するすべての設定が削除され、完全に初期化されます。

**実際のターミナル画面**

![Screenshot 2025-03-02 at 8.01.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/31723400-794b-4e96-8a87-31eebc6c2655.png)

## 4. 特定のプロファイルのみ削除
もし `default` 以外のプロファイルのみ削除したい場合は、以下のコマンドを実行して設定を開きます。

```sh
aws configure --profile プロファイル名
```

設定ファイルが開かれるので、不要な情報を削除して保存します。（`Ctrl + X → Y → Enter`）

## 5. 削除後の確認
設定が正しく削除されたか確認するには、以下のコマンドを実行します。

```sh
aws configure list
```

**実際のターミナル画面**

![Screenshot 2025-03-02 at 8.01.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/327f7e0b-5c6c-48c4-a218-28cb89a89b2c.png)


すべての設定が削除されていれば、`access_key` や `region` の情報が表示されなくなります。

## まとめ
- 誤って設定を削除すると、AWS CLI を利用する際に再設定が必要になります。
- 必要な情報は事前にバックアップを取ることを推奨します。

これで AWS CLI の設定を適切に削除できます！試してみてください！
【Terraform】secret情報保存のベストプラクティス

TerraformでRDSのログイン情報を管理する場合、セキュリティと運用効率を考慮したベストプラクティスが重要です。以下に、推奨される方法と、避けるべきアンチパターンを説明します。

**避けるべきアンチパターン**

* **Terraformコードに直接パスワードを記述する:**
    * `resource "aws_db_instance" "example" { ... username = "admin" password = "password123" ... }`
    * これは絶対に避けるべきです。コードがバージョン管理システムにコミットされた場合、パスワードが平文で漏洩するリスクがあります。

* **ステートファイルに平文パスワードを保存する:**
    * Terraformのステートファイルにもパスワードが平文で保存される可能性があります。ステートファイルも厳重に管理する必要がありますが、そもそも平文で保存しないようにするのがベストです。

* **リポジトリにパスワードをコミットする:**
    * パスワードを環境変数として設定する場合でも、それをリポジトリにコミットするスクリプトや設定ファイルに記述するのは避けるべきです。

**推奨されるベストプラクティス**

1. **シークレット管理ツールの利用:**

   * **AWS Secrets Manager:** AWSが提供するシークレット管理サービスを利用します。
      * RDSのパスワードをSecrets Managerで生成・管理し、Terraformから参照します。
      * パスワードのローテーション機能も利用できます。
      * IAMロールでアクセス制御を行い、必要なリソースのみがシークレットにアクセスできるようにします。

     ```terraform
     data "aws_secretsmanager_secret_version" "rds_password" {
       secret_id = "arn:aws:secretsmanager:リージョン:アカウントID:secret:rds-password-xxxxxx" # Secrets ManagerのシークレットARN
     }

     resource "aws_db_instance" "example" {
       ...
       username = "admin"
       password = data.aws_secretsmanager_secret_version.rds_password.secret_string
       ...
     }
     ```

   * **HashiCorp Vault:**  マルチクラウド環境やオンプレミス環境でも利用できるシークレット管理ツールです。
      * TerraformからVaultのシークレットエンジンを通じてパスワードを取得します。

2. **パスワードの自動生成:**

   * Terraformの`random_password`リソースや、AWS Secrets Managerの自動パスワード生成機能を利用して、RDSインスタンス作成時にランダムなパスワードを生成します。
   * 手動でパスワードを設定するよりも安全で、複雑なパスワードを容易に設定できます。

     ```terraform
     resource "random_password" "rds_password" {
       length           = 16
       special          = true
       override_special = "!#$%&*()-_=+[]{}<>:?"
     }

     resource "aws_db_instance" "example" {
       ...
       username = "admin"
       password = random_password.rds_password.result
       ...
     }
     ```
     * `random_password`で生成したパスワードをSecrets Managerに保存し、後から参照するようにすると、より安全に管理できます。

3. **環境変数またはTerraform Cloud/Enterpriseの変数:**

   * 機密性の低い環境や、ローカルでの開発環境など、限定的な状況下では環境変数を利用することも考えられます。
   * Terraform Cloud/Enterpriseを利用している場合は、変数グループやワークスペース変数で機密変数を設定できます。
   * ただし、環境変数はプロセスやログに漏洩するリスクがあるため、本番環境など機密性が求められる環境での利用は推奨されません。

4. **IAM認証の利用 (パスワードレス認証):**

   * RDS for MySQL, PostgreSQL, MariaDB ではIAM認証を利用できます。
   * パスワードを使用せずに、IAMロールに基づいてデータベースへのアクセスを制御します。
   * TerraformでIAMロールとポリシーを適切に設定し、RDSインスタンスに紐付けることで、よりセキュアな認証基盤を構築できます。
   * パスワード管理が不要になり、運用負荷を軽減できます。

5. **パスワードローテーション:**

   * 定期的にRDSのパスワードをローテーションすることを検討してください。
   * AWS Secrets Managerのローテーション機能や、Terraformと連携した自動ローテーションの仕組みを構築できます。
   * パスワード漏洩時のリスクを低減し、セキュリティを向上させます。

6. **Terraform Stateの保護:**

   * Terraform Stateファイルには、リソースの設定情報が含まれており、機密情報も含まれる可能性があります。
   * StateファイルをS3などのセキュアな場所に保存し、バージョン管理、暗号化、アクセス制御を適切に行うことが重要です。
   * Terraform Cloud/Enterpriseを利用すると、Stateの管理を安全に行うことができます。

**まとめ**

TerraformでRDSのログイン情報を管理するベストプラクティスは、**シークレット管理ツール（AWS Secrets Managerなど）を利用し、パスワードを自動生成・管理すること**です。IAM認証が利用できる場合は、パスワードレス認証も強力な選択肢となります。

セキュリティを最優先に考え、環境や要件に応じて適切な方法を選択してください。パスワードをコードに直接記述する、平文で保存するなどのアンチパターンは絶対に避けるようにしてください。
【Docker】Web→API→DBサーバの作成及びデータ連携【Docker-compose】

## 概要
・Docker-composeファイルを実行し、Web→API→DBサーバの作成の自動化
・Web→API→DBサーバ間のデータ連携の確認


## ファイル格納先イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/8adc3f8a-410a-49c7-8200-a6245c0d8622.png)


## 各ファイルの参照URL

https://github.com/hiro-tech-taku/container

## 前提条件
・DockerHubのインストールが済んでいること

https://hub.docker.com/_/docker


・Docker Desktopのインストールおよび起動が済んでいること

https://www.docker.com/products/docker-desktop/

## 作業手順
1. Docker-composeファイルを実行し、Web→API→DBサーバの作成
2. Web→API→DBサーバ間のデータ連携の確認
3. コンテナとイメージの削除（後片付け）

## Docker-composeファイルを実行し、Web→API→DBサーバの作成
・ターミナルを開き、各ファイルが格納されてあるcontainerディレクトリまで移動
・下記コマンド実行
```
docker compose up -d
```
・イメージの確認
```
docker image ls
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/7ca61abc-c379-4f03-b872-66f56e986450.png)

・実行コンテナの確認
```
docker container ls
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/0e8c8632-f312-41d1-9d74-42c75e349eca.png)


## Web→API→DBサーバ間のデータ連携の確認
・Webブラウザにて、下記コマンドを実行
```
http://localhost:8081
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/c09d1aaf-d9d5-4f89-a910-1d8c1d6d3fdb.png)

・【API Test】ボタン押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/aa1e59b7-0c2a-453f-9ad5-b90e91006446.png)

・【Database Test】ボタン押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/b47c6ff1-f7b4-4752-8cb0-40230e5e38b8.png)


## コンテナとイメージの削除（後片付け）
・コンテナの削除
```
docker compose down
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/1f73af0f-84ab-41d3-ac75-b97e94aafec9.png)

・コンテナイメージの削除
```
docker image rm イメージID
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/130ec658-9474-40a3-b3b0-0f045189d502.png)

## 最後に
今回のハンズオンの参考として、CloudTech内のレッスン動画を複数回見て勉強しました。とても素晴らしい教材なので皆さんも是非ご活用ください。
下記にリンクを貼っておきます。

https://kws-cloud-tech.com/
Terraform入門：MacBookにHomebrewと手動でTerraformをセットアップする方法を紹介してみた

## はじめに
Terraform をインストールする方法にはいくつかの選択肢がありますが、Mac では Homebrew を使うのが簡単で手軽です。

:::note info
***実際に Terraform をセットアップする際に、どの方法が最適なのか迷うことがあったため、整理してまとめようと思いました。***
:::

また、手動インストールの手順も知っておくと、環境によっては役立つ場面があるため、両方の方法を解説することにしました。

## 1. Homebrew を使って Terraform をインストール

Mac では、Homebrew を使うのが最も簡単な方法です。以下の手順でインストールできます。

### 1-1. Homebrew のインストール（未導入の場合）

まず、Homebrew がインストールされているか確認します。

```sh
brew --version
```

Homebrew がインストールされていない場合は、以下のコマンドを実行してインストールします。

```sh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

### 1-2. Terraform のインストール

Homebrew を使って Terraform をインストールします。

```sh
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
```

### 1-3. インストール確認

以下のコマンドで Terraform のバージョンを確認します。

```sh
terraform -version
```

バージョンが表示されれば、インストールは成功です。

**実際のターミナル画面**

![Screenshot 2025-03-02 at 6.54.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/cb63bf39-9e59-458b-a96d-94db1fb2601a.png)


## 2. 手動で Terraform をインストールする方法（Homebrew を使わない）

Homebrew を使いたくない場合、公式サイトからバイナリをダウンロードしてセットアップすることもできます。

### 2-1. Terraform の公式サイトからダウンロード

Terraform の公式ページにアクセスし、Mac 用のバイナリをダウンロードします。

🔗 [Terraform 公式ダウンロードページ](https://developer.hashicorp.com/terraform/downloads)

### 2-2. ダウンロードしたファイルを解凍

ダウンロードした `.zip` ファイルを解凍します。

```sh
unzip terraform_*.zip
```

### 2-3. `/usr/local/bin` に移動

Terraform をシステムのパスが通っているディレクトリに配置します。

```sh
sudo mv terraform /usr/local/bin/
```

### 2-4. パーミッションを設定

Terraform を実行できるように権限を付与します。

```sh
chmod +x /usr/local/bin/terraform
```

### 2-5. インストール確認

以下のコマンドで Terraform が正しくインストールされたか確認します。

```sh
terraform -version
```

## 3. Terraform の初期設定

Terraform の基本的な動作を確認するため、以下のコマンドを実行してみましょう。

```sh
terraform init
```

このコマンドが正常に動作すれば、Terraform の環境は問題なくセットアップされています。

## 4. Terraform を最新バージョンに更新する方法

Terraform は定期的に新しいバージョンがリリースされるため、適宜アップデートすることを推奨します。

### 4-1. Homebrew を使ってアップデート（推奨）

Homebrew を使って Terraform をインストールしている場合、以下のコマンドで更新できます。

```sh
brew upgrade hashicorp/tap/terraform
```

更新後、バージョンを確認してください。

```sh
terraform -version
```

### 4-2. 公式サイトから手動アップデート

もし Homebrew を使わずに手動で Terraform をインストールしている場合、以下の手順で更新できます。

1. Terraform の公式ページから最新バージョンをダウンロード。
2. `.zip` ファイルを解凍。
3. `/usr/local/bin` に移動。
4. 権限を付与。
5. `terraform -version` で確認。

### 4-3. うまく更新できない場合

Homebrew のキャッシュが影響している場合、以下の手順を試してください。

```sh
brew untap hashicorp/tap
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
```

その後、バージョンを再確認してください。

```sh
terraform -version
```

## まとめ

| 方法 | コマンド |
|------|---------|
| **Homebrew を使う（推奨）** | `brew install hashicorp/tap/terraform` |
| **Homebrew でアップデート** | `brew upgrade hashicorp/tap/terraform` |
| **公式サイトから手動インストール** | Terraform のバイナリをダウンロードし、`/usr/local/bin` に配置 |

通常は **Homebrew を使う方法** が簡単でおすすめです。必要に応じて `terraform -version` でインストールを確認し、動作チェックを行いましょう。
Terraform入門：インフラ管理を自動化するための基本コマンドを体系的に整理してみた

## はじめに
近年、クラウド環境の利用が急速に拡大する中で、**インフラ管理の自動化** が重要視されています。  

:::note warn
**Terraform は、その代表的なツールの一つであり、**コードとしてインフラを定義し、管理することで、効率的かつ一貫性のある運用** を実現できます。**
:::

本記事では、**Terraform の主要なコマンド** を解説し、**実践的な使い方** を紹介します。  

## 書こうと思ったきっかけ
Terraform を学び始めた当初、公式ドキュメントやさまざまな記事を参考にしながらコマンドを試しましたが、**どのコマンドがどの場面で役立つのかが整理されておらず、使いこなすのに苦労** しました。  

:::note info
***そこで、**初心者でも迷わずに Terraform を使い始められるよう、よく使うコマンドをまとめた記事を作成** しようと思いました。***
:::

また、Terraform を活用することで、**手作業による設定ミスを防ぎ、より再現性の高いインフラ管理** を実現できることを伝えたいと考えました。  

## 実際に紹介してみた

Terraformはインフラをコードで管理するためのツールであり、クラウドリソースの作成・変更・削除を効率的に行えます。本記事では、Terraformの主要なコマンドを解説します。

## 1. 初期化
Terraformの実行環境を準備するためのコマンドです。

```sh
terraform init
```

- Terraformが必要なプラグインやプロバイダーをダウンロードします。
- 初回実行時や新しい環境で使用する際に実行します。

## 2. 実行プランの作成
適用前にどのような変更が行われるかを確認できます。

```sh
terraform plan
```

- 変更予定のリソースやパラメータを表示します。
- インフラの変更を適用する前に影響を確認できます。

## 3. リソースの適用
実際にリソースを作成・更新するためのコマンドです。

```sh
terraform apply
```

- `terraform plan` で確認した内容を適用し、インフラを変更します。
- `-auto-approve` オプションを付けると確認なしで適用できます。

```sh
terraform apply -auto-approve
```

## 4. リソースの削除
Terraformで作成したリソースを削除します。

```sh
terraform destroy
```

- `terraform apply` で作成したリソースを削除します。
- `-auto-approve` オプションを付けると確認なしで削除できます。

```sh
terraform destroy -auto-approve
```

## 5. 状態管理
Terraformはリソースの状態を `terraform.tfstate` ファイルに記録します。

### 現在の状態を確認
```sh
terraform show
```

- Terraformが管理しているリソースの詳細情報を表示します。

### 管理対象のリソース一覧を表示
```sh
terraform state list
```

### 特定のリソースの詳細を表示
```sh
terraform state show <リソース名>
```

### Terraformの管理からリソースを削除
```sh
terraform state rm <リソース名>
```

- リソース自体は削除されず、Terraformの管理対象から除外されます。

## 6. コードのフォーマット
Terraformのコードを自動整形するコマンドです。

```sh
terraform fmt
```

- インデントやスペースを整えて可読性を向上させます。

## 7. コードの検証
Terraformの設定ファイルにエラーがないかチェックします。

```sh
terraform validate
```

- 構文ミスや設定の誤りを検出できます。

## 8. 依存関係のグラフを作成
リソース間の依存関係を可視化できます。

```sh
terraform graph
```

- `dot` コマンドを使うと、視覚的なグラフを生成できます。

```sh
terraform graph | dot -Tpng > graph.png
```

## 9. ワークスペース管理
Terraformのワークスペース機能を利用すると、同じコードで異なる環境（開発・本番）を管理できます。

### ワークスペースの一覧表示
```sh
terraform workspace list
```

### 新しいワークスペースを作成
```sh
terraform workspace new <ワークスペース名>
```

### ワークスペースの切り替え
```sh
terraform workspace select <ワークスペース名>
```

## 10. バージョン確認
Terraformのバージョンを確認するコマンドです。

```sh
terraform version
```

## まとめ

| コマンド | 説明 |
|----------|--------------------------------|
| `terraform init` | 初期化 |
| `terraform plan` | 実行計画の作成 |
| `terraform apply` | リソースの適用 |
| `terraform destroy` | リソースの削除 |
| `terraform show` | 現在の状態を表示 |
| `terraform state list` | 管理中のリソース一覧を表示 |
| `terraform state show <リソース名>` | 指定リソースの詳細を表示 |
| `terraform fmt` | コードの整形 |
| `terraform validate` | コードの検証 |
| `terraform graph` | 依存関係の可視化 |
| `terraform workspace new <名前>` | 新しいワークスペース作成 |
| `terraform workspace select <名前>` | ワークスペースの切り替え |
| `terraform version` | Terraformのバージョン確認 |

Terraformを活用すれば、インフラを効率的に管理できるようになります。ぜひ試してみてください！
競プロ日記#/25/03/01

# アルゴ式-[友達の友達](https://algo-method.com/tasks/413)
- 配列の要素として特定の数値を含むかどうかを判定するロジックが重要
こちらの記事参照
[[C++]ある値がvector内の要素に含まれているか否か判定する](https://qiita.com/wonder_zone/items/51fb5c3a773b98aa130c)

- 題意である「友達の友達」が満たす条件を正確に組み込むことも重要
```
set<int> ans;
    int countOfFriendsAruru = G.at(X).size();

    for (int i =  0;i < countOfFriendsAruru;i++){
        int countOfFriendsArurusFriends = G.at(G.at(X).at(i)).size();
        for (int j = 0;j < countOfFriendsArurusFriends;j++){
            // アルルのi番目の友達の友達をsetに追加していく
            if (!vector_finder(G.at(X), G.at(G.at(X).at(i)).at(j)) && G.at(G.at(X).at(i)).at(j) != X){
            // アルルの友達iのj番目の友達がアルルと友達ではない　且つ　アルル自身ではない
                ans.insert(G.at(G.at(X).at(i)).at(j));
            }
            
        } 
    }
```
個人的備忘録：Terraformコード分割の重要性とファイル構成について、ChatGPTに質問しながらまとめてみた

## はじめに
今回チーム開発で実施した Terraform のコードですが、一括でまとめて作ってしまい、コードレビューの際にご指摘をいただきました。

:::note info
***その中でいくつか修正が必要になりそうなので、まずは小さな環境から正しくコードの分割をしていこうと思って記事を投稿します。***
:::

自分自身、独学で勉強した部分が多いので、正しく理解して作っていきたいと思います。

## Terraform コード分割のメリット

- **可読性向上**  
  - 役割ごとに整理することで、コードを見やすくする。  

- **再利用性向上**  
  - 変数や出力値を分けることで、環境ごとに流用しやすい。  

- **保守性向上**  
  - 影響範囲を限定でき、変更や修正が容易になる。  

- **チーム開発の効率化**  
  - 担当を分けやすくなり、作業の分担がスムーズになる。  

- **エラー特定が簡単に**  
  - 問題のあるファイルを特定しやすく、デバッグが迅速にできる。  

- **状態管理が明確に**  
  - `backend.tf` を活用することで、本番環境への誤操作を防げる。  

- **拡張性向上（モジュール化）**  
  - VPC や EC2 などを分けることで、再利用しやすくなる。

## Terraform のコード分割について
Terraform のコード分割は、**可読性や再利用性を向上** させるために行います。

:::note warn
***一般的な方法として、以下のように分割します。***
:::

### **1. メイン設定ファイル (`main.tf`)**  
- リソース定義の中心部分を記述します。

### **2. 変数定義 (`variables.tf`)**  
- 変数を管理し、環境ごとの違いを抽象化します。

### **3. 出力値 (`outputs.tf`)**  
- 重要な情報を出力します。

### **4. プロバイダー設定 (`provider.tf`)**  
- AWS などのプロバイダー設定を定義します。

### **5. Terraform 状態管理 (`backend.tf`)**  
- リモートの状態管理設定を行います。

## **ディレクトリ構成**
Terraform のコードを適切に分割する際のディレクトリ構成の一例を示します。

```
terraform_project/
├── provider.tf     # プロバイダー設定
├── variables.tf    # 変数定義
├── main.tf         # メインのリソース定義
├── outputs.tf      # 出力情報
├── backend.tf      # 状態管理
└── terraform.tfvars # 環境ごとの変数設定（任意）
```

この構成にすることで、コードの見通しが良くなり、チーム開発でも管理しやすくなります。

## まとめ
Terraform のコード分割を適切に行うことで、コードの可読性や保守性が向上し、チーム開発においてもスムーズに作業を進めることができます。

:::note warn
**今回の見直しを通じて、自分の理解が浅かった部分を整理できました。特に、環境ごとに変数を適切に管理する重要性を再認識しました。**
:::

しかし、今回の作業では適切にコードを分割しきれなかった部分もありました。

そのため、今後は Terraform のモジュール化や環境ごとの適切なディレクトリ構成などについて、さらに深く学び、より良いコード設計ができるようにしていきたいと思います。
Gazebo9でTurtlebot3のカメラを有効にする

# 0. はじめに
Turtlebot3のチュートリアルを進めていくと現れるGazeboシュミレーションの中の下の画像。
<img width="1000" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577522/c667b8ec-8722-5683-4fb6-7b7a21fc3de9.png">
どうもカメラのシュミレーションもGazebo内でできるようなのだが、どうやってやるのか詳細なく、困ったので書き記しておく。

# 1. 環境
 <table>
    <tr>
      <td>ホストOS</td>
      <td>Windows 10 HOME 21H2</td>
    </tr>
    <tr>
      <td>仮想化ソフト</td>
      <td>Virtual Box 6.1.22</td>
    </tr>
    <tr>
      <td>ゲストOS</td>
      <td>Ubuntu 18.04.6 LTS</td>
    </tr>
    <tr>
      <td>ROS</td>
      <td>ROS2 Dashing Diademata</td>
    </tr>
 </table>

# 2. 設定方法
結論から述べますと、burgerだけカメラがモデルにないというオチでした。ひどい。
waffleの方にはちゃんとカメラの記述がありますので、そこからコピーしてもってくればOKです。以下参考
#### 1.URDFファイルにCameraの情報を追記
aptでturtlebot3をインストールした場合、下記にurdfファイルがあると思います。
```/opt/ros/dashing/share/turtlebot3_description/urdf/turtlebot3_burger.urdf ```
これに同階層にあるturtlebot3_waffle.urdfの下記カメラに関する記述をコピーします。
個人的備忘録：CloudShell で Terraform を実行した際の "no space left on device" エラーの対処法

## **はじめに**
AWS CloudShell 上で Terraform を実行した際に、`terraform init` の段階で以下のようなエラーが発生しました。

```CSS
Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v5.89.0...

Error: Failed to install provider

Error while installing hashicorp/aws v5.89.0: write
.terraform/providers/registry.terraform.io/hashicorp/aws/5.89.0/linux_amd64/terraform-provider-aws_v5.89.0_x5:
no space left on device
```

このエラーは、CloudShell のディスク容量が不足していることが原因です。CloudShell の `/home/cloudshell-user` は `/dev/loop0` にマウントされており、**ディスクの使用率が100%** になっていると、Terraform のプラグインをインストールできなくなります。

:::note info
***本記事では、この問題を解決する方法を紹介します。***
:::

## **1. ディスクの空き容量を確認**

まず、現在のディスク使用状況を確認します。

```sh
df -h
```

また、ホームディレクトリの使用量を確認するには、以下のコマンドを実行します。

```sh
du -sh /home/cloudshell-user/*
```

今回の環境では、`/home/cloudshell-user` にマウントされている `/dev/loop0` の使用率が **100%** になっていました。

```
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop0      974M  907M     0 100% /home/cloudshell-user
```

この状態では、新しいファイルを作成できないため、Terraform のプラグインがインストールできません。

## **2. 不要なファイルを削除**

### **(1) Terraform のキャッシュを削除**
Terraform のキャッシュフォルダを削除すると、ディスクの空きを確保できる場合があります。

```sh
rm -rf .terraform
rm -rf ~/.terraform.d
```

その後、`terraform init` を再試行してください。


### **(2) 不要なファイルを削除**
以下のコマンドで不要なファイルを削除します。

```sh
rm -rf ~/Downloads/*
rm -rf ~/.cache/*
rm -rf ~/.npm/*
rm -rf ~/.local/share/Trash/*
```

Terraform の zip ファイルなど、古いファイルも削除して空き容量を増やします。

```sh
rm -f ~/terraform_0.14.2_linux_amd64.zip
```

## **3. Terraform の作業ディレクトリを `/tmp` に移動**
CloudShell の `/tmp` ディレクトリは `/home/cloudshell-user` とは異なる領域であり、空き容量がある場合があります。そのため、Terraform の作業ディレクトリを `/tmp` に移動して実行できます。

```sh
mv ~/terraform_project /tmp/
cd /tmp/terraform_project
terraform init
```

## **4. CloudShell をリセットする**

もし `/home/cloudshell-user` の容量を確保できない場合、CloudShell をリセットすると環境が初期化され、空き容量が回復することがあります。

```sh
exit
```

その後、CloudShell を開き直して Terraform を試してください。

## **5. Terraform のプラグインキャッシュを `/tmp` に変更する**
デフォルトでは `.terraform` フォルダが `/home/cloudshell-user` に作成されますが、プラグインキャッシュの保存先を `/tmp` に変更することで容量不足を回避できます。

```sh
export TF_PLUGIN_CACHE_DIR="/tmp/.terraform.d/plugin-cache"
mkdir -p $TF_PLUGIN_CACHE_DIR
terraform init
```

## **6. 別の環境（ローカルマシン・EC2）で実行する**
CloudShell のディスク容量には制限があるため、ローカルマシンや EC2 で Terraform を実行するのも選択肢の一つです。

- **EC2 インスタンスを作成**
- **Terraform をインストール**
- **Terraform のコードを移動して実行**

## **まとめ**

| No  | 解決策                                      |
|-----|-------------------------------------------|
| 1   | 不要ファイルを削除 (`rm -rf .terraform .terraform.d ~/.cache/*`) |
| 2   | Terraform プロジェクトを `/tmp` に移動 (`mv ~/terraform_project /tmp/`) |
| 3   | CloudShell をリセット (`exit` して再接続) |
| 4   | Terraform のプラグインキャッシュを `/tmp` に変更 |
| 5   | 別の環境（ローカル or EC2）で Terraform を実行 |

CloudShell は便利な環境ですが、ディスク容量の制限があるため、容量不足にならないよう注意しながら作業する必要があります。

***今回紹介した対策を試して、Terraform の環境をスムーズに構築してみてください！***
個人的備忘録：-- を含むファイル名の扱い方。削除できなかったが、「./」と「--」を使えば削除できたので紹介してみた

## はじめに

Linux の `rm` コマンドを使う際、**意図せずファイル名がオプションとして解釈** されてしまうことがあります。  

:::note info
特に `--client-id` のような名前のファイルを削除しようとすると、**エラーが発生しがち** です。
:::

この問題に直面し、**思うように削除できず困った経験** がありました。  
そこで、今回は **この問題の原因と、確実に削除する方法** について紹介します。

## 起きていた問題
Linux の `rm` コマンドを使って `--client-id` のようなオプションのように見えるファイルを削除しようとすると、`rm` がファイル名ではなくオプションとして解釈してしまい、削除できないことがあります。

### **実際のエラー画面**

こんな感じで削除することができませんでした。

![Screenshot 2025-03-02 at 3.27.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/d8a71987-ef28-4e14-9d07-f1f1175da9c4.png)

**例:**
```bash
rm -rf --client-id
```
この場合、`rm` は `--client-id` をオプションとして認識し、不明なオプションエラーを出してしまいます。

実際にこの問題に直面し、なかなか削除できずに困っていました。

## 解決方法
このようなケースでは、以下のいずれかの方法でファイルを削除できます。

### 方法 1: `./` をつける
ファイル名の前に `./` をつけることで、オプションではなくファイル名として認識させることができます。

```bash
rm ./--client-id
```

この方法を試したところ、正常にファイルを削除することができました。

### 方法 2: `--` を使う
`rm` コマンドに `--` を渡すと、それ以降の引数をオプションではなくファイル名として扱うようになります。

```bash
rm -- --client-id
```

この `--` は「これ以降はオプションではなく引数として解釈する」という意味になります。Linux コマンドではよく使われるテクニックなので覚えておくと便利です。

## まとめ
Linux では `rm` コマンドを使う際に、`--` で始まるファイル名がオプションとして誤解釈されることがあります。

***そのため、削除しようとしてもエラーが発生し、困ってしまうことがあります。***

:::note warn
***しかし、`./` をつけるか `--` を使うことで、簡単に削除できることが分かりました。***
:::

今後もこのような問題に直面した際には、これらの方法を試してみることをおすすめいたします。
AWSのEC2インスタンスが自動的に落ちてしまう・・・

# はじめに
- **この記事では先日遭遇したエラーに関しての原因とその解決策を備忘録として残しておきます**。

# 目次
**1. 遭遇したエラーの詳細**
**2. 原因特定の旅**
**3. 原因**
**4. 解決策**

# 遭遇したエラーの詳細
- ある日、**EC2インスタンスで立ち上げているwebサーバーにアクセス**しようとしました。
    しかし、**以下のように「アクセスしています」状態のまま20分ほどアクセスできずにいました**。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758326/74985677-a561-4741-a1e1-2af9c5551a0c.png)

    これは何かおかしいと感じてエラー発見の旅に出ました。

# 原因特定の旅
- まずはAWSのEC2インスタンスを見て何が起きているのかを確認してみることにしました。すると以下のような**インスタンスの接続性チェックに失敗しました**という文字がありました。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758326/af076b8f-a66b-4fa6-a9a7-890cb593c9e9.png)

    この段階ではまだ、原因の特定には至りませんでしたが、何かしらEC2インスタンス側でエラーが発生していることが分かりました。

- 色々調べてみると**インスタンスのスクリーンショット**を取得してみると原因がわかるみたいです。
    インスタンスのスクリーンショットの取得の仕方は**使用しているインスタンスを選択→アクション→モニタリングとトラブルシューティング→インスタンスのスクリーンショットを取得**で行えるようです。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758326/541c5f01-df8b-472d-8549-84aca1b09b42.png)

- こうしてインスタンスのスクリーンショットを取得すると以下のような画像が得られました。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758326/9447b403-5d4a-41f6-9c13-88873c8b3dc3.png)
    なにやら**Out of memory**という文字が見えています。ふむふむ・・・なんとなくエラーの原因が見えてきました。

# 原因
- つまり原因としては**インスタンスに割り当てられたメモリを超える負荷・使用量になり、OSがプロセスを停止せざるを得なかった**ことのようです。

# 解決策
- 自分がとった解決策としては単純に**EC2インスタンスのスペックを上げる**ことを行いました。今まではEC2インスタンスの**無料枠であるt2.micro**を使用していたので、メモリの想定使用量と料金を鑑みて**t3.small**にしました。
- インスタンスのタイプの変更はわざわざもう一度インスタンスを作り直さなくても、変更できます。変更方法は**使用しているインスタンスを選択→アクション→インスタンスの設定→インスタンスタイプを変更**から行うことができます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758326/01239997-80e2-4117-80f2-9519ff3984aa.png)

# まとめ
- この記事ではインスタンスが途中で終了することに対しての原因と解決策に関してまとめました。今回は簡単にエラーの内容を特定、解決できましたが大規模システムになればなるほど、簡単にインスタンスのタイプを変更するだけでエラー解決という線は薄そうです。
【初心者向け🔰】ICTにおけるインフラエンジニアのお仕事とは（職種編）

アディクシィ株式会社でインフラアーキテクトとして従事している
おんたまと申します。記事に目を止めていただきありがとうございます。
>アディクシィ株式会社
>https://adixi.co.jp

本記事は以下の方向けに記載をしております。

:::note info
・ICT業界に興味を持っていただいた方
・インフラ領域に興味がある方
・インフラエンジニアとしてのキャリア形成について考えている方
:::

# インフラエンジニアのお仕事とは（職種編）
「そもそもインフラエンジニアってどんな仕事があるの？」という疑問に回答したいと思います！！
あくまでざっくりとした職種の紹介なので、興味のある方は調べてみて下さい。

# クライアントPCエンジニア
クライアントPCエンジニアは、企業や組織のクライアントPC（デスクトップやノートPC）の技術的な管理とサポートを担当する技術者です。
主にPCのセットアップ、ソフトウェアのインストール、セキュリティ対策、トラブルシューティング、アップデートの適用などを行います。
また、ユーザーサポートやデバイスのパフォーマンス管理も行い、業務が円滑に進むようサポートするお仕事です。

# サーバーエンジニア
サーバーエンジニアは、サーバーの設計、構築、運用、保守を担当する技術者です。サーバーとは、情報システムやWebサービスにおいて要求を処理する機器になります。
企業の情報システムやWebサービスに必要なサーバーを管理するお仕事です。
サーバーの安定性やセキュリティを確保し、トラブルシューティングやパフォーマンスの最適化を行ったりします。

# ネットワークエンジニア
ネットワークエンジニアは、ネットワークの設計、構築、運用、保守を担当する技術者です。
企業や組織内、また情報システムやWebサービス内のネットワークがスムーズに動作するように、ネットワーク機器を管理し、通信の安全性や効率性を確保するお仕事です。

# ストレージエンジニア
ストレージエンジニアは、情報（データ）の保存・管理を行うストレージという機器を使ったシステムの設計、構築、運用、保守を担当する技術者です。
ストレージを管理し、データの可用性、バックアップ、リカバリー、パフォーマンス向上を図ります。また、ストレージの容量計画やセキュリティ対策にも関わるお仕事です。

# ソリューションエンジニア
ソリューションエンジニアは、ICTインフラ（クライアント、サーバー、ネットワーク、ストレージなど）に関する技術的な問題を解決するために提供される製品やサービス（ソリューション）の設計、構築、導入する技術者です。
製品の一例として、セキュリティ対策、バックアップ・リカバリー対策、クライアントPC管理、仮想化技術、監視・構成管理などが挙げられます。
顧客のニーズに基づき、ソリューションを導入することで、効率的で安定したインフラ環境を提供し、長期的なインフラの安定運用を支援するお仕事です。

# クラウドエンジニア
クラウドエンジニアは、クラウドサービス環境（例えば、AWS、Azure、Google Cloud）を活用して、ICTインフラを設計、構築、運用、最適化する技術者です。
クラウドサービス上のサーバー、ストレージ、ネットワークなどを管理し、情報システムやWebサービスの維持、管理を行うお仕事です。
また、クラウドサービスは一般的に従量課金制のため、コスト管理や運用自動化を進め、効率的なクラウドインフラの運用をサポートします。

# 終わりに
今回はインフラエンジニアのお仕事について技術的な職種について紹介致しました。
次回はICTインフラを構成する上で必要な「役割（プロセス）」の面から解説したいと思います！！
ProxmoxでCT作った後に内ファイルをVSCodeで編集したい

# 前提
- 今回はクライアント側はWindows11Homeを想定
# クライアント側（Windows側設定）
## sshキー作成
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/d9d03b35-87ca-4243-b348-342b16c10a4c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/b8781482-6c66-4d6c-b353-f7ed2d52a0f4.png)
- 両方作っておく
## ssh秘密鍵のパーミッション設定（他の人から見えなくする）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/a9e34d1c-2e1a-4e80-9506-5660db2213b6.png)
- ファイル→プロパティ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/37e873e5-a2e8-47a9-b441-6ca053b83f03.png)
- セキュリティタブ→詳細設定
- 自分以外の権限を削除、もしくは「継承の無効化」

## サーバーへsshできるか確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/9f0a3995-524f-4199-ba1a-5d130ddf218a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/d2495098-41d9-400a-b05b-be8e5e710f7d.png)
- OK

## サーバー側のauthorized_keysに公開鍵を登録
（省略）

# VScode側設定
## でRemote-ssh拡張機能をインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/efc7018f-97ca-4f23-bb39-6b749a08e4fc.png)
## Remote-ssh機能の起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/f18fd42f-0282-431f-a1fb-f808fbcb63c7.png)
-  「コマンドの表示と実行」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/98a77d2d-3eb4-4a00-a1f4-acc20652faec.png)
- Remote-ssh関連を探し、実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/542ea2f9-14a4-44d4-afb6-1894e863e8c4.png)
- 「ユーザー名@ホスト名（IPアドレス）」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/76b32b3b-9bf0-4c3e-8f30-197eac1cdb65.png)
- configを適宜編集しておく

## 接続
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/9a3683ca-3bed-4012-bc21-fe66390f9329.png)
- 途中の選択肢は適宜選ぶ
- これでcopilot経由でLinuxサーバー側ファイルの編集ができる
- =すてき
ProxmoxでCT（Linuxコンテナ）を作った後の作業（自分用メモ）

# CT作成
## 全般
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/0ee04d6a-091b-4c29-905f-d77eba48fd80.png)
- ホスト名付ける
- パスワード付ける

## テンプレート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/0937a8bf-8f9f-40e3-8a03-ce6d348156e8.png)
- テンプレート選ぶ（今回はUbuntu-2410）

## ディスク
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/147b7633-80b0-444d-9043-2fa4e9084d4d.png)
- 適宜サイズを調整する（今回は20G）

## CPU
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/7c906bd6-96e1-4654-86c1-2b86af5b6d02.png)
- 適当に（今回はテスト用なので1コア）

## メモリ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/eff26ccc-7f82-4d35-a049-5e68fdef580b.png)
- 適当に（今回はテスト用なので512M）

## ネットワーク
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/90ff9fd5-8342-480c-b757-d5c0e312a157.png)
- 適宜選ぶ（今回はテスト用なのでBBルータDHCPで）

## DNS
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/943dc5fb-58ff-443c-a348-2b16561e68c6.png)
- 適宜選ぶ（今回はテスト用なのでたぶんDHCPからとってくれるはず）

## 確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/740aa06b-002d-4187-87a6-98926580fb40.png)
- 問題なければ「完了」し、Linuxコンテナ作る

## TASKOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/66e94cc9-251b-4fe4-bdd5-62be534b3859.png)

# ログイン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/0f88d847-c231-4841-beea-d3d3ae43a9f2.png)
- データセンター→ノード→サマリ画面から「開始」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/f8d90f12-f08c-47e8-9fc3-005cc3f6e6e9.png)
- コンソールでログインプロンプト
- ユーザー名：root、CT作成時のパスワードでログインする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/d5a4efbd-ec91-4aec-913e-3b08afd79f1a.png)

# グループ作成
```
# groupadd -g 10000 user
```
- 適当に10000ぐらいのgidでuserグループを作成

# ユーザー作成
```
# useradd -u 10000 -g 10000 testuser
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/ead525dc-bcd2-4c40-87be-39267c912fe6.png)
- 確認

# パスワード設定
```
# passw testuser
```

# 各パッケージのアップデート
```
# apt update
# apt upgrade
```

# エディタ変更
```
# apt install vim emacs
```
- とりあえず、vim、emacs入れておく
```
# update-alternatives --config editor
```
- デフォルトエディタ変更（これやっておかないとnanoが起動するが、使い方がわからない）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/e0898268-d6ec-43d3-9561-0aab72a61eb7.png)
- viでもEmacsでも好きな物を

# sudoできるようにする
```
# usermod -aG sudo testuser
```
- 正しいやり方はよくわからないが、sudoグループに入れた人に権限付けるがよさそう

```
# visudo
```
- visudoでsudoできるユーザー管理ファイル編集
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6972/7e0c6bf1-0b1a-4893-a1ee-51f8fc281c45.png)
- sudoグループに属している人はパスワードなし設定
【Next.js】Vue出身者が行うライブラリ選定

Laravel + Vue, Nuxt 構成出身の私が、現時点で行ったライブラリ選定をまとめるぞ。
おすすめがあればコメント欄で教えてほしい...。


## Database

Laravel なら全部入っているが、Next の場合開発者にお任せされている。

まず `Validation` は `Zod` がおすすめ。
型生成なども合わせて行うことが可能なので、jsonスキーマとの相性が最高。

https://zod.dev/

DB周り、`Model` `Migration` `Seeder` は `Drizzle ORM` がおすすめ。
新興 ORM なのだが、すべてが `TypeScript` で構築可能で、とてもタイプフレンドリー。
しかも簡易DBビューワーが付いてくるので、至れり尽くせり。

https://orm.drizzle.team/

書き味は、SQLが関数で表現されている感じのシンプルな実装。
[Kysely](https://kysely.dev/) に非常に近い。
json など一部の記述はまだ未対応なので、kyselyと組み合わせる変態なライブラリも用意されている。

https://github.com/drizzle-team/drizzle-kysely

有名なのは [Prisma](https://www.prisma.io/) だけど、これは独自言語のスキーマな点がBAD...。
やはり、TypeScript で SQL を書けたほうが良いと思う。


## フォーム系

フォームを作成するなら `React Hook Form` 一択な雰囲気がある。
デフォルト値の設定から、zod バリデーションの組み込み、ハンドラーまでを担当。

`useFieldArray()` というリストの追加、削除のラッパーまで用意されているので、使っていてとても楽しい。

https://www.react-hook-form.com/

React がレンダリングに特化しているので、Vue のように柔軟に値を持たせて、という思想で画面を作ると、コードがごちゃごちゃしてしまう。
汎用機能は外出しするのがよさそう。


## UI 系

拡張性を考えると、`TailwindCSS` ベースのものが良いと思う。

ただ、React の UIライブラリではなく、Tailwind の class セットを提供しているものが多い。
UIライブラリの導入は、開発速度やデザインの統一感であると考えるので、自身でコピペしてコンポーネントを作成したりの手間が一段階増えるのはいかがなものか。
（デザインをフルスクラッチするなら、更にに要らないし...）

このあたりがおすすめ。
個人的には `daisyUI` がかわいくてとても好き。

https://daisyui.com/  

https://ui.shadcn.com/  

https://ui.supabase.io/  

アイコンは `React Icon` を使っておけばいい感がとても強い。
全部入りである...。

https://react-icons.github.io/react-icons/



## linter

`Linter` は `ESLint` で十分です。
`Prettier` は `ESLint Stylistic` を使って、`ESLint` に集約するとよい。

https://eslint.style/

世の中には [Biome](https://biomejs.devt/) というイケイケなやつがいるがあれは罠だ...。
`HTML` に対応してねぇ...。

未来に期待して、`ESLint` のエコシステムを利用するのが賢い。
Flat Config って言っても、設定ファイル JSON をマージするイメージなので、慣れたら簡単よ。


## その他

チュートリアルにも出てくる `clsx`。
className に対して、Vue のように配列やオブジェクトを渡すことが可能。

これが無いと Tailwind の開発できなくない...？
レイアウトコードとデザインコードは分けたいマン。

https://github.com/lukeed/clsx
AtCoderをPythonで取り組んだ振り返り(ABC395)

どうもこんにちは！

今週もAtCoderのコンテストに参加できたので記録がてら振り返ります。
残念ながらA,Bの２問完答、Cを解ききれず終了となりました。悔しい。

# 問題
問題は以下から。

https://atcoder.jp/contests/abc395/tasks

# A - Strictly Increasing? -
与えられた正数数列が狭義単調増加(数列を進めると必ず数値が増える数列。同じ数値が連続になるのもNG)であるかを判定する問題。
数列を読み込んで、for文で順番に比較して満たしているかどうかを確認する形にしました。
~~~Python
n = int(input())
s = [int(x) for x in input().split()]
for i in range(n-1):
  if s[i] >= s[i+1]:
    print("No")
    break
  elif i == n-2:
    print("Yes")
~~~

# B - Make Target -
与えられた正の整数Nをもとに、N×Nの模様を作成する問題。作成の条件は以下。
・左上端の座標を(i,j)とし、上からi行目、左からj列目とする。i=1,2,…,N の順に、以下の操作を行う。jはj=N+1−i とする。
・i≤j であるならば、i が奇数ならば黒、偶数ならば白で、マス (i,i) を左上、マス(j,j) を右下とする矩形領域に含まれるマスを塗りつぶす。このとき、既に色が塗られているマスについては色を上書きする。
・i>j であるならば、何もしない。
・黒に塗るときは#、白に塗るときは.とする。
シンプルに2重ループを使ってiの値ごとに(i,i)から(j,j)を塗りつぶすとしました。
~~~Python
n = int(input())
s = [["."]*n for _ in range(n)]

for i in range(1,n+1):
  j = n + 1 - i
  if i <= j:
    if i % 2 == 1:
      for k in range(i-1,j):
        for l in range(i-1,j):
          s[k][l] = "#"
    else:
      for k in range(i-1,j):
        for l in range(i-1,j):
          s[k][l] = "."

for i in range(n):
  print("".join(s[i]))
~~~

# C - Shortest Duplicate Subarray -
与えられた整数Nと長さNの整数列があり、整数列の空でない連続部分列で同じ値を複数個含むようなものがあるかどうか、ある場合は最短の長さを求めるというもの。制約として整列の長さは最大で$2*10^5$、整列内の数値は最大で$10^6$。
Paizaで学んだしゃくとり法で解けそうと作ったのが以下。
~~~Python
n = int(input())
s = [int(x) for x in input().split()]
length = 10000000
ans = 0

tmp = [s[0]]
right = 1
for i in range(n):
  while right < n and (right == i or s[right] not in tmp):
    tmp.append(s[right])
    right += 1
  if right < n:
    if s[right] in tmp:
      ans = 1
      length = min(length,len(tmp)+1-tmp.index(s[right]))
  tmp.pop(0)

if ans == 0:
  print(-1)
else:
~~~

多分解けるんですがテストケースの約半分が時間制限を満たせず。while文がある分計算量が増えている・・・？ということでfor文だけで解くようにしたんですがむしろ遅くなったようで、解決できずタイムアップ。
解説を見たら、$10^6$分の配列を作って、数列内にでてきた値の位置を仕分け、あとは2個以上ある数値の中から最短の距離を回答すればよいとのこと。しゃくとり法でも解けはするとのことですが、ハンマー持つとなんでも釘に見えたような感じでよくなかったですね。。

# おわりに
前回も２問完答だったので結果出せず悔しいところですが、地道にやっていくしかないですね。


ではでは。
[rspec] サポートモジュールでロジックを共通化


## テストコード
毎回JSON.parse(response.json)をするのは面倒なので
メソッドに切り出したいです。
この処理をrequest系の処理全体で共通化します
```rb
require 'rails_helper'

RSpec.describe "Users", type: :request do
  let!(:user) { create(:user) }

  after { User.destroy_all }

  describe "GET /users" do
    before { get '/users' }
    
    it 'ユーザー覧を取得できる' do
      expect(response).to be_successful
      expoect(body.size).to eq(1) # ヘルパーを使用
    end
  end

  # ヘルパーメソッド: レスポンスJSONをパースする
  def json
    JSON.parse(response.body)
  end
end
```

## 共通化手順
1 spec/support/request_helpers.rbを作成
2 メソッド作成
3 spec/rails_helper.rbで`Rails.root.glob('spec/support/**/*.rb').sort_by(&:to_s).each { |f| require f }`のコメントアウトを解除
4 moduleのinclude

---
1・2

```rb
# spec/support/request_helpers.rb
module RequestHelpers
  def body
    JSON.parse(response.body)
  end
end
```

3 
rails8では`Rails.root.glob('spec/support/**/*.rb').sort_by(&:to_s).each { |f| require f }`でしたが、古いversionでは`Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }`の場合もあるようです。

4
```rb
RSpec.configure do |config|
  ...
  config.include RequestHelpers, type: :request
end
```