OmniAICreator/Qiita-1.07M huggingface dataset:
Rails Server が正常に終了しない場合の対処法

## 事象

`Rails Server` を使用している際、通常は `Ctrl + C` を使用して終了しますが、サーバーが正常に終了しない場合があります。再度 `bin/rails s` コマンドで `Rails Server` を起動しようとすると、以下のようなエラーが発生することがあります。

```sh
% bin/rails s                                        
=> Booting Puma
=> Rails 7.0.4.3 application starting in development 
=> Run `bin/rails server --help` for more startup options
A server is already running. Check /path/to/your/project/tmp/pids/server.pid
Exiting
```

こちらのエラーメッセージは `Rails Server` が既に実行中であることを示しており、正常に終了していない、或いは異常終了して `プロセスID（PID）` ファイルが残っていると表示されます。`Rails` はサーバーを起動するとき `tmp/pids/server.pid` ファイルに現在実行中のサーバープロセスの `PID` を記録します。このファイルが存在すると新たにサーバーを起動しようとするとき、既にサーバーが実行中であると判断され、上記のエラーメッセージが表示されてサーバーの起動が中止されます。

## 対処法

今回のエラーを解消するためには、エラーメッセージに表示されているパスにある `server.pid` ファイルを削除します。

```sh
rm /path/to/your/project/tmp/pids/server.pid
```

`PID` ファイルを削除しても問題が解決しない場合、`lsof` コマンドを使用して該当するポート（通常は `Rails` のデフォルトである3000番ポート）を使用しているプロセスを見つけて終了させることができます。

```sh
lsof -i :3000
```

このコマンドは、3000番ポートを使用しているプロセスのリストを表示します。出力結果から `PID` を探します。そして見つけた `プロセスID` を使用してプロセスを終了させます。

```sh
kill -9 <PID>
```

`<PID>` は前のコマンドで見つけた `プロセスID` に置き換えます。`-9オプション` はプロセスを強制終了させるために使用されます。

自らの備忘録のために投稿してますが、なにかお役に立てましたら幸いです！:clap:
また、なにか間違ってましたらご指摘いただけますと幸いです！:pray:
【雑記】PC遍歴

# はじめに
備忘録として、購入したPCをまとめておく。

# PC遍歴

## 2016/4/1〜

大学生協のパソコンをこだわりなく購入。

良かったところ：可もなく不可もなく。長期間使用できている。
悪かったところ：修理前提なので、スペックの割に値段が高い。

| 属性 | 値 |
| --- | --- | 
| 製品名 | LIFEBOOK SH90/W |
| 製品番号 | FMVS90WWD1 |
| 会社 | 富士通 |
| 発売日 | 2015/11/20 |
| 金額 | ¥179,000 | 
| 画面サイズ | 13.3インチ |
| OS | Windows 10 Home 64bit |
| CPU | Core i5-6200U |
| GPU | Intel HD Graphics 520 |
| メモリ | 4GB |
| ストレージ | 256GB(SSD) |

## 2020/5/22〜

MacBookが使ってみたくて購入。

良かったところ：筐体とディスプレイが綺麗。
悪かったところ：macOSに慣れない。

| 属性 | 値 |
| --- | --- | 
| 製品名 | MacBook Air |
| 製品番号 | ー |
| 会社 | Apple |
| 発売日 | 2020/03/27 |
| 金額 | ¥134,800 | 
| 画面サイズ | 13インチ |
| OS | macOS 10.15.7 Catalina|
| CPU | 10世代 intel Core i5 |
| GPU | Intel Iris Plus Graphics 1536MB |
| メモリ | 16GB |
| ストレージ | 256GB(SSD) |

## 2024/2/21〜
トラックポイントが使ってみたい&スペックの高いWindows PCが欲しくて購入。

良かったところ：ー
悪かったところ：ー

| 属性 | 値 |
| --- | --- | 
| 製品名 | ThinkPad X1 Carbon Gen 11 |
| 製品番号 | 21HNCTO1WWJP7 |
| 発売日 | 2023/04/27 |
| 会社 | Lenovo |
| 金額 | ¥234,752 | 
| 画面サイズ | 14インチ |
| OS | Windows 11 Home 64bit |
| CPU | Core i7-1355U |
| GPU | Intel Iris Xe Graphics |
| メモリ | 32GB |
| ストレージ | 512GB(SSD) |
【Rails】RailsにJS, jQueryを実装する方法

こんばんは！
現在チーム開発で時間がだいぶ余りRailsにJavaScriptやjQueryを実装したので、実装方法を忘れないうちに書いておきます！

# 環境
AWS Cloud9
Rails6系

# 方法
## app/javascript配下にjsファイルを作成する
名前はxxxx.jsとなっていればなんでも大丈夫です！今回はscript.jsにしました。
実装後、基本的にはこのファイルにJS、jQueryの記述をしていくことになります。

## app/javascript/packs/application.jsにimportする
```javascript:app/javascript/packs/application.js
import "script.js"
```
この記述を追加してください。

## yarnを使用して導入
ターミナル上でこのコマンドを実行してください。
```terminal:ターミナル
$ yarn add jquery
```

## config/webpack/environment.jsに追記する
```javascript:config/webpack/environment.js
const { environment } = require('@rails/webpacker')
// ここから
const webpack = require('webpack')
environment.plugins.prepend(
  'Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery',
  })
)
//　ここまで
module.exports = environment
```

## jQueryをimportする
```javascript
:
:
import 'jquery' // この行を追記
import "script.js"
:
:
```
## 実際に試してみる
ここまでで実装は終了ですが、確認のためにアラートを試してみます。
最初に作ったapp/javascript配下のjsファイルを開いて記述してください。
```javascript:app/javascript/script.js
let title = "javascript実装完了！";
alert(title);
```
サーバーを起動後、viewページを開いたときにアラートメッセージが表示されれば実装できている証拠です！

# すべてのページで遷移時JS,jQueryを反映させる
 　表示させたいviewページが1ページなら上の実装のみで問題ありませんが、複数ページある場合問題がおきてしまいます。その問題について対処できるようになりましょう。
　RailsではTurbolinksという仕組みを使って、サイト内で最初のページの表示にはHTMLファイルすべてを参照しますが、サイト内のページ遷移後はbodyタグ内の情報のみ取得して表示することで動作を軽くしています。(headタグ内やjsファイルは最初のページでしか読み込まれません。読み込まれても差分のみです。)そのため、最初に表示したページから他のページへaタグやlink_toで遷移した際にはjsファイルは読み込まれないようになっています。そうするとjsファイルで実装した内容がページ遷移後に反映されなくなるので、以下の記述を付け足すとすべてのページでjsファイルの内容が反映されます。
 ```javascript: jsファイル
 $(document).on('turbolinks:load', function () {
  // 実装内容
});
```
【Xcode】Xcode内にドキュメントを簡易表示する

# はじめに
プロジェクトが大きくなってくると、ドキュメントを見ないとどのような処理をしているのかわからないものもでてくる可能性があります。

そんな時、定義元に行かずとも、ドキュメントを閲覧できたらいいですよね。

使用側でドキュメントを簡易表示する方法を紹介します。

以下のような関数があり、このドキュメントを見たいとします。

![スクリーンショット 2024-02-22 22.18.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d283062d-bb83-4d08-aeca-ca5a85caca3a.png)

# やりかた1
① ドキュメントを表示したい関数を右クリックします。
② 「Show Quick Help」を押します。

![スクリーンショット 2024-02-22 22.23.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/194d0717-4dfd-d8f3-3a85-7f38fa1837e7.png)

![スクリーンショット 2024-02-22 22.26.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/88e1c845-3f73-936c-f348-065b79bab333.png)

# やりかた2（ショートカット）
`option` + クリック

![スクリーンショット 2024-02-22 22.27.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/f44a2805-d156-0684-8d42-60b31210d553.png)

# おわり
以下のような閲覧方法もあります。

https://qiita.com/SNQ-2001/items/6da78bcffd7181163e44

↑こちらはガッツリ見たい時に使えそうです。
mermaid.jsをMarkdownファイル内部に記載しよう

## 前提条件

今回はコードエディターであるVisual Studio Code（以降VScode）が導入されていることを前提としてお話を進めます。導入がまだの方は下記を参考に導入をお願いいたします！（少し古い記事なので方法が変わってたらごめんなさい！）
Macの方↓

https://qiita.com/miriwo/items/4ed96b54b4421fe9d275

Windowsの方↓

https://qiita.com/miriwo/items/710cf3b21cce539d8be2

## 拡張機能のインストールと記載の準備

mermaid.jsのプレビューに必要な拡張機能をインストールします。VScodeを開いてサイドメニューの拡張機能メニューを開きます。

![Visual_Studio_Code-2-1024x768.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/5a3dd3e9-7eaf-be18-9441-63cca59feaaf.png)

拡張機能検索ウインドウに「Markdown Preview Enhanced」と入力して検索にヒットしたMarkdown Preview Enhancedの「インストール」をクリックします。

![拡張機能__Markdown_Preview_Enhanced-1024x768.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/80c51099-24ab-5a06-071c-3eab39319236.png)

任意の場所に「test.md」という新規ファイルを作成しVScodeで開きましょう。

![test_md-1-1024x564.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/889cbde7-08ae-73f8-0c8b-ba935de1595f.png)

テストとしてtest.mdに下記の内容を記載して矢印が指しているアイコンをクリックしてみましょう

```markdown
# テスト

- これはMarkdown Preview Enhancedのテストです。
```

![test_md-2-1024x589.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/2ad8d573-d667-3476-bc52-26a128fd63d5.png)

下記のように画面右側にプレビューが表示されていたらMarkdown Preview Enhancedは正常に動作しています。

![test_md-3-1024x587.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/f021fdeb-c067-c272-ffc1-a198ccf21f19.png)

## mermaid.jsの記載

プレビューを表示したままtest.mdに下記の内容を追記してみましょう。

```
    ```mermaid
    graph LR
        A[起床] --> B[朝食]
        B --> C[作業]
        C --> D[昼食]
        D --> E[作業]
        E --> F[夕飯]
        F --> G[就寝]
        G --> A
    ```
```

VScodeの画面が下記のようになってプレビューにはmermaid.jsの図形が表示されていることを確認します。

![test_md-4-1024x494.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/94ad73d0-2e98-81a0-76a9-1f1b9d858e34.png)

そうなんです！Markdown Preview Enhancedが動作していてMarkdownのpre記法を使用してmermaidを指定してあげるとmermaid.jsの図形を表示する事ができます！

この方法ならMarkdownのドキュメントの間にコードベースの図形を差し込むことができるので図形も含めてGit管理する事が可能になったり、直感的にドキュメントを修正したりできます！自分は前職でお客さんに見せるドキュメントなどをこの方法で作成したりしたことがあります！活用方法は無限大だと感じたのでよければ皆さん活用してみてください！
Ansible 配列が空の場合の処理(with_items)

## 配列の空判定
インベントリやロールで空の配列を設定したときの
条件文についてのメモ書き

### 変数設定
``` vars/main.yml
List_A:
  - 'Apple'
  - 'Orange'
  - 'Banana'

List_B:

```
「List_A」にはリストを登録し、「List_B」は何も登録しない

### 空判定がうまくいかないパターン
```playbook.yml
- hosts: localhost
  tasks:
    - name: List A Checks
      debug: msg="{{ item }}"
      with_items: "{{ List_A }}"
      when: List_A != ""

    - name: List B Checks
      debug: msg="{{ item }}"
      with_items: "{{ List_B }}"
      when: List_B != ""
```

```:実行結果
PLAY [localhost] ********************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************
ok: [localhost]

TASK [List A Checks] ****************************************************************************************************************************
ok: [localhost] => (item=Apple) => {
    "msg": "Apple"
}
ok: [localhost] => (item=Orange) => {
    "msg": "Orange"
}
ok: [localhost] => (item=Banana) => {
    "msg": "Banana"
}

TASK [List B Checks] ****************************************************************************************************************************
ok: [localhost] => (item=None) => {
    "msg": null
}

PLAY RECAP **************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```

変数が設定されていないが空が認識できずnullが出力される

### 空判定がうまくいくパターン
```playbook.yml
- hosts: localhost
  tasks:
    - name: List A Checks
      debug: msg="{{ item }}"
      with_items: "{{ List_A }}"
      when: List_A

    - name: List B Checks
      debug: msg="{{ item }}"
      with_items: "{{ List_B }}"
      when: List_B
```

```:実行結果
PLAY [localhost] ********************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************
ok: [localhost]

TASK [List A Checks] ****************************************************************************************************************************
ok: [localhost] => (item=Apple) => {
    "msg": "Apple"
}
ok: [localhost] => (item=Orange) => {
    "msg": "Orange"
}
ok: [localhost] => (item=Banana) => {
    "msg": "Banana"
}

TASK [List B Checks] ****************************************************************************************************************************
skipping: [localhost] => (item=None)
skipping: [localhost]

PLAY RECAP **************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
```

## 結論
リストの有無の判定のように記載しているが判定としてはtrue/falseの真偽を利用しているだけ。
本来ならlengthでの判定が一番良いのだろうが、自分の環境だとErrorしか返さないので、とりあえずこれで対応
Visual Studio Codeの拡張機能「Markdown PDF」を使ってみよう

## MarkdownファイルをPDF化したい

「Markdown形式で記載したファイルをそのままPDFにしたい」そんな需要に答えるのがこの「Markdown PDF」です。MarkdownファイルをVScodeで開いてクリックひとつでPDF化することができます。そんなMarkdown PDFの導入方法と簡単な使用方法をまとめます。

## 前提条件

今回はコードエディターであるVisual Studio Code（以降VScode）が導入されていることを前提としてお話を進めます。導入がまだの方は下記を参考に導入をお願いいたします！（少し古い記事なので方法が変わってたらごめんなさい！）

Macの方 ↓

https://qiita.com/miriwo/items/4ed96b54b4421fe9d275

Windowsの方 ↓

https://qiita.com/miriwo/items/710cf3b21cce539d8be2

## Markdown PDFの導入

VScodeを開いて下記画像の赤矢印部分をクリックして拡張機能のメニューを開きます。

![Visual_Studio_Code-1024x768.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/55903d4d-0d90-2cac-0304-5c9c35442da0.png)

検索ウインドウ「Markdown PDF」と入力すると検索結果に表示されるので「インストール」をクリックします。これで導入は完了です。

![Visual_Studio_Code-1-1024x768.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/86ad3237-9386-3e68-c37c-9f51d4fa7341.png)

## 使ってみよう

デスクトップ画面に「test.md」というファイルを作成し下記の内容を記載しましょう。

```markdown
# テスト

これはMarkdown PDFのテストです。
```

「test.md」をVScodeで開きましょう。

![test_md-1024x590.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/dacba06e-9239-2ab9-1596-0dbfd74fcdb1.png)

VScode上で右クリックし、「Markdown PDF: Export (PDF)」をクリックしましょう。

![スクリーンショット_2020-12-05_14_21_46-1024x589.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/45d53f9d-6ce5-4ea3-67c6-5135fe38f8b5.png)

出力中は右下に矢印のような表示が出ます。これが消えたらデスクトップを見てみましょう。PDFファイルが出力されています！これをダブルクリックで開いてみると・・

![AppleVPNExtra_と_AirPortExtra_と_BatteryExtra_と_AppleClockExtra_と_AppleUser_と_Item-0_と_NotificationCenter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/904b0920-0993-cc6f-6482-c2a17712a4ef.png)

Markdownで記載した内容がPDFで表示されています。

![test_pdf（1ページ）-1024x671.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/56c0860a-a21a-9789-0fb3-d131dc05d15a.png)

Markdown PDFはPDF以外にもHTML PNG JPEGなどにも出力可能です！とても便利なのでぜひ皆さんも使用してみてください！
今回はこれで以上となります。ありがとうございました。
Amazon S3 Transfer Acceleration

Amazon S3 Transfer Accelerationとは
--------------
Amazon S3 Transfer Accelerationは、クライアントとS3バケット間でファイル転送を高速かつ簡単で安全にできる

ユースケース
・1つのバケットに世界中からファイルのアップロードが行われる場合
大陸間で定期的にギガバイトからテラバイト単位でデータを転送する場合
インターネット経由のため、帯域幅等は考慮できないように見える

要件
・バケット名に「.」をが含まれていないこと
・Transfer Accelerationは仮想ホスト形式のリクエストでのみサポートされます
例
https://bucket-name.s3.region-code.amazonaws.com/key-name

設定方法
-------------------------
Amazon S3＞バケット＞バケット名＞プロパティ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3146038/24c72289-8caf-0005-f58c-9d536292b2da.png)

〇有効にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3146038/36dc25e1-ecd8-0a1a-d28b-4144eb095444.png)

※有効後は、無効にもできます。

料金
-------------------------
Amazon CloudFront のグローバルに分散したエッジロケーションを利用する
また、S3の転送量にプラスして料金が上乗せされるらしいです
※ここも少し実機動かして確認したいです
S3にデータ転送する場合は、無料ですがダウンロードする際は課金されます
よって、ダウンロード料金＋Transfer Accelerationが発生するに見えますね
米国、欧州、日本の AWS エッジロケーションによる高速化 0.04 USD/GB
https://aws.amazon.com/jp/s3/pricing/


実際に動かしてみる
-------------------------
```s3:cloudshell:accelerate
[cloudshell-user@ip-10-130-48-216 ~]$ ls -al test20240222
rw-r--r--. 1 cloudshell-user cloudshell-user 104857600 Feb 22 16:33 test20240222
[cloudshell-user@ip-10-130-48-216 ~]$ time aws s3 cp ./test20240222 s3://bucket名.s3-accelerate.amazonaws.com/ \
> --endpoint-url https://bucket名.s3-accelerate.amazonaws.com
upload: ./test20240222 to s3://bucket名.s3-accelerate.amazonaws.com/test20240222
real    0m3.297s　#コマンドの開始から終了までの経過時間
user    0m1.610s　#プログラムがCPUを使用した時間
sys     0m0.472s　#システムがCPUを使用した時間
```
```s3:cloudshell:S3
[cloudshell-user@ip-10-130-48-216 ~]$ time aws s3 cp ./test20240222 s3://バケット名             upload: ./test20240222 to s3://bucket名/test20240222
real    0m3.080s　#コマンドの開始から終了までの経過時間
user    0m1.525s　#プログラムがCPUを使用した時間
sys     0m0.544s　#システムがCPUを使用した時間
```

結果
-------------------------
何度か100MBのファイルをS3への転送をデフォルトで転送するパターンとTransfer Accelerationを利用しファイルを転送するパターンで検証した結果、CloudFrontを余計に経由するからか、Transfer Accelerationを利用し、ファイル転送した方が遅くなった

CloudFrontの仕様を理解していない
インターネット経由だから正確な値がでない
リージョン等の考慮していない

東京から東京リージョンS3バケットへファイル転送する場合には、遅い結果になるのかもしれない

https://docs.aws.amazon.com/cli/latest/reference/s3/

Transfer Accelerationを有効化した際に、エンドポイントが表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3146038/de72c8dc-08c6-1a19-9203-c2d51319da20.png)

https://aws.amazon.com/jp/s3/pricing/

あとでゆっくり読みたい
https://developers.play.jp/entry/2023/03/02/194851
【SwiftUI】@State がない カスタム ViewModifier を無邪気に View extension にしていいのだろうか謎

WWDC2022 SwiftUI の QA 抜粋です。

```
What’s the difference between a custom ViewModifier vs View extension

Q: What’s the difference between a custom ViewModifier (without DynamicProperty) that uses some built-in modifiers in body(content:), and a custom View extension func that just use those built-in modifiers?

Similarly, what’s the difference between a custom ViewModifier with some DynamicProperty and a custom View with some DynamicProperty (also has a @ViewBuilder content property to receive content to modify) ?

I think two have the same render result and behavior.

A: Because of the way a ViewModifier is expressed, the engine knows it’s not changing the content passed in and can apply performance optimizations (compared to just an extension on View)

カスタム ViewModifier と View extension の違いは何ですか ?

質問:
body(content:) でいくつかの組み込み modifier を使用するカスタム ViewModifier (DynamicPropertyなし)と、それらの組み込み Modifier を使用するカスタム View extension の違いは何ですか?

同様に、いくつかの DynamicProperty を持つカスタム ViewModifier と、いくつかの DynamicProperty を持つカスタム View の違いは何ですか ? (modify する content を受け取るための @ViewBuilder content property もあります)

2つは同じレンダリング結果と動作を持っていると思います。

回答:
ViewModifier の表現方法により、エンジンは渡されたコンテンツを変更していないことを知っており、パフォーマンスの最適化を適用できます。Viewの単なる拡張と比較すると。
```


【SwiftUI】カスタム ViewModifier の使い方と使いどころ 🤔
👉 https://android.benigumo.com/20240221/custom-viewmodifier/
推移的依存関係をわかりやすくみよう

# 推移的依存関係とは
ライブラリの中でさらにライブラリが使われてたりしますよね。

例えばAというライブラリの中でv1.0.0のBというライブラリが使われていたとします。
gradleを通してAのバージョンをアップデートして、Bはv1.0.0のままにしていたとしても、
アプデ後のAの中でもしv1.2.0のBが使われている場合、アプリではv1.2.0のBが使用されます。

![20240222_205516.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906559/01c4ca30-4b3e-214a-080a-a8eacb18e4e9.jpeg)

そーゆー感じのことを推移的依存関係と言います。
「推移的」に関しては「つられてバージョンあがっちゃった💦」みたいに解釈してます。私は。

# どんなシチュエーションで知りたくなる
業務で何かしらのライブラリのバージョンをアップデートするときに、つられて上がっちゃう他のライブラリちゃんがないか調べておきたいですよね。  

つられてあがっちゃったライブラリに破壊的変更が含まれていたら悲しいですから、**アップデートして大丈夫そうかどうか確認しておきたい**です。

# どんなツールでわかりやすく見れる
**[dependency-diff-tldr](https://github.com/careem/dependency-diff-tldr)** を使いましょう。

こんな感じで簡単に推移的依存関係のアップグレードを確認できます

```
New Dependencies
com.careem.identity:user-profile:0.0.63
project :miniapp:thirdparty

Upgraded Dependencies
androidx.annotation:annotation-experimental:1.0.0, (upgraded from 1.0.0-rc01)
androidx.constraintlayout:constraintlayout:2.0.2, (upgraded from 2.0.1)
androidx.constraintlayout:constraintlayout-solver:2.0.2, (upgraded from 2.0.1)
com.careem.care:helpcenter:0.0.17, (upgraded from 0.0.16)
com.careem.chat:core:3.1.6, (upgraded from 3.1.4)
```

これをﾌﾟﾙﾘｸのコメントとかにもはっちゃったりして、レビュアーに親切なﾌﾟﾙﾘｸを作れます :heart: :hear_no_evil: 

## 導入方法

[githubのReleases](https://github.com/careem/dependency-diff-tldr/releases)を見にいきます。 

そして最新バージョンのAssetsから`dependency-diff-tldr-r8.jar`をクリックしてダウンロードします。
![スクリーンショット 2024-02-22 21.10.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906559/60cf9ee8-b14f-fc49-4185-de40843c670d.png)


## 使い方

**ライブラリアップデート前の状態で**以下のコマンドを叩きます。

このコマンドで、`old.txt`というファイルを作成し、appモジュールの実行時に関連するライブラリの依存関係を取得してファイルに書き出します。

（実際に書き出せているかは`vim old.txt`で確認してみましょう。）
```
./gradlew :app:dependencies --configuration releaseRuntimeClasspath > old.txt
```

`releaseRuntimeClasspath`は実行中のアプリケーションがクラスやリソースを検索する場所（**実行時クラスパス**）を示すものです。

通常、リリースタスクの実行時クラスパスと実際に取り込んでいるライブラリは一致します。

なので、**アプリが使用しているライブラリの一覧を知るためには`releaseRuntimeClasspath`を見れば良い**ことになります。

:::note info
`[ビルドバリアント]RuntimeClasspath`とすることでそのビルドバリアントでの実行時のクラスパスを指定します。

参考：[モジュールの依存関係を表示する](https://developer.android.com/build/dependencies?hl=ja#view-dependency-tree)
:::


次に、**ライブラリのバージョンをアップデートして**、以下のコマンドを叩きます。

このコマンドでも同様に新しいバージョン後の実行時に関連するライブラリの依存関係を取得して`new.txt`ファイルに書き出します。

```
./gradlew :app:dependencies --configuration releaseRuntimeClasspath > new.txt
```

最後に、以下のコマンドで`old.txt`と`new.txt`を比較します。

```
java -jar dependency-diff-tldr-r8.jar old.txt new.txt
```

:::note warn
`old.txt`と`new.txt`と`dependency-diff-tldr-r8.jar`が同じディレクトリにあることを確認してください。異なる場所にある場合はそれぞれのフルパスを明記してください
```
java -jar [dependency-diff-tldr-r8.jarのパス] [old.txtのパス] [new.txtのパス]
```
:::

そしたらターミナル上に次のような一覧が表示されるはずです。

```
Upgraded Dependencies
androidx.room:room-common:2.6.1, (changed from 2.5.2)
androidx.sqlite:sqlite:2.4.0, (changed from 2.3.1)
org.jetbrains.kotlin:kotlin-stdlib:1.9.22, (changed from 1.7.21)
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1, (changed from 1.6.4)
...
```

> org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1, (changed from 1.6.4)

coroutineのバージョンが`1.6.4`から`1.7.1`にアップグレードされていルナあとかが分かりますね。 :eyes:
【SwiftUI】@ViewBuilder って逆にないほうが分かりやすくね ?

```swift
struct TitleTextFormatView<Content: View>: View {
  var content: Content

  var body: some View {
    content
      .font(.title)
      .foregroundColor(.red)
  }
}

// Error:
// Type '() -> VStack<TupleView<(Text, Text)>>' cannot conform to 'View'

TitleTextFormatView {
  VStack {
    Text("top")
    Text("bottom")
  }
}
```

【SwiftUI】 今日のなんでやねん - @ViewBuilder
👉 https://android.benigumo.com/20240222/viewbuilder/
mermaid.jsで作図しよう

## mermaid.jsって？？

公式ドキュメントは[こちら](https://mermaid.js.org/intro/)です
「Javascriptベースのダイアグラム作成およびチャート作成ツール」です。コードで図を作成することができます！2020/11/27現在ではフローチャート、シーケンス図、ガントチャート、クラス図、ユーザージャーニーダイアグラムなどをサポートしています。詳しい記載方法は公式ドキュメントか自分がまとめた別記事をご覧いただければ幸いです。

https://qiita.com/miriwo/items/4a9ba5cc14587d71d72f

「Mermaid Live Editor」というブラウザ上でmermaid.jsの記載とプレビュー、出力を行う事のできるサービスを利用します。まずはこちらにアクセスしてみてください。 ↓

https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbiAgQVtDaHJpc3RtYXNdIC0tPnxHZXQgbW9uZXl8IEIoR28gc2hvcHBpbmcpXG4gIEIgLS0-IEN7TGV0IG1lIHRoaW5rfVxuICBDIC0tPnxPbmV8IERbTGFwdG9wXVxuICBDIC0tPnxUd298IEVbaVBob25lXVxuICBDIC0tPnxUaHJlZXwgRltmYTpmYS1jYXIgQ2FyXVxuXHRcdCIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In19

下記のようなページが開くと思います。

![Online_FlowChart___Diagrams_Editor_-_Mermaid_Live_Editor_と_TODO.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/aa64df99-fd2e-8be2-eeca-5e6f6b513131.png)

初期段階でフローチャートが記載されています（クリスマスに買い物をするというフローチャートです。なんだかワクワクしますよね。）見ればわかると思いますが「Code」の部分のコードを記載して結果が「Preview」表示されます。

試しに下記の内容を「Code」に記載してみましょう。

```
graph LR
  A[起床] --> B[朝食]
  B --> C[作業]
  C --> D[昼食]
  D --> E[作業]
  E --> F[夕飯]
  F --> G[就寝]
  G --> A
```

下記のようにプレビューに下記の図が表示されていると思います。

![Online_FlowChart___Diagrams_Editor_-_Mermaid_Live_Editor_と_TODO.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/fde24f87-c156-a820-d389-951342395e3f.png)

表示されている図を画像ファイルとしてダウンロードしてみましょう。「Actions」にある「PNG」ボタンをクリックすることで図形を画像ファイルでダウンロードすることができます。

![Online_FlowChart___Diagrams_Editor_-_Mermaid_Live_Editor_と_TODO.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/9d79dbdb-14c2-9912-cdd6-3318dcefe29d.png)

ダウンロードする形式もpngとsvgで選べたり、図を表示するためのリンクを作成することもできます。

![Online_FlowChart___Diagrams_Editor_-_Mermaid_Live_Editor_と_TODO.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/5af8a4e4-6d1d-0ed5-05e0-1b45b2d6d4af.png)

最近だとQiitaもmermaidの作図に対応したりとこれからも盛り上がりそうで嬉しいです！

ちなみに下記のように記載することでQiitaの記事でも作図が可能です！

![uploading...0]()
研修期間前後で自分の成長をふりかえる

## まえがき

2020年3月からバックエンドエンジニアとして働かせていただいています。3月から9月までの研修期間を通して自分がどれだけ成長できたかを簡単にまとめてみたいと思います！

## 研修期間に実施した内容をまとめた記事

ダラダラ書いてあるので読まなくて大丈夫です！（笑）一応リンク貼っておいただけです！

https://qiita.com/miriwo/items/686e819ffea927c6c745

https://qiita.com/miriwo/items/7282d49374903e9b36b1

https://qiita.com/miriwo/items/dfb5485d106395d355b6

https://qiita.com/miriwo/items/314bd4c04ef117aa8333

https://qiita.com/miriwo/items/1aa60bc970c953a0c1f7

https://qiita.com/miriwo/items/9463d00a43e535df5b97

## 入社直後の知識レベル

- Ruby on Railsで簡単なWebアプリ開発ができる。
- herokuを用いたアプリのデプロイをすることができる。
- Webの基礎が理解できている。（リクエスト、レスポンスなど）
- MVC構造を知っている。
- 物理PCにLinuxを導入することができる。
- MacOSを触ったことがある。
- 調べながらならPHPの制御構文を記載することができる。

## 研修を終えての知識レベル

- LaravelでCRUD系処理の実装がスラスラできる。
- AWSのEC2 RDS S3 ElastiCacheがどういうものなのか自分なりの言葉で説明できる。
- SQLが考えられる。
- yumを用いたインストールをすることができる。
- 実案件の作業が先輩に相談しながらなら実施できる。

## まとめ

知識レベルの個数だけで言ったら減っています。しかしながら各項目でより深く理解が深まったと思えます。基礎的な部分で最も大きいのがSQLが苦なく考えられるようになったことです。入社時点では一切触ったことなかったSQLですが、joinなどを用いてほしいデータを取得できるようになりました。　ほぼほぼ触ったことのなかったLaravelにも慣れアプリの作成や画像のアップロード、ライブラリの入れ方もわかりました。少しインフラ側の話ですがyumを用いたパッケージの正しいインストール方法（-yを使わない、リポジトリを指定してインストール、そもそものyumインストールの概要）も理解できました。そして最も大きい内容としては最後に書いてある「実案件の作業ができるようになった」ということです。まだまだ全然一人前には満たないですが「お金になる作業」に参加できるようになったことは非常に大きいと思います。

## 次のステップ

自分が考える次のステップとしては「実案件の作業で自己完結ができるようになる」だと考えています。上司の方ともこのお話はしていて、時間は少しかかってしまってもいいから一人で作業できることをまずは考えたいと思っています。更に次のステップとしては「一人で時間内に作業が完了することができる」だと思います。本記事を書いている2020/11/19現在やっと実案件の作業を自己完結できるかできないかくらいになってきたので時間も意識しつつでより成長していこうと思います！
Bottle(Python)とjQueryのAjaxで時計を作る

雑記。書き足す予定です。

# 概要
Ajaxを使って、Pythonで算出されて出力した値をリアルタイムでWebサイトに表示したい。Pythonでロボットを制御して、かつWebアプリケーションとしてブラウザから制御や監視ができるようにすることでロボコンに活用したい。

時計は動作が一番わかりやすく、かつ自動で定期的にロードされる点がとても勉強になると考えて書いた。JavaScriptではなくPythonのdatetimeで現在時刻を取得している、すなわちサーバーサイドで取得している。

# 環境
* Windows 11
* Python 3.12.2
* VSCode

# 環境構築
bottleをpipでインストールします。
```:Powershell
pip install bottle
```

# プログラムを書く
## Python
```:bottle_test.py
from bottle import route, run, template
import datetime, json

@route('/')
def hello():
    return "<h3>Hello!</h3><p>こんにちは！</p>"
    
@route('/ajax')
def ajax():
    return template('ajax')
    #return "hello"

@route('/ajax/update')
def ajax_update():
    dt = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    dict = {'dt': dt}
    return json.dumps(dict)

# 最後に書く（これより下に書いても反映されない）
if __name__ == '__main__':
    run(host = 'localhost', port = 5555, debug = True, reloader = True)
```

## テンプレートファイル（フロントエンド的な）
今回はhtmlとしたが、tplを使うとPythonをテンプレートファイル内で実行できる（```%```を最初に入れるとPythonのコードと認識される）。
```:views/ajax.html
<!DOCTYPE html>
<html lang="en">
<head>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>World Clock</title>
</head>
<body>
    <h1>Hello!</h1>
    <div id = "time"></div>
    <script type="text/javascript">
        function reloadClock() {
            $.ajax("/ajax/update", {
                type: "get"
            }).done(function(received_data) {           // 戻ってきたのはJSON（文字列）
                var dict = JSON.parse(received_data);   // JSONを連想配列にする
                // 以下、Javascriptで料理する
                var dt = dict["dt"];
                $("#time").html(dt);              // html要素を書き換える
            }).fail(function() {
                console.log("失敗");
            });
        };
        reloadClock();
        setInterval(reloadClock, 10);
    </script>
</body>
</html>
```

# 起動
```:Powershell
python bottle_test.py
```

# 動作の内容
BottleはGETが行われたときのみしか通信が行われないため、Ajaxで通信を行って書き換える。簡潔に言えば定期的にGETを行って別ページで情報を出力させ、Ajaxを使って書き換え・表示反映を行ったというだけである。

動作は```localhost:5555/ajax```で確認できる。JavaScriptで```div#time```の中のテキストを書き換える。この時reloadClock関数を定期的に実行することで、jQueryを利用してAjax通信する。```/ajax/update```に接続して、Python上でdatetimeを動かし時刻を取得（ブラウザではなくサーバー、今回はBottleで時刻を取得している点が重要）、JSON形式で時刻を出力させる（実際、```/ajax/update```に接続するとJSON形式で表示される）。得られた値をもとにテキストを書き換えている。

# 参考
* Ajaxについて（Flaskを使った事例）：https://qiita.com/mo256man/items/d3f1761e8454d1bd8305
* Bottleについて：https://www.mgo-tec.com/blog-entry-raspi4-python-bottle1.html#title02-01
使いたいSTMマイコンがPlatformIOにないときに。

みなさんはPlatformIO使ってますか？僕は大好きです。
さて、PlatformIOではたくさんのSTMマイコンを使うことができますが、STMマイコンはそれ以上に数があり、自分の使いたいマイコンがない！ということもあるかもしれません。
というわけで、その解決方法を紹介します。


# 前提
今回の記事で解決できるのは、「**そのマイコンのNucleoボードはあるが生(Generic)STMがない**」または**その逆**のときのみです。
両方ない場合はこの記事を読んでも解決できないのでご了承ください。

:::note warn
両方ない場合は、自分でピン情報などを定義する必要があり、一気にハードルが上がります。
:::

# 説明
まず、PlatformIOのディレクトリをのぞいてみましょう。
`platforms`フォルダの中に`ststm32`というフォルダがあります。
この中の`boards`と`misc\svd`が大事になります。
中を見ればわかりますが、`boards`には各ボードの情報が50行程度のjson形式で保存されています。つまり、ここにjsonを追加すれば、PlatformIOで使うことができるのです。
そして、`misc\svd`には何万行もにわたってマイコンのピン情報などが保存されています。これがあるおかげで快適なコーディングができるわけです。

さて、すでにお気づきの方もいらっしゃるかもしれませんが、`boards`ではNucleoボードと生STMは分けてある一方で、**`svd`はどちらも共通なのです！**（そりゃマイコンは同じだもん）
なので、どっちかさえもともと存在していれば、長ったらしいファイルを作る必要はなく、jsonだけパパっと書くだけでばいいのです！

# やろう
今回は例として、Nucleo H723ZGからSTM32H723ZG (Generic)を作ってみます。

上で説明したように、jsonだけ作ればよいです。
`boards`フォルダに新しくjsonファイルを作ってください。
ファイル名はほかに合わせて`genericSTM32H723ZG.json`とかにでもしておきましょう。

できたら何らかのエディタで開いて編集できるようにし、まずNucleoのjson（今回なら`nucleo_h723zg.json`）から全てコピペしてください。

そしていくつか変更します。

先に完成状態を見せてしまいます。

``` json:genericSTM32H723ZG.json
{
    "build": {
        "core": "stm32",
        "cpu": "cortex-m7",
        "extra_flags": "-DSTM32H7xx -DSTM32H723xx",
        "f_cpu": "550000000L",
        "mcu": "stm32h723zgt6",
        "product_line": "STM32H723xx",
        "variant": "STM32H7xx/H723Z(E-G)T_H730ZBT_H733ZGT"
    },
    "connectivity": [
        "can",
        "ethernet"
    ],
    "debug": {
        "jlink_device": "STM32H723ZG",
        "openocd_target": "stm32h7x",
        "svd_path": "STM32H723.svd"
    },
    "frameworks": [
        "arduino",
        "cmsis",
        "stm32cube",
        "libopencm3"
    ],
    "name": "STM32H723ZG (564k RAM. 1024k Flash)",
    "upload": {
        "maximum_ram_size": 327680,
        "maximum_size": 1048576,
        "protocol": "serial",
        "protocols": [
            "blackmagic",
            "dfu",
            "jlink",
            "serial",
            "stlink"
        ]
    },
    "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32h723zg.html",
    "vendor": "Generic"
}

```

変更するところは5か所ほどです
### debug
NucleoにはST-LINKがついていますが生STMにはついていませんので該当箇所を消します。
### frameworks
若干Nucleoのものとは違います。これは他のgenericSTMのjsonからコピペで大丈夫です（たぶんgenericSTMは一緒で大丈夫なはず）。
### name
名前は変えましょう。他のものに合わせるとよいです。
### uploadのprotocols
frameworksと同じように他のjsonからコピペしてください
### url・vendor
urlは別に自分用ならなくてもいい気がしますが一応、製品ページを書いておきましょう。
vendorはGenericに。


これで保存すればPlatformIOで新しく作ったボードが選択できるようになると思います。

### 最後に
筆者もまだまだマイコン初心者なので何か間違い・ご意見ありましたら是非コメントお願いします。
systemd-timesyncdでNTPサーバに接続できない

# はじめに
LinuxでNTPクライアントの設定をするとき、いろいろなエラーに遭遇してきたので、解決策のメモです。

※この記事はNTPクライアントでのトラブルシューティングです。NTPサーバに問題があるときは、この記事を読んでも解決しません！

# ログの確認方法
以下のコマンドを実行してログを確認します。正常な場合は次のようなログが表示されます。
```
$ sudo journalctl -u systemd-timesyncd
-- Logs begin at Wed 2023-02-01 10:15:00 JST, end at Fri 2024-02-16 12:41:13 JST. --
Feb 16 12:43:01 ntp-cli systemd[1]: Stopping Network Time Synchronization...
Feb 16 12:43:01 ntp-cli systemd[1]: systemd-timesyncd.service: Succeeded.
Feb 16 12:43:01 ntp-cli systemd[1]: Stopped Network Time Synchronization.
Feb 16 12:43:01 ntp-cli systemd[1]: Starting Network Time Synchronization...
Feb 16 12:43:01 ntp-cli systemd[1]: Started Network Time Synchronization.
Feb 16 12:43:01 ntp-cli systemd-timesyncd[10478]: Initial synchronization to time server 192.168.1.2:123 (192.168.1.2).
```

# 症状1 Server has too large root distance.
```
$ sudo journalctl -u systemd-timesyncd
～中略～
Feb 01 01:15:10 ntp-cli systemd-timesyncd[1]: Network configuration changed, trying to establish connection.
Feb 01 01:15:10 ntp-cli systemd-timesyncd[1]: Server has too large root distance. Disconnecting.
```

設定ファイルのRootDistanceMaxSecを設定すると直ることがあります。初期値は5ですが、この値を増やします。
```
$ sudo vi /etc/systemd/timesyncd.conf
[Time]
NTP=192.168.1.2
#FallbackNTP=ntp.ubuntu.com
RootDistanceMaxSec=30
#PollIntervalMinSec=32
#PollIntervalMaxSec=2048
```

設定ファイルを更新したら、サービスを再起動します。
```
$ sudo systemctl restart 
systemd-timesyncd.service
```
# 症状2 Failed to run 'start' task: Not a directory
```
$ sudo journalctl -u systemd-timesyncd
～中略～
Jan 11 01:47:42 ntp-cli systemd[1]: systemd-timesyncd.service: Failed to run 'start' task: Not a directory
Jan 11 01:47:42 ntp-cli systemd[1]: systemd-timesyncd.service: Failed with result 'resources'.
Jan 11 01:47:43 ntp-cli systemd[1]: Failed to start Network Time Synchronization.
```

tmpがディレクトリではなくファイルになっていました。tmpを再作成したら直りました。
※ファイルを削除してしまうので、実行に注意してください！
```
$ sudo rm /var/tmp
$ sudo mkdir /var/tmp/
$ sudo chmod 777 /var/tmp/
$ sudo chmod +t /var/tmp/
$ sudo systemctl restart systemd-timesyncd.service
```

# 症状3 Timed out waiting for reply from
```
$ sudo journalctl -u systemd-timesyncd
～中略～
Jan 11 02:45:02 ntp-cli systemd-timesyncd[249]: Timed out waiting for reply from 192.168.1.2:123 (192.168.1.2). 
Jan 11 02:45:12 ntp-cli systemd-timesyncd[249]: Timed out waiting for reply from 192.168.1.2:123 (192.168.1.2).
```
時刻設定を確認します。
```
$ date
```

表示された時刻が実際の時刻より大幅にずれている場合は、現在時刻に手動で合わせます。
※ 大幅に時間がずれていると、NTPサーバとの接続に失敗します。
```
$ date -s "2024-2-13 00:17:38"
```

時刻を更新したら、サービスを再起動します。
```
$ sudo systemctl restart 
systemd-timesyncd.service
```

# 最後に
この記事が何かの役に立てれば幸いです。
またエラーに遭遇したら、記事を更新しようと思います。

# 謝辞
以下の投稿には大変お世話になりました。

https://benkyou.work/windows/ntp-server/

https://stackoverflow.com/questions/52170218/apache2-service-failed-to-run-start-task-no-such-file-or-directory
研修内容を振り返る 2020.08~2020.09

## まえがき

2020/03/09からバックエンドエンジニアとして働かせていただいています。前回の記事に引き続き8月から9月にかけての自分が研修内容と実際に実施した内容・振り返りなどを一か月毎に区切って記事にしたいと思います。いよいよ研修も最後の月です。すべての研修を通しての振り返りは次週記事にしたいと思います。

前回の記事はこちら

https://qiita.com/miriwo/items/1aa60bc970c953a0c1f7

## ご注意

- 本内容は研修を受けた自分が感じた主観であり、弊社の意向と異なる可能性があります。
- ご入社いただいたみなさんに必ず本研修を受けていただくということではありません。
- 研修内容に関してはメモを取っていましたが実際の内容と異なる可能性があります。
- 情報セキュリティの観点から一部実名を伏せて記載することがあります。

## 2020.08の自分のレベル

前提情報として2020.07時点での自分の知識レベルを簡単に書いてみます。

- 「こんなサービスを作りたい」を時間はかかるが自分の手で形にできる。
- AWS EC2でサービスを動作させアプリからS3にファイルをアップロードする事ができる。

## 研修のサポート

2020.04の記事と同じですが、毎日上司の方とzoomを用いて10分~30分程度のミーティングを行いました。また、弊社のSlackにある技術的な内容を質問できるチャンネルで詰まった部分の相談に乗ってもらったりしました。

## 2020.09までの主な研修内容

- 自社プロダクトの設計と開発

### 研修内容をちょっと深掘り

#### 自社プロダクトの設計と開発

先月から設計していた自社プロダクトの作成を開始しました。とりあえず今構想しているサービスを形にすることを目標に開発を行い、綿密に上司の方と認識合わせをして作成したというより今までの研修で得た知識を使ってなるべく人の手を借りずに作成しました。もちろん進捗具合や完成品の確認はしていただき毎日フィードバックを頂きました。

## 得た知識

- 画面デザインや機能を決める→実装の流れの重要さ
- ユーザの認証情報と管理者の認証情報保存を分ける方法
- 新規登録ユーザのメールアドレス確認方法
- クエリビルダの使用方法

## 苦労した点

- 仕様変更に弱いサービスになってしまった

### 苦労した点をちょっと深堀り

#### 仕様変更に弱いサービスになってしまった

5ヶ月研修をしてきたとはいえまだまだド素人に変わりは無く、要求された機能を満たすアプリを作ることが精一杯でした。結果、一箇所修正したときの影響範囲がとてつもないことになり修正に時間がかかりました。具体的には「コントローラにほぼすべての処理が記載されておりビジネスロジックとDBアクセス処理の分離ができていない」「テーブルにカラムが足りておらず何度もマイグレーションを実施する」などがありました。加えてテストコードも書いておらず確認はブラウザでの動作確認だったため見落としも多発しました。今でこそサービス層やインターフェース、リポジトリなどの活用方法やテーブルのリレーションが少しづつ理解でき、実装できるようにはなってきましたので当時作っていたものがいかにメンテンス性が悪いものであるかがわかります。

## 最後に

今回の記事で研修内容をすべて書き終わりました。研修を通した振り返りは次週書こうと思います。苦労した点にも書きましたが仕様を形にすることに注力しいっぱいいっぱいになっていました。コーディングのセオリー的な部分もほぼなかったため非常に遠回りした気もします。例えばビューファイルの表示をDBから取得したデータによって切り替えたいときなどはすべてifディレクティブで記載していたりしました。（今なら三項演算子使ってもう少しスマートに記載できる。）とはいえ一人で仕様に沿ったサービスを作れるようになってきたのは自信に繋がりました。
スタンドアロン環境でのUiPath Assistant利用時のオートメーション表示


# はじめに

UiPath StudioがOrchestratorと接続していない場合は、デフォルトのパブリッシュ先はC:\ProgramData\UiPath\Packagesになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177240/dbd7deaa-0ee0-1ad7-cb99-95fd436b256b.png)
一度パッケージがこの場所に公開されると、その端末を使用する全てのユーザーがアクセスし、UiPath Robotを介して自動化プロセスを実行することが可能になります。
これにより、企業や組織内での自動化の展開と管理が容易になり、異なるユーザー間でのプロセス共有がスムーズに行えるようになります。

# しかし、こんなことに困っていますか

複数のユーザーがたくさんのパッケージをパブリッシュすると、こんな問題に直面したことはありませんか？
- 自分がパブリッシュしたオートメーションを、他の利用者に見せたくない。
- 表示されるオートメーションが多すぎて、探すのが大変。

　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177240/1d9d5e40-66ee-f3d7-8bad-1b18f6498938.png" alt="見せたくないよ！" width="240">

# どう解決するのか

デフォルトのパブリッシュ先はC:\ProgramData\UiPath\Packagesに設定されています。このパブリッシュ先をユーザーごとのフォルダーに変更することで、ユーザーに応じたパブリッシュ先や、UiPath Assistantで表示される内容を個別に管理できます。

これからの操作は、以下の環境で行います。環境によっては、操作手順やファイルパスが異なる可能性があることをご了承ください。
- UiPath Studio(Assistant): 2023.4.5
- Microsoft Windows 10 Pro 10.0.19045、二つのユーザー(User01/User02)

## UiPath.settingファイルの編集

UiPath.settingsファイルには、以下のような内容が記載されています。NuGetServerUrlを修正することにより、UiPath Studioのパブリッシュ先およびAssistantでのパッケージ読み込み先を変更することができます。

```json
{
  "SecureLicenseKey": "",
  "TracingLevel": "Information",
  "UiPathServerUrl": "",
  "ConnectionString": "",
  "ActivitiesFeed": "",
  "NuGetApiKey": "",
  "NuGetServerUrl": "%ProgramData%\\UiPath\\Packages",
  "LowLevelTracing": false,
  "LoginToConsole": true,
  "ResolutionWidth": 0,
  "ResolutionHeight": 0,
  "ResolutionDepth": 0,
  "FontSmoothing": false
}
```

UiPath.settingファイルは`C:\Users\%username%\AppData\Local\UiPath\`に保存しています。
このファイルを管理者権限で開き、例えば、パブリッシュ先を`C:\Users\%username%\AppData\Local\UiPath\PKG` フォルダーに変更したい場合は、NuGetServerUrlを以下のように修正します。

```json
  "NuGetServerUrl": "C:\\Users\\%username%\\AppData\\Local\\UiPath\\PKG",
```

変更が完了したら、UiPathの関連サービスを再起動し、UiPath StudioとAssistantも再起動してください。

UiPath Studioでワークフローをパブリッシュすると、パブリッシュ先が以下のように変わります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177240/003d6a2d-7b3a-6db4-56b4-78455d8acd54.png)

Assistantにもパブリッシュしたオートメーションが表示されるようになります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177240/c2c4ee66-9799-5925-9721-1fc1382ba34b.png" alt="パブリッシュ先変更" width="360">

別のユーザーアカウントでログインし、Assistantを起動すると、先ほどのオートメーションが表示されていないことを確認できます。

これにより、以下の二つの問題を解決できました。
- 自分がパブリッシュしたオートメーションを他の利用者に見せたくない。
- 表示されているオートメーションが多すぎて、探すのが大変。


# 最後に

UiPath.settingファイルは`C:\Users\%username%\AppData\Local\UiPath\`に保存されてしているため、パブリッシュ先をデフォルトのC:\ProgramData\UiPath\Packagesから変更する場合は、ユーザーごとにUiPath.settingファイルを変更する必要があります。

# 参照資料

https://docs.uipath.com/ja/robot/standalone/2023.10/user-guide/uipathsettings-file-description
研修内容を振り返る 2020.07~2020.08

## まえがき

2020/03/09からバックエンドエンジニアとして働かせていただいています。前回の記事に引き続き7月から8月にかけての自分が研修内容と実際に実施した内容・振り返りなどを一か月毎に区切って記事にしたいと思います。

前回の記事はこちら

https://qiita.com/miriwo/items/314bd4c04ef117aa8333

## ご注意

- 本内容は研修を受けた自分が感じた主観であり、弊社の意向と異なる可能性があります。
- ご入社いただいたみなさんに必ず本研修を受けていただくということではありません。
- 研修内容に関してはメモを取っていましたが実際の内容と異なる可能性があります。
- 情報セキュリティの観点から一部実名を伏せて記載することがあります。

## 2020.07の自分のレベル

前提情報として2020.07時点での自分の知識レベルを簡単に書いてみます。

- AWSのEC2を使ってLaravelの動作環境を構築することができる
- EC2、S3を使ったことがある

## 研修のサポート

2020.04の記事と同じですが、毎日上司の方とzoomを用いて10分~30分程度のミーティングを行いました。また、弊社のSlackにある技術的な内容を質問できるチャンネルで詰まった部分の相談に乗ってもらったりしました。

## 2020.08までの主な研修内容

- 自社プロダクトの設計

### 研修内容をちょっと深掘り

#### 自社プロダクトの設計

とある自社プロダクトの作成も進行中です。そんな中でメインのアプリではないものの自社プロダクトの設計を行いました。モックアップアプリの作成を実施しました。画面の洗い出し→当該画面で必要なデータの抽出→DBの設計というように進みました。

## 得た知識

- サービス作成の概要を知ることができました。モックアップアプリなので自分が設計したものがそのまま実運用されるものではないので100%実務と一緒かと言われるとそうでもない気がします。しかしながら、依頼主さんと相談（今回の場合上司の方）→設計→作成の大枠位の流れを実体験として学べたことはとても大きかったと思います。

## 苦労した点

- 先を見通した設計

### 苦労した点をちょっと深堀り

#### 先を見通した設計

「後々の改修が楽になるように」や「拡張性をもたせる」「メンテナンス性を考えたDB構造」などに非常に苦労しました。中でもDBの構造はとても苦労しました。DBを作成する段階での認識の齟齬や完全決定前にDBの作成を始めてしまったことが要因でテーブルの作り直し、カラムの作成し直しが頻発し時間がかかってしまいました。モックアップアプリ&自社プロダクトである点で迷惑を掛ける範囲が狭かったのでまだ良かったですが、実案件だった場合炎上待ったなしのアンチパターンで開発をしてしまいました。ただ、初心者の時期にアンチパターンを体験できたことは非常に良かったと思います。最初の仕様決定がいかに大切であるか身にしみました。

## 最後に

6ヶ月に渡って実施していただいた自分の研修も大詰めに差し掛かってきました。受託案件入りの話もちょこちょこ出始めた頃です。次の投稿で研修内容をまとめる記事は最後になります！研修を通してどのくらい知識が溜まったのかもまとめたいと思います。
研修内容を振り返る 2020.06~2020.07

## まえがき

2020/03/09からバックエンドエンジニアとして働かせていただいています。前回の記事に引き続き6月から7月にかけての自分が研修内容と実際に実施した内容・振り返りなどを一か月毎に区切って記事にしたいと思います。

前回の記事はこちら

https://qiita.com/miriwo/items/dfb5485d106395d355b6

## ご注意

- 本内容は研修を受けた自分が感じた主観であり、弊社の意向と異なる可能性があります。
- ご入社いただいたみなさんに必ず本研修を受けていただくということではありません。
- 研修内容に関してはメモを取っていましたが実際の内容と異なる可能性があります。
- 情報セキュリティの観点から一部実名を伏せて記載することがあります。

## 2020.06の自分のレベル

前提情報として2020.06時点での自分の知識レベルを簡単に書いてみます。

- 既存サービスからDBの構造を推測する事ができる。
- Laravelを使ったCRUD処理がすぐに実装する事ができる。

## 研修のサポート

2020.04の記事と同じですが、毎日上司の方とzoomを用いて10分~30分程度のミーティングを行いました。また、弊社のSlackにある技術的な内容を質問できるチャンネルで詰まった部分の相談に乗ってもらったりしました。

## 2020.07までの主な研修内容

- AWS EC2とS3に慣れよう
- 実案件のサーバサイドコードをAWS EC2を使ってデプロイしてみよう

### 研修内容をちょっと深掘り

#### AWS EC2とS3に慣れよう

EC2インスタンスの作成部分から経験し、yumを用いたApacheのインストールとドキュメントルートに設置したindex.htmlの表示から始まりとにかくAWSのEC2とS3を使ってみてなれてゆくというものです。

#### 実案件のサーバサイドコードをAWS EC2を使ってデプロイしてみよう

本当の案件で使用しているフロントエンドのソースを使ってバックエンド側の処理を自分で考えて記載したソースコードをAWS EC2でデプロイするというものです。

## 得た知識

- yumを用いたパッケージインストールは慎重に行う、「リポジトリを指定しない」や「パッケージインストール時に-yをつける」などは本来良くない方法
- AmazonLinux2インスタンスはCentOSベースだが環境構築など若干異なる部分がある
- そもそも「EC2のインスタンスを借りる」ということは「CentOSのは行ったPCを借りている」と同じこと

## 苦労した点

- AWS EC2そのもの
- EC2インスタンスでのLaravel動作環境の構築

### 苦労した点をちょっと深堀り

#### AWS EC2そのもの

そもそもではありますが「EC2のAmazonLinux2インスタンス」がどういうものなのか理解するまで苦労しました。今までAWSはRailsチュートリアルでcloud9を使ったことある程度でノータッチでした。
しかしながら前職がオンプレのUbuntuサーバマシンを使っており、LinuxのPC構築経験だけは豊富でした。「Linuxが入ったサーバPCを貸してくれるのか！」と理解できてからはそこまで苦労しなかった記憶があります。ただCentOSはノータッチだったので勝手をしりたくて、家のジャンクラップトップPCにCentOSを入れて色々動作を確認したりしました。

#### EC2インスタンスでのLaravel動作環境の構築

yumを用いたパッケージインストールにとにかく苦労しました。Ubuntuだとapt getコマンドを用いてパッケージはインストールしていたのでリポジトリを指定してインストールするということにまず慣れません。
さらにしっかりと理解していない状態でyumコマンドを実行したものなので、入れるパッケージは合っているけどリポジトリが正しくないことが多発し、弊社技術ブログ「インフラ刑事」の作者の先輩に助けてもらいました。
先輩の方法を見ながらプライベートで使用しているインスタンスとCentOSのPCにLaravelの動作環境を構築しました。非常に勉強になりたくさんの知見が得られました。得た知見は下記のリンク先にまとめてあります。

https://qiita.com/miriwo/items/a1ab84c098008e43d042

https://qiita.com/miriwo/items/c0ba0ff17c329700fc9e

https://qiita.com/miriwo/items/7d94303e7185e4118f52

https://qiita.com/miriwo/items/b25f9d4d74b7103f6ff6

https://qiita.com/miriwo/items/b39d1ac6289c54cc2cfd

## 最後に

AWSをいじり始めて新しいこと、知らないことばかりでとても楽しかった一ヶ月でした。LinuxのPCを構築するのは好きなのでEC2インスタンスの勝手がわかってしまえば辛さも吹き飛び楽しみながら習得できました！
次の記事は2020.08までの研修内容をまとめたいと思います。
DockerコンテナをAWS ECSに移行　その１ Docker Engineインストール

# きっかけ
　Dockerはすごく便利です。さらに便利になるよう、そのコンテナをマネージド利用するべく、ECS on Fargateに移行してみました。
 構築手順の量が多く、特にECSの設定は間違いなく忘れる自身があります ^^;
 最初のdocker構築からECS構築までの一連の流れについて、忘却の彼方へ記憶が飛ぶ前に、記録しておきたいと思いました

# Qiitaの記事の構成、今回、次回、今後について
- その１：今回の記事
    - Docker Engineインストール
- その２：次回の記事
    - Docker Composeで、wordpress＋mysqlを構築
- その３：今後の記事
    - その２のDocker Compose構成を、ECS on Fargateに移行

# 構築の前提
- 移行元マシン
    - AWS EC2 Ubuntu 20.04 LTS


# dockerエンジン インストール手順
古いバージョンのアンインストール
```
$ sudo apt-get remove docker docker-engine docker.io containerd runc
```
---
リポジトリのセットアップ
```
$ sudo apt-get update
$ sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
```
---
Docker の公式 GPG 鍵を追加
```
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
```
---
以下のコマンドを使って安定版（stable）リポジトリをセットアップ
```
$ echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```
---
Docker Engine のインストール
```
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
```
---
Docker Engine をhello-worldコンテナイメージで動作確認
```
$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete
Digest: sha256:d000bc569937abbe195e20322a0bde6b2922d805332fd6d8a68b19f524b7d21d
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
```
---
Dockerイメージの確認
```
$ sudo docker images -a
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    d2c94e258dcb   9 months ago   13.3kB
```
---
全てのコンテナ一覧(停止中のコンテナ含む)
```
$ sudo docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED         STATUS                     PORTS     NAMES
20dda2dab55d   hello-world   "/hello"   7 minutes ago   Exited (0) 7 minutes ago             vibrant_beaver
```


### 次回に続く
研修内容を振り返る 2020.05~2020.06

## まえがき

2020/03/09からバックエンドエンジニアとして働かせていただいています。前回の記事に引き続き5月から6月にかけての自分が研修内容と実際に実施した内容・振り返りなどを一か月毎に区切って記事にしたいと思います。

前回の記事はこちら

https://qiita.com/miriwo/items/7282d49374903e9b36b1

## ご注意

- 本内容は研修を受けた自分が感じた主観であり、弊社の意向と異なる可能性があります。
- ご入社いただいたみなさんに必ず本研修を受けていただくということではありません。
- 研修内容に関してはメモを取っていましたが実際の内容と異なる可能性があります。
- 情報セキュリティの観点から一部実名を伏せて記載することがあります。

## 2020.05の自分のレベル

前提情報として2020.05時点での自分の知識レベルを簡単に書いてみます。

- マイグレートを実行してテーブルの作成をすることができる。
- Laravelアプリにユーザ認証機能を付与することができる。

## 研修のサポート

2020.04の記事と同じですが、毎日上司の方とzoomを用いて10分~30分程度のミーティングを行いました。また、弊社のSlackにある技術的な内容を質問できるチャンネルで詰まった部分の相談に乗ってもらったりしました。

## 2020.06までの主な研修内容

- 既存Webサービスのテーブル設計とSQLを考えてみよう。の続き。
- 実案件のフロントエンドのコードをもらってバックエンド側の処理を自分で書いてみよう。

### 研修内容をちょっと深掘り

#### 既存Webサービスのテーブル設計とSQLを考えてみよう。の続き。

現在すでに世の中で利用されているWebサービスの一つの機能を上司の方と選び、当該の機能全体や個々のページを表示するにはどの様なテーブルが必要か、どの様なSQLを実行すれば必要なデータを取得することができるかを考えます。機能の視野を広げてさらに多くのSQLを考えます。

#### 実案件のフロントエンドのコードをもらってバックエンド側の処理を自分で書いてみよう

本当の案件で使用しているフロントエンドのソースを使ってバックエンド側の処理を自分で考えて記載します。本物のバックエンドのソースは見ずに自分だけで考えて実装してゆきます。一旦現状の自分の知識だけでソースを書いてみて上司の方にみてもらいアドバイスを受けます。

## 得た知識

- より多くのテーブルとの関係性と複雑なテーブル結合の方法
- SQLは一行づつ確認しながら記載してゆけばそこまで句では無い
- DBへの問い合わせはなるべく回数を抑える

## 苦労した点

- DBへの問い合わせ回数を減らす。
- クエリビルダを用いたデータ取得

### 苦労した点をちょっと深堀り

#### DBへの問い合わせ回数を減らす。

先月は表示するデータを取得することを最優先に考えSQL文を考えてきました。それこそselect文をたくさん並べるなどしていました。しかし実運用的にはレスポンスを重視するとDBへの問い合わせ回数は減らすべきであり最小回数で当該ページのデータを取得します。結合などの概念は理解はしてきましたが若干の苦手意識があり複数のテーブルに跨がる結合などはとても苦労しました。この頃の自分でも一行一行確認しながら記載すれば可能ではありましたが「DBアクセスを最小限にする」を考えながらだと非常に難しかった記憶があります。

#### クエリビルダを用いたデータ取得

SQL文を習得したことによりクエリビルダを用いたデータ取得をコードに織り交ぜる様になりました。今でこそ簡単にできますが、素のSQLとは若干異なる部分が苦労した思い出です。また取得したデータの配列の構造にも翻弄されました。

## 最後に

入社後二ヶ月が経過し少しづつ実践的な内容に入ってきました。一切実施したことない内容を習得できる時間感がすこしづつわかってきました。次の記事は2020.07までの研修内容をまとめたいと思います。
セキュリティグループの設定をコピーする

# はじめに

AWSの管理コンソールを触っていたら、セキュリティグループをまっさらな状態から作るのではなく、既存のセキュリティグループの設定を複製する方法があることに気付いたので、その方法を備忘録としてまとめてみました。


# 方法

* AWSのEC2サービスの画面に入り、画面左側のツリーで［ネットワーク & セキュリティ］から［セキュリティグループ］を選びます。
* 所望のセキュリティグループを選択して、［アクション］→［新しいセキュリティグループにコピー］を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/f85508d5-0d60-643e-1594-a6ee9eb91929.png)

* ［新しいセキュリティグループにコピー］画面が開いたら、ソースセキュリティグループ（※コピー元のセキュリティグループ）が正しいことを確認します。
* さらにセキュリティグループ名やVPCを入力して、インバウンド/アウトバウンドのルールを適宜変更した上で、［セキュリティグループを作成］を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/c31b7454-5289-2ea1-6106-f5cb5fffb736.png)

# まとめ

* GUIでこれほど簡単に設定をコピーできるとは思いませんでした。
* セキュリティグループの設定を変える前に、この方法でバックアップしておくのも良いかもしれません。

# 参考URL

* [既存のセキュリティグループから新しいセキュリティグループへルールをコピーする方法を教えてください。 - AWS re:Post](https://repost.aws/ja/knowledge-center/vpc-copy-security-group-rules)
Vue3でemitsを使う。但し、TypeScriptじゃなくてJavaScriptで。

# 目的と背景
久しぶりにVue3でフロントエンド開発をした時にemitってどうやって使うんだっけ？と調べたところ、TypeScriptで書かれた記事ばっかりだったので、JavaScriptベースだとこうだよというのを残しておこうと思った

# そもそもemitってなに?
子コンポーネントから親コンポーネントの操作を実行するための仕組み。
例えば、親コンポーネントが持っている変数を子コンポーネント内で変更するような時に使う。

# store使えばよくない？
piniaなどのstoreを使えばコンポーネントの階層に関係なく状態を参照/更新できるので、emit使わなくてもよいが、個人的には単に親コンポーネントが参照し、単一の子コンポーネントが更新をするような時はstoreでやるほどではないなという感覚。

単一の子コンポーネントが更新を担当し、親コンポーネントが別の子コンポーネントにその状態を渡すような場面ではstoreのがいいかなと思う。

# 本題
今回はファイルの表示画面でリスト表示とギャラリー表示どちらの状態にあるかを表す「type」を子コンポーネント上の要素のクリックによって切り替える場面を考える。

まず、親コンポーネントで参照する変数とメソッドを定義して、子コンポーネントに渡す
```vue
<template>
<ChileComponent @changeType="changeType"/>
{{ type }}
</template>
<script setup>
const type = ref('list');
const changeType = (newType) =>{
  type.value = newType;
};
</script>
```
子コンポーネントではdefineEmitsして、emitとして使えるように定義をしてからそれを呼び出す
```vue
<template>
  <div>
    <div @click="emits('changeType','list')">リスト</div>
    <div @click="emits('changeType','gallery')">ギャラリー</div>
  </div>
</template>
<script setup>
const emits = defineEmits(['changeType']);
</script>
```

上記で正しく子コンポーネントから親コンポーネントの操作をすることができた。
[Unity]Unity Terrain - HDRP Demo Sceneアセットのエラー

# 概要
Unity公式のHDRP環境のデモシーンアセット「Unity Terrain - HDRP Demo Scene」を触った時発生したエラーについての記事です。

![スクリーンショット 2024-02-22 185716.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/b3a5d9b7-abe3-dc4c-b7ad-04f7a430ac75.png)



# 本文

起動するとすぐエラーが表示されました。

:::note warn
No more space in Reflection Probe Atlas. To solve this issue, increase the size of the Reflection Probe Atlas in the HDRP settings.
:::

![スクリーンショット 2024-02-22 185957.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/1e82068a-5b21-78a7-33fe-5c474dc4ed6c.png)

①メニューからEdit > ProjectSettings
②Quality > HDRP > Lighting > Reflection 2D Atlas Sizeのサイズ設定を大きくします（今回は8192×4096にしたらエラーは出なくなりました）

![スクリーンショット 2024-02-22 190433.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/1254d615-7397-54d3-941c-f24ab9753ebd.png)
【超ざっくり】Terraform用にサービスプリンシパルを作成してみた

# はじめに
TerraformでAzure上のリソースを作成するために必要な**サービスプリンシパル**を作成する手順について、初学者なりに**超ざっくり**まとめてみました。
TerraformでAzure上のリソースを作成するための大まかな手順は下記記事をご覧ください。

https://qiita.com/Katsuya_T/items/4f2adb369562419da8b0

# 目次
- [1. サービスプリンシパルの作成](#サービスプリンシパルの作成)
- [2. ロール付与](#ロール付与)
- [3. 各資格情報の確認](#各資格情報の確認)

# サービスプリンシパルの作成
Azureポータル上でサービスプリンシパルを作成します。
ここでは「TerraformUser」という名前で作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715340/9b88cd49-b7b1-cce8-bcfc-ea9e5933f704.png)

次にクライアントシークレットを作成します。
ここでは「TerraformUser_ClientSecret」という説明で作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715340/85871be6-4ce7-7005-335c-1fb256582cbe.png)

# ロール付与
次にサービスプリンシパルに対してAzureロールを付与します。
ここでは「サブスクリプション」単位で「共同作成者」を付与します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715340/20e0d4bb-9b6e-b955-738a-2bf07e150aef.png)

# 各資格情報の確認
続いてTerraformを利用するための資格情報を確認していきます。
必要な資格情報は以下の通りです。
 - サブスクリプションID
 - テナントID（ディレクトリID）
 - クライアントID（アプリケーションID）
 - クライアントシークレット

ここではテナントID、クライアントID、クライアントシークレットを確認します。
※サブスクリプションIDは省略しました。すみません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715340/858cae02-63d1-4880-bf9e-f893513b8963.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715340/8ad4e0ab-7a76-de3a-fd04-779980600943.png)

# おわりに
Terraformを利用するためのAzure上の事前準備が完了しました！
次の記事（下記リンク）ではTerraformで実際にAzureリソースを作成していきます。

https://qiita.com/Katsuya_T/items/be62705a05fb3c39ae9f