TECH PLAY

電通総研

電通総研 の技術ブログ

822

電通国際情報サービス 、オープン イノベーション ラボの 比嘉康雄 です。 Web3開発入門シリーズ with Algorand(アルゴランド)、今回のテーマは、 アセットの作成 です。 今回の記事のGoogle Colab用のノートブックはこちらになります。ブラウザだけでブロックチェーンにアクセスするコードを、実際に動かしながら試せるので、おすすめです。 Ethereum などの ブロックチェーン では、貨幣的な価値を持つ トーク ンである Fungible Token (FT)や代替不可能な トーク ンである Non Fungible Token (NFT)が存在します。 Algorand では、 FT と NFT を統合したものをアセットと呼んでいます。 もう一つ理解しておきたいことは、 Algorand のアセットは、 Ethereum のようにスマート コントラ クトではないということです。 アセットに対する基本的な操作は、 Algoland の機能として実装されているので、個別のアセットで実装する必要がないのです。 もちろん、アセット固有のロジックがある場合は、スマート コントラ クトで個別に実装することもできます。 Web3開発入門 with Algorandの全てのコンテンツ アカウント TestNetでALGOをゲット 支払い アセットの作成 py-algorand-sdkのインストール アカウントの作成 アカウントにAlgorand Dispenserを使って入金する AlgodClientオブジェクトの作成 AssetConfigTxnオブジェクトの作成 署名 トランザクションをAlgorandに送る トランザクションが確定するのを待つ アセットの確認 仲間募集 これから、アセットを作成します。 py-algorand- sdk のインストール py-algorand-sdk をインストールします。 下記のコードを実行してください。 !pip3 install py-algorand-sdk アカウントの作成 アセットを作成するアカウントを作成しましょう。 下記のコードを実行してください。 from algosdk import account private_key, address = account.generate_account() print("Account Address:", address) 出力結果の例です。 Account Address: H7BCYZGX4J6QKXEG5TYMMVQVSTRHWL4WWQQVBGH725HHIYL2R72RDSMNN4 アカウントにAlgorand Dispenserを使って入金する アセットを作成するためには、 トランザクション 手数料を払う必要があります。 TestNet では、 Algorand Dispenser のサイトで、 ALGO を無料でゲットできます。 Account Address: の後ろの部分のアドレスをコピーしてください。 Algorand Dispenser のサイトにアクセスし、 I'm not a roboot をチェックし、 target address の入力エリアに先ほどコピーしたアドレスをペーストします。 Dispense のボタンをクリックしてください。 Status: Code 200 success のように表示されればOKです。 AlgodClientオブジェクトの作成 Algorand にアクセスするために、 AlgodClient オブジェクトを作成します。 下記のコードを実行してください。 from algosdk.v2client.algod import AlgodClient algod = AlgodClient("", "https://node.testnet.algoexplorerapi.io:443") AlgodClient オブジェクトを作成するときに、 https://node.testnet.algoexplorerapi.io:443 を指定しています。これにより Algoexplorer の TestNet のノードに接続します。 AssetConfigTxnオブジェクトの作成 アセットを作成するためには、 AssetConfigTxn オブジェクトを作成します。 AssetConfigTxn オブジェクトを作成するときのパラメータを説明します。 asset_name は、アセットの名前です。32バイト以内である必要があります。 unit_name は、アセットの単位名です。8バイト以内である必要があります。 total は、どれだけアセットを作成するか指定します。例えば、 1000000 を指定した場合、百万個のアセットを作成することになります。 decimals は小数点以下の桁数です。例えば、3を指定した場合、このアセットの最小の単位は、 0.001 になります。 ややこしいのは、 total が decimals の影響を受けることです。 total が 1000000 で decimals が3の場合、市場に流通するアセットは 1000.000 になります。 decimals が3の場合、アセットの最小単位は、 0.001 なので、それが total で 1000000 個、市場に出回るので、市場で流通するアセットの量は、 0.001 x 1000000 で 1000.000 になるということです。 default_frozen について説明する前に、アセットの凍結(frozen)について説明します。 アカウントAがアセットZを2つ作成し、一つをアカウントBに、もう一つをアカウントCに売ったとします。その後、アカウントBが良くない行動をとっていることが判明したため、アカウントBのアセットZを凍結します。 凍結されたアセットZは、売ることができなくなります。 アセットの凍結はアカウント単位です。アカウントBのアセットZは凍結されているので、売ることはできませんが、アカウントCのアセットZは自由に売ることができます。 default_frozen に True を指定すると、凍結された状態でアセットが作成されます。 manager には、作ったアセットを修正したり、削除したりすることができるアドレスを指定します。 reserve は、ほとんど使われていないので、気にしなくても大丈夫です。 frozen には、作ったアセットを凍結することのできるアドレスを指定します。 clawback には、作ったアセットを自由に移動(Transfer)させることのできるアドレスを指定します。 この clawback は非常に強力で、アカウントAがアカウントCにアセットを売ったあと、アカウントCが持っているアセットを強制的にアカウントAのものにすることもできます。 さらに、強力なことに、凍結されたアセットも自由に動かすことができます。 ただし、 clawback は悪いことをするために用意されているわけではなく、スマート コントラ クトの address を指定することがよく行われます。 特定の条件を満たしたときだけ、スマート コントラ クトがアセットを移動できるようにするためです。 それでは、 AssetConfigTxn オブジェクトを作成しましょう。 下記のコードを実行してください。 from algosdk.future.transaction import AssetConfigTxn sp = algod.suggested_params() txn = AssetConfigTxn( sender=address, sp=sp, asset_name="Test", unit_name="Test", total=1000, decimals=0, default_frozen=False, manager=address, reserve=address, freeze=address, clawback=address, ) 署名 トランザクション は、差出人の秘密キーで署名をする必要があります。 下記のコードを実行してください。 signed_txn = txn.sign(private_key) トランザクション をAlgorandに送る 署名した トランザクション を Algorand に送り出しましょう それを行うのが、 AlgodClientオブジェクト.send_transactions() になります。 下記のコードを実行してください。 tx_id = algod.send_transactions([signed_txn]) print('Transaction ID:', tx_id) トランザクション が確定するのを待つ トランザクション を Algoland に送っても、それで トランザクション が確定されたわけではありません。 トランザクション が確定されるのを待つ必要があります。 トランザクション が確定されるのを待つには、 wait_for_confirmation() を呼び出します。 下記のコードを実行してください。 from algosdk.future.transaction import wait_for_confirmation wait_for_confirmation(algod, tx_id, 10) アセットの確認 Algoexplorer でアセットを確認してみましょう。 アカウントのアドレスをコピーしてください。 TestNetのAlgoexplorer のサイトにアクセスし、一番上の真ん中の検索エリアにコピーして実行してください。 真ん中の方に Transactions と Assets のタブがあるので、 Assets のタブをクリックします。 先ほど作成したアセットの Balance が 1000 になってますね。 なにか感想があれば、 Twitter で@yasuo_algoにメンションしてつぶやいてください。 仲間募集 私たちは同じグループで共に働いていただける仲間を募集しています。 現在、以下のような職種を募集しています。 ソリューションアーキテクト AIエンジニア 執筆: @higa 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
アバター
X イノベーション 本部 オープン イノベーション ラボの飯田です。 ISIDでは、有志で論文輪読会を実施しています。 tech.isid.co.jp 最近、Stable Diffusionなどの画像生成系がかなり盛り上がっていますよね。 AI画像生成によって出力された顔画像に対して、我々はどのような印象評定をしているのでしょうか? 今回は、AI(GAN:StyleGAN2)によって生成された顔画像に対する 印象評定を行った 社会心理学 の論文を紹介したいと思います。 Nightingale, S. J., & Farid, H. (2022). AI-synthesized faces are indistinguishable from real faces and more trustworthy. Proceedings of the National Academy of Sciences, 119(8), e2120481119. 論文サマリ 背景 実験1 実験2 実験3 考察 最後に 論文サマリ AI(StyleGAN2)で生成された顔画像は、 不気味の谷 を乗り越え、本物の顔と見分けがつかない それだけでなく、実物よりも信頼を得る顔を作成できるようになっていた 背景 AI画像生成技術には、詐欺やリベンジポルノで利用されてしまうなどの脅威があると言われています。 どんな画像や動画も偽造できてしまうことにより、 デジタルメディア記録の信憑性が疑われてしまうことも懸念されます。 フェイク画像の検出技術開発も進んでいますが、現状の技術では不十分であり、 コンテンツの消費者自身で本物と偽物を見分けなければなりません。 この研究では、GAN(StyleGAN2)によって生成された顔と本物の顔を区別できるか? また、その顔がどの程度の信頼を得るか?を研究しました。 実験1 128枚の顔画像を本物か生成画像かを判定する課題を315人に実施。 結果は、平均精度は48.2%であり、チャンスレベルの50%と同等でした(下図、上のグラフ:青)。 →つまり、見分けができていないと示唆された 実験2 試行ごとに正解・不正解のフィードバックを受けながら(=見分ける学習をしながら)、 128枚の顔画像を本物か生成画像かを判定する課題を219人に実施。 結果は試行ごとのフィードバックを行ったが、時間の経過とともに精度の向上は見られなかった。 フィードバックを与えることで、精度が向上したが、精度はチャンスレベルを少し上回る程度(下図、上のグラフ:赤)。 →つまり、見分ける練習をしても、本物か生成画像かの弁別は難易度が高い 実験3 生成された顔画像から、その人が信頼できるか?を評価してもらう課題を実施。 128人の顔画像の信頼度を7件法で評価 (1:非常に信頼できない←→7:非常に信頼できる) 結果、生成された顔画像の方が本物に比べて7.7%、有意に信頼度が高い。 本物(下図、下のグラフ:青)の平均:4.48 AI生成(下図、下のグラフ:オレンジ)の平均:4.82 →つまり、本物よりもAI生成画像の方がより信頼できる 考察 AI画像生成は、本物と見分けがつかず、 不気味の谷 を超えたと思われます。 さらに、AI画像生成の方が、より”信頼できる”と感じる人が多い結果となりました。 AI画像生成の信頼性が高かった理由としては、以下のことが考えられます。 ヒトは平均的な顔のほうが、より魅力的・信頼できると言われています。 GANは学習・生成の過程で、教師データの平均的な顔に似ていく傾向があるため、 より魅力的・信頼できると感じられることが多くなったのではないかと思われます。 不気味の谷 を超えて、本物・偽物の判別がつかず、 より信頼されるような顔画像が生成可能になりました。 それは、高品質なフェイク画像を作成できることになったことを意味します。 詐欺、情報操作など、個人・社会に影響を与える可能性があります。 今後、AI開発においての倫理が必要となったり、 生成系メディアでの ガイドライン が必要となってきたり来る可能性があります。 最後に 今回は、GANで生成された顔画像の印象評価の論文について紹介しました。 Stable Diffusionが話題になっているように、今後生成系のクオリティはどんどん上がっていくかと思います。 現状でも、人間は本物か偽物かを区別できず、信頼性を高く感じるという報告がありました。 技術の進歩だけでなく、AIを使う側、作る側、それぞれでAI倫理が大切になってくるかと思います。 私たちは同じグループで共に働いていただける仲間を募集しています。 現在、以下のような職種を募集しています。 ソリューションアーキテクト AIエンジニア 論文輪読会をはじめとした各種勉強会に気軽に参加できるような環境で働くことに興味のある皆様、ぜひご応募お待ちしています! 執筆: @iida.michitaka 、レビュー: @higa ( Shodo で執筆されました )
アバター
X イノベーション 本部 オープン イノベーション ラボの飯田です。 ISIDでは、有志で論文輪読会を実施しています。 tech.isid.co.jp 最近、Stable Diffusionなどの画像生成系がかなり盛り上がっていますよね。 AI画像生成によって出力された顔画像に対して、我々はどのような印象評定をしているのでしょうか? 今回は、AI(GAN:StyleGAN2)によって生成された顔画像に対する 印象評定を行った 社会心理学 の論文を紹介したいと思います。 Nightingale, S. J., & Farid, H. (2022). AI-synthesized faces are indistinguishable from real faces and more trustworthy. Proceedings of the National Academy of Sciences, 119(8), e2120481119. 論文サマリ 背景 実験1 実験2 実験3 考察 最後に 論文サマリ AI(StyleGAN2)で生成された顔画像は、 不気味の谷 を乗り越え、本物の顔と見分けがつかない それだけでなく、実物よりも信頼を得る顔を作成できるようになっていた 背景 AI画像生成技術には、詐欺やリベンジポルノで利用されてしまうなどの脅威があると言われています。 どんな画像や動画も偽造できてしまうことにより、 デジタルメディア記録の信憑性が疑われてしまうことも懸念されます。 フェイク画像の検出技術開発も進んでいますが、現状の技術では不十分であり、 コンテンツの消費者自身で本物と偽物を見分けなければなりません。 この研究では、GAN(StyleGAN2)によって生成された顔と本物の顔を区別できるか? また、その顔がどの程度の信頼を得るか?を研究しました。 実験1 128枚の顔画像を本物か生成画像かを判定する課題を315人に実施。 結果は、平均精度は48.2%であり、チャンスレベルの50%と同等でした(下図、上のグラフ:青)。 →つまり、見分けができていないと示唆された 実験2 試行ごとに正解・不正解のフィードバックを受けながら(=見分ける学習をしながら)、 128枚の顔画像を本物か生成画像かを判定する課題を219人に実施。 結果は試行ごとのフィードバックを行ったが、時間の経過とともに精度の向上は見られなかった。 フィードバックを与えることで、精度が向上したが、精度はチャンスレベルを少し上回る程度(下図、上のグラフ:赤)。 →つまり、見分ける練習をしても、本物か生成画像かの弁別は難易度が高い 実験3 生成された顔画像から、その人が信頼できるか?を評価してもらう課題を実施。 128人の顔画像の信頼度を7件法で評価 (1:非常に信頼できない←→7:非常に信頼できる) 結果、生成された顔画像の方が本物に比べて7.7%、有意に信頼度が高い。 本物(下図、下のグラフ:青)の平均:4.48 AI生成(下図、下のグラフ:オレンジ)の平均:4.82 →つまり、本物よりもAI生成画像の方がより信頼できる 考察 AI画像生成は、本物と見分けがつかず、 不気味の谷 を超えたと思われます。 さらに、AI画像生成の方が、より”信頼できる”と感じる人が多い結果となりました。 AI画像生成の信頼性が高かった理由としては、以下のことが考えられます。 ヒトは平均的な顔のほうが、より魅力的・信頼できると言われています。 GANは学習・生成の過程で、教師データの平均的な顔に似ていく傾向があるため、 より魅力的・信頼できると感じられることが多くなったのではないかと思われます。 不気味の谷 を超えて、本物・偽物の判別がつかず、 より信頼されるような顔画像が生成可能になりました。 それは、高品質なフェイク画像を作成できることになったことを意味します。 詐欺、情報操作など、個人・社会に影響を与える可能性があります。 今後、AI開発においての倫理が必要となったり、 生成系メディアでの ガイドライン が必要となってきたり来る可能性があります。 最後に 今回は、GANで生成された顔画像の印象評価の論文について紹介しました。 Stable Diffusionが話題になっているように、今後生成系のクオリティはどんどん上がっていくかと思います。 現状でも、人間は本物か偽物かを区別できず、信頼性を高く感じるという報告がありました。 技術の進歩だけでなく、AIを使う側、作る側、それぞれでAI倫理が大切になってくるかと思います。 私たちは同じグループで共に働いていただける仲間を募集しています。 現在、以下のような職種を募集しています。 ソリューションアーキテクト AIエンジニア 論文輪読会をはじめとした各種勉強会に気軽に参加できるような環境で働くことに興味のある皆様、ぜひご応募お待ちしています! 執筆: @iida.michitaka 、レビュー: @higa ( Shodo で執筆されました )
アバター
ISIDテックブログ編集部です。今回は弊社社員が登壇するイベントを紹介します。詳細およびお申込みはリンク先サイトを参照してください。 techplay.jp ご興味あれば、ぜひ登録おねがいします。 基本情報 タイトル:Azureではじめるマルチテナント SaaS のつくり方 -変化に強い アーキテクチャ 設計・実装のコツ- 日時:2022/11/22(火) 19:00〜20:30 形態:オンライン開催 概要 変化の時代である今、DXに求められるスピーディな対応を実現するためには SaaS の活用が必要不可欠です。 では、 SaaS 開発において、変化に柔軟に対応できる アーキテクチャ の設計・実装のポイントは何でしょう? 今回はISIDが今年4月に製品版をリリースした従業員コラボレーション SaaS 『ENGAGE TAG』を題材に 「マルチテナント SaaS の開発」についてお話ししながら、そのポイントを紐解きます。 『ENGAGE TAG』は社内の新規事業創出プログラムから生まれました。 現在 PMF (Product Market Fit)を目指し、顧客のフィードバックを元に日々改善を続けています。 PMF に至るまでには事業のピボットや顧客のフィードバックへの迅速な対応など、様々な変化に直面します。 【例①】プロダクトのKPIを「チャットする」から「プロフィールを見る」ことに変更し、新機能を追加開発する 【例②】プロフィールにタグだけでなく、画像やリンクも掲載したい 【例③】新卒や中途入社した人、最近タグをつけた人など、全社で発信してほしい など、様々な変化に対して柔軟に対応すべく、 Microsoft AzureのPaaSとAzure DevOpsを最大限に活用した開発を行っています。 本イベントでは、 「第1部:Azure PaaSの概要と最新トレンド」と「第2部:マルチテナント SaaS 開発の ケーススタディ 」 の2部構成でお届けします。 第1部では、 Microsoft 佐藤氏より、 「AzureのPaaS機能の活用方法」「最新トレンド」「ベストプ ラク ティス」について マルチテナント SaaS 開発という文脈を踏まえつつお話します。 第2部では『ENGAGE TAG』の開発責任者のISID通山氏より、 クラウド で設計/実装する際に重要なポイントとなる 「信頼性」「セキュリティ」「コストの最適化」「オペレーショナル エクセレンス 」「パフォーマンス効率」の視点から「ENGAGE TAG」でどのようにして変化に強いマルチテナント SaaS を設計/実装したのかをお話します。 執筆: Ishizawa Kento (@kent) 、レビュー: @nakamura.toshihiro ( Shodo で執筆されました )
アバター
ISIDテックブログ編集部です。今回は弊社社員が登壇するイベントを紹介します。詳細およびお申込みはリンク先サイトを参照してください。 techplay.jp ご興味あれば、ぜひ登録おねがいします。 基本情報 タイトル:Azureではじめるマルチテナント SaaS のつくり方 -変化に強い アーキテクチャ 設計・実装のコツ- 日時:2022/11/22(火) 19:00〜20:30 形態:オンライン開催 概要 変化の時代である今、DXに求められるスピーディな対応を実現するためには SaaS の活用が必要不可欠です。 では、 SaaS 開発において、変化に柔軟に対応できる アーキテクチャ の設計・実装のポイントは何でしょう? 今回はISIDが今年4月に製品版をリリースした従業員コラボレーション SaaS 『ENGAGE TAG』を題材に 「マルチテナント SaaS の開発」についてお話ししながら、そのポイントを紐解きます。 『ENGAGE TAG』は社内の新規事業創出プログラムから生まれました。 現在 PMF (Product Market Fit)を目指し、顧客のフィードバックを元に日々改善を続けています。 PMF に至るまでには事業のピボットや顧客のフィードバックへの迅速な対応など、様々な変化に直面します。 【例①】プロダクトのKPIを「チャットする」から「プロフィールを見る」ことに変更し、新機能を追加開発する 【例②】プロフィールにタグだけでなく、画像やリンクも掲載したい 【例③】新卒や中途入社した人、最近タグをつけた人など、全社で発信してほしい など、様々な変化に対して柔軟に対応すべく、 Microsoft AzureのPaaSとAzure DevOpsを最大限に活用した開発を行っています。 本イベントでは、 「第1部:Azure PaaSの概要と最新トレンド」と「第2部:マルチテナント SaaS 開発の ケーススタディ 」 の2部構成でお届けします。 第1部では、 Microsoft 佐藤氏より、 「AzureのPaaS機能の活用方法」「最新トレンド」「ベストプ ラク ティス」について マルチテナント SaaS 開発という文脈を踏まえつつお話します。 第2部では『ENGAGE TAG』の開発責任者のISID通山氏より、 クラウド で設計/実装する際に重要なポイントとなる 「信頼性」「セキュリティ」「コストの最適化」「オペレーショナル エクセレンス 」「パフォーマンス効率」の視点から「ENGAGE TAG」でどのようにして変化に強いマルチテナント SaaS を設計/実装したのかをお話します。 執筆: Ishizawa Kento (@kent) 、レビュー: @nakamura.toshihiro ( Shodo で執筆されました )
アバター
電通国際情報サービス 、オープン イノベーション ラボの 比嘉康雄 です。 Web3開発入門シリーズ with Algorand(アルゴランド)、今回のテーマは、 支払い です。 今回の記事のGoogle Colab用のノートブックはこちらになります。ブラウザだけでブロックチェーンに対するコードを、実際に動かしながら試せるので、おすすめです。 Web3開発入門 with Algorandの全てのコンテンツ アカウント TestNetでALGOをゲット 支払い アセットの作成 py-algorand-sdkのインストール アカウントAの作成 アカウントAにAlgorand Dispenserを使って入金する アカウントBの作成 ALGO残高の確認 AlgodClientオブジェクトの作成 PaymentTxnオブジェクトの作成 署名 トランザクションをAlgorandに送る トランザクションが確定するのを待つ ALGO残高の再確認 まとめ 仲間募集 今回は、アカウントAからアカウントBに 1 ALGO を支払う支払い トランザクション を実行してみましょう。 py-algorand- sdk のインストール py-algorand-sdk をインストールします。 下記のコードを実行してください。 !pip3 install py-algorand-sdk アカウントAの作成 アカウントAを作成しましょう。 下記のコードを実行してください。 from algosdk import account a_private_key, a_address = account.generate_account() print("AccountA Address:", a_address) 出力結果の例です AccountA Address: QLK6LJT2CWOV5XIILG5XRSM6QLOMLYG77YLE3F5EFIQU37BY3WKL2HPYEM アカウントAにAlgorand Dispenserを使って入金する アカウントAがアカウントBに送金するためには、 ALGO の残高がなければいけません。 TestNet では、 Algorand Dispenser のサイトで、 ALGO を無料でゲットできます。 AccountA Address: の後ろの部分のアドレスをコピーしてください。 Algorand Dispenser のサイトにアクセスし、 I'm not a roboot をチェックし、 target address の入力エリアに先ほどコピーしたアドレスをペーストします。 Dispense のボタンをクリックしてください。 Status: Code 200 success のように表示されればOKです。 アカウントBの作成 アカウントBを作成しましょう。 下記のコードを実行してください。 from algosdk import account b_private_key, b_address = account.generate_account() print("AccountB Address:", b_address) 出力結果の例です。 AccountB Address: JO7RPRV36UVWWEAUA5JMXTPX62REHXFY5EYGNX3RBCSCITOO76PZCI2Y6E ALGO残高の確認 アカウントAとアカウントBの残高を確認してみましょう。 TestNetのAlgoexplorer のサイトにアクセスし、一番上の真ん中の検索エリアに、アカウントAのアドレスをコピー&ペーストして実行してください。 Balances(残高)に 10 と表示されていますね。 アカウントBの残高も同様に確認してみましょう。一度、ブラウザでページをリロードし、アカウントBのアドレスをコピー&ペーストして実行してください。ページをリロードしないとたまに変になることがあります。 Balances(残高)は - つまり 0 ですね。 AlgodClientオブジェクトの作成 Algorand にアクセスするために、 AlgodClient オブジェクトを作成します。 下記のコードを実行してください。 from algosdk.v2client.algod import AlgodClient algod = AlgodClient("", "https://node.testnet.algoexplorerapi.io:443") AlgodClient オブジェクトを作成するときに、 https://node.testnet.algoexplorerapi.io:443 を指定していますね。これにより Algoexplorer の TestNet のノードに接続します。 PaymentTxnオブジェクトの作成 あるアカウントが別のアカウントへALGOを支払うためには、 PaymentTxn オブジェクトを作成します。 下記のコードを実行してください。 from algosdk.future.transaction import PaymentTxn sp = algod.suggested_params() txn = PaymentTxn(sender=a_address, sp=sp, receiver=b_address, amt=1000000) この トランザクション の差出人(sender)はアカウントA(a_address)です。 この トランザクション の受取人(receiver)はアカウントB(b_address)です。 金額(amt)は、1000000 micro ALGO = 1.0 ALGOになります。 spは気にしなくても大丈夫です。 署名 トランザクション は、確かに差出人はアカウントAであるということと、 トランザクション が作成されてから変更されていないことを検証するために、そのアカウントの秘密キーで署名をする必要があります。 下記のコードを実行してください。 signed_txn = txn.sign(a_private_key) アカウントAの秘密キー(a_private_key)で署名( sign )していますね。 トランザクション をAlgorandに送る 署名した トランザクション を Algorand に送り出しましょう それを行うのが、 AlgodClientオブジェクト.send_transactions() になります。 下記のコードを実行してください。 tx_id = algod.send_transactions([signed_txn]) トランザクション を Algorand に送ると トランザクション ID(tx_id)がふられ、 Algoexplorer などで検索可能になります。正確には、次で説明する トランザクション の確定後、検索可能になります。 トランザクション が確定するのを待つ トランザクション を Algoland に送っても、それで トランザクション が確定されたわけではありません。 トランザクション がブロックに取り込まれるのを待つ必要があります。 Algorand の場合、 トランザクションがブロックに取り込まれた == トランザクションが確定された という意味になります。 Algorand の場合、3.8秒ほどで トランザクション が確定します。 トランザクション が確定されるのを待つには、 wait_for_confirmation() を呼び出します。 下記のコードを実行してください。 from algosdk.future.transaction import wait_for_confirmation wait_for_confirmation(algod, tx_id, 10) 3つ目の引数の10は、どれくらいのラウンドを待つのかの指定になります。ここで指定されたラウンドで トランザクション が確定しない場合、 wait_for_confirmation() の呼び出しから処理が返ってきます。 Algorand に何らかの問題があったときに、無限に待ち続けないためのパラメータです。 ラウンドとは、一つのブロックが作成される時間帯です。前のブロックが作成されてから、今回のブロックが作成されるまでの時間が一つのラウンドになります。 ALGO残高の再確認 アカウントAとアカウントBの残高をもう一度確認してみましょう。 TestNetのAlgoexplorer のサイトにアクセスし、一番上の真ん中の検索エリアに、アカウントAのアドレスをコピー&ペーストして実行してください。 Balances(残高)に 8.999 と表示されていますね。 10 の状態から、 1 支払ったので、 9 になりそうですが、 0.001 足りません。 0.001 は トランザクション 手数料として支払った分です。 アカウントBの残高も同様に確認してみましょう。一度、ブラウザでページをリロードし、アカウントBのアドレスをコピー&ペーストして実行してください。ページをリロードしないとたまに変になることがあります。 Balances(残高)は予想通りに 1 と表示されていますね。 まとめ 今回は、 支払い を学びました。 トランザクション を作成した後の、「 トランザクション に署名する」、「署名した トランザクション を Algorand に送り出す」の処理はどの トランザクション でも同じです。 トランザクション 処理の山は今回でこえましたよ。 なにか感想があれば、 Twitter で @yasuo_algo にメンションしてつぶやいてください。 次回は、 アセットの作成 です。 仲間募集 私たちは同じグループで共に働いていただける仲間を募集しています。 現在、以下のような職種を募集しています。 ソリューションアーキテクト AIエンジニア 執筆: @higa 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
アバター
電通国際情報サービス 、オープン イノベーション ラボの 比嘉康雄 です。 Web3開発入門シリーズ with Algorand(アルゴランド)、今回のテーマは、 支払い です。 今回の記事のGoogle Colab用のノートブックはこちらになります。ブラウザだけでブロックチェーンに対するコードを、実際に動かしながら試せるので、おすすめです。 Web3開発入門 with Algorandの全てのコンテンツ アカウント TestNetでALGOをゲット 支払い アセットの作成 py-algorand-sdkのインストール アカウントAの作成 アカウントAにAlgorand Dispenserを使って入金する アカウントBの作成 ALGO残高の確認 AlgodClientオブジェクトの作成 PaymentTxnオブジェクトの作成 署名 トランザクションをAlgorandに送る トランザクションが確定するのを待つ ALGO残高の再確認 まとめ 仲間募集 今回は、アカウントAからアカウントBに 1 ALGO を支払う支払い トランザクション を実行してみましょう。 py-algorand- sdk のインストール py-algorand-sdk をインストールします。 下記のコードを実行してください。 !pip3 install py-algorand-sdk アカウントAの作成 アカウントAを作成しましょう。 下記のコードを実行してください。 from algosdk import account a_private_key, a_address = account.generate_account() print("AccountA Address:", a_address) 出力結果の例です AccountA Address: QLK6LJT2CWOV5XIILG5XRSM6QLOMLYG77YLE3F5EFIQU37BY3WKL2HPYEM アカウントAにAlgorand Dispenserを使って入金する アカウントAがアカウントBに送金するためには、 ALGO の残高がなければいけません。 TestNet では、 Algorand Dispenser のサイトで、 ALGO を無料でゲットできます。 AccountA Address: の後ろの部分のアドレスをコピーしてください。 Algorand Dispenser のサイトにアクセスし、 I'm not a roboot をチェックし、 target address の入力エリアに先ほどコピーしたアドレスをペーストします。 Dispense のボタンをクリックしてください。 Status: Code 200 success のように表示されればOKです。 アカウントBの作成 アカウントBを作成しましょう。 下記のコードを実行してください。 from algosdk import account b_private_key, b_address = account.generate_account() print("AccountB Address:", b_address) 出力結果の例です。 AccountB Address: JO7RPRV36UVWWEAUA5JMXTPX62REHXFY5EYGNX3RBCSCITOO76PZCI2Y6E ALGO残高の確認 アカウントAとアカウントBの残高を確認してみましょう。 TestNetのAlgoexplorer のサイトにアクセスし、一番上の真ん中の検索エリアに、アカウントAのアドレスをコピー&ペーストして実行してください。 Balances(残高)に 10 と表示されていますね。 アカウントBの残高も同様に確認してみましょう。一度、ブラウザでページをリロードし、アカウントBのアドレスをコピー&ペーストして実行してください。ページをリロードしないとたまに変になることがあります。 Balances(残高)は - つまり 0 ですね。 AlgodClientオブジェクトの作成 Algorand にアクセスするために、 AlgodClient オブジェクトを作成します。 下記のコードを実行してください。 from algosdk.v2client.algod import AlgodClient algod = AlgodClient("", "https://node.testnet.algoexplorerapi.io:443") AlgodClient オブジェクトを作成するときに、 https://node.testnet.algoexplorerapi.io:443 を指定していますね。これにより Algoexplorer の TestNet のノードに接続します。 PaymentTxnオブジェクトの作成 あるアカウントが別のアカウントへALGOを支払うためには、 PaymentTxn オブジェクトを作成します。 下記のコードを実行してください。 from algosdk.future.transaction import PaymentTxn sp = algod.suggested_params() txn = PaymentTxn(sender=a_address, sp=sp, receiver=b_address, amt=1000000) この トランザクション の差出人(sender)はアカウントA(a_address)です。 この トランザクション の受取人(receiver)はアカウントB(b_address)です。 金額(amt)は、1000000 micro ALGO = 1.0 ALGOになります。 spは気にしなくても大丈夫です。 署名 トランザクション は、確かに差出人はアカウントAであるということと、 トランザクション が作成されてから変更されていないことを検証するために、そのアカウントの秘密キーで署名をする必要があります。 下記のコードを実行してください。 signed_txn = txn.sign(a_private_key) アカウントAの秘密キー(a_private_key)で署名( sign )していますね。 トランザクション をAlgorandに送る 署名した トランザクション を Algorand に送り出しましょう それを行うのが、 AlgodClientオブジェクト.send_transactions() になります。 下記のコードを実行してください。 tx_id = algod.send_transactions([signed_txn]) トランザクション を Algorand に送ると トランザクション ID(tx_id)がふられ、 Algoexplorer などで検索可能になります。正確には、次で説明する トランザクション の確定後、検索可能になります。 トランザクション が確定するのを待つ トランザクション を Algoland に送っても、それで トランザクション が確定されたわけではありません。 トランザクション がブロックに取り込まれるのを待つ必要があります。 Algorand の場合、 トランザクションがブロックに取り込まれた == トランザクションが確定された という意味になります。 Algorand の場合、3.8秒ほどで トランザクション が確定します。 トランザクション が確定されるのを待つには、 wait_for_confirmation() を呼び出します。 下記のコードを実行してください。 from algosdk.future.transaction import wait_for_confirmation wait_for_confirmation(algod, tx_id, 10) 3つ目の引数の10は、どれくらいのラウンドを待つのかの指定になります。ここで指定されたラウンドで トランザクション が確定しない場合、 wait_for_confirmation() の呼び出しから処理が返ってきます。 Algorand に何らかの問題があったときに、無限に待ち続けないためのパラメータです。 ラウンドとは、一つのブロックが作成される時間帯です。前のブロックが作成されてから、今回のブロックが作成されるまでの時間が一つのラウンドになります。 ALGO残高の再確認 アカウントAとアカウントBの残高をもう一度確認してみましょう。 TestNetのAlgoexplorer のサイトにアクセスし、一番上の真ん中の検索エリアに、アカウントAのアドレスをコピー&ペーストして実行してください。 Balances(残高)に 8.999 と表示されていますね。 10 の状態から、 1 支払ったので、 9 になりそうですが、 0.001 足りません。 0.001 は トランザクション 手数料として支払った分です。 アカウントBの残高も同様に確認してみましょう。一度、ブラウザでページをリロードし、アカウントBのアドレスをコピー&ペーストして実行してください。ページをリロードしないとたまに変になることがあります。 Balances(残高)は予想通りに 1 と表示されていますね。 まとめ 今回は、 支払い を学びました。 トランザクション を作成した後の、「 トランザクション に署名する」、「署名した トランザクション を Algorand に送り出す」の処理はどの トランザクション でも同じです。 トランザクション 処理の山は今回でこえましたよ。 なにか感想があれば、 Twitter で @yasuo_algo にメンションしてつぶやいてください。 次回は、 アセットの作成 です。 仲間募集 私たちは同じグループで共に働いていただける仲間を募集しています。 現在、以下のような職種を募集しています。 ソリューションアーキテクト AIエンジニア 執筆: @higa 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
アバター
電通国際情報サービス 、X イノベーション 本部デジタルエンゲージメントセンターの堀越です。 Salesforce の開発でも GitHub を使って CI/CD をできるようにしたいのですが、この記事ではそのやり方などについて書きます。 最近の Salesforce の開発では、 Salesforce DX というコンセプトのもと、 CLI を使って Salesforce 上のローコード設定を XML で取得したり反映したりできます。 XML として取り扱えれば、 GitHub などで構成管理したり、環境間の差異がないかの比較をしたりということも可能です。 当然ながらローコードだけでなくApexやVisualforce、Lightning コンポーネント といったプログラムコードも CLI で取り扱うことができます。 ここまでは 個々の開発者で CLI とGitを利用すれば実現できるところです。 が、せっかく GitHub で構成管理するのであれば、Pull Request した際に自動テストやデプロイ可否のチェック(いわゆるCI/CD)もやりたくなりますね。 これを踏まえて、ここでは Salesforce DX の CLI を日ごろから使っている & プロジェクト構成が GitHub 上の リポジトリ に登録されていることを前提に、CI/CDを組み込んでみたいと思います。 CI/CD の実行には、 GitHub 標準装備の GitHub Actions を使いたいと思います。 やりたいことのイメージは次のようなものです。 統合用のブランチにSandboxを対応させて、Pull Request されたときにそのSandboxにデプロイできるかを自動チェックできるようにしたいと思います。 CLIによる Sandbox への接続 秘密鍵とそれとペアになった証明書の用意 Salesforce 側の準備 プロファイルの許可IPアドレス設定 プロファイルに与える権限 GitHub側の準備 セキュリティの考慮で secrets を使う CLIでの接続設定のイメージ CLIでの認証に向けた設定作業 キーペアと証明書の準備 Sandbox側の設定 接続用のプロファイルの準備 接続用のユーザーの準備 接続アプリケーションの準備 GitHubリポジトリ側の設定 Secretsの設定 GitHub Actions ワークフローの作成 GitHub Actions ワークフローの接続検証 CLI認証後の操作 接続時のトラブルシューティングのヒント Salesforce側のID検証履歴を確認 余談 CLI による Sandbox への接続 Salesforce DX の CLI では、まず Sandbox に接続(認証)し、それから取得やデプロイなどの操作を行う必要があります。 CLI による認証にはいくつか方式が提供されていますが、CI/CDで利用可能なのは「JWTベアラー トーク ンフロー」です。 JWTベアラー トーク ンフローでの接続には、以下の準備が必要です。 秘密鍵 とそれとペアになった証明書( 自己署名証明書 でOK)の用意 Salesforce 側の準備 GitHub 側の準備 秘密鍵 とそれとペアになった証明書の用意 opensslで 秘密鍵 と 自己署名証明書 を準備します。 自己署名証明書 は、 Salesforce 側の「接続アプリケーション」設定に登録されることになります。 また、 秘密鍵 は GitHub 側で利用されることになります。 Salesforce 側の準備 Salesforce 側がJWTベアラー トーク ンフローでアクセスを受けるためには、「接続アプリケーション」の設定が必要となります。 「接続アプリケーション」では大きく以下の要素の設定が必要です。 JWTベアラー トーク ンフローを有効化する諸設定 JWT を検証するための証明書のアップロード 接続アプリケーションで利用するプロファイル(または権限セット)とユーザー プロファイルまたは権限セットでSandbox内の操作可否を制御する認可の設定をします。 今回は、CI/CDでの利用のため、デプロイやテストを実行するための権限を与えておく必要があります。 また、そのプロファイルまたは権限セットに属する Salesforce ユーザーで接続することになりますので、そのためのユーザーも用意しておく必要があります。 今回は、セキュリティを考慮し、デプロイやテストを実行するための最小の権限を持った専用ユーザーと専用プロファイルを用意することにしました。 また、このユーザーはブラウザでのログインを行わないものとし、 API 呼出専用のユーザーとして用意しておくことにします。 これらの一連の設定方法は、 Salesforce DXのドキュメントの以下が参照できます。 https://developer.salesforce.com/docs/atlas.ja-jp.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_connected_app.htm プロファイルの許可 IPアドレス 設定 プロファイルには、ログインが許可できるアクセス元 IPアドレス 範囲の指定が可能で、 GitHub からのアクセスを許可するように設定するようにします。 ただ、つぶさに設定するのは数が多くて現実的ではないので広めのレンジにならざるを得ないものと思います。 その分、クレデンシャル情報はしっかりと管理しておく必要があるでしょう。 なお、 GitHub のIPレンジは以下から取得できます。 https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/about-githubs-ip-addresses プロファイルに与える権限 プロファイルで与える権限(システム権限)は、以下になります。 「アプリケーションのカスタマイズ」(Customize Application) 「 メタデータ API 関数を使用した メタデータ の変更」(Modify Metadata Through Metadata API Function) 「 API の有効化」( API Enabled) 「 API 限定ユーザ」( API Only User) 「すべてのデータの編集」(Modify All Data) 必要な権限についての情報は以下を参照しています。 https://developer.salesforce.com/docs/atlas.ja-jp.238.0.api_meta.meta/api_meta/meta_modify_metadata_perm.htm なお、「すべてのデータの編集」は、全てのオブジェクトに対する CRUD 操作を行える権限となります。 デプロイに伴ってApexのテストコードの実行が必要であり、それに伴ってオブジェクトの CRUD 操作が必要となることから、この権限を与えておくのが無難でしょう。 GitHub 側の準備 JWTベアラー トーク ンフローで認証する際には、 CLI コマンドで以下を指定する必要があります。 JWT を署名するための 秘密鍵 のファイル Sandboxへの接続に利用するユーザー名 接続アプリケーションのコンシューマ鍵(OAuthのクライアントID) Salesforce 環境のログインURL 認証のコマンドは以下のようなイメージとなります。 sfdx auth:jwt:grant --instanceurl=https://test.salesforce.com/ --jwtkeyfile 【秘密鍵ファイル名】 --username 【接続ユーザー名】 --clientid 【接続アプリケーションのコンシューマ鍵】 ここで、 https://test.salesforce.com/ はログインURLであり、今回はSandboxを利用するためにこちらのURLとなっています。 もし本番環境に接続したい場合は Salesforce の「私の ドメイン 」で指定したURLを適切に指定する必要があると思われます。 「接続アプリケーションのコンシューマ鍵」は、準備した接続アプリケーション設定から取得します。 また、「接続ユーザー名」も同様に Salesforce 側の準備で作成したものを利用します。 セキュリティの考慮で secrets を使う コンシューマ鍵や 秘密鍵 ファイルなどはクレデンシャル情報なので リポジトリ 内に含めるわけにはいきません。 そこで、 GitHub の secrets に登録しておくものとします。 また 秘密鍵 ファイルはX.509形式ですが、改行が含まれるため、そのまま secrets で扱うことはできません。 そこで、 BASE64 エンコード して secrets に登録しておき、それを実行時に取り出して BASE64 デコード、一時ファイルに書き出して鍵ファイルとするものとします。 今回は secrets を利用しましたが、接続先の Sandbox が増えるようであれば、 Environments 機能を利用するのが良いでしょう。 CLI での接続設定のイメージ この接続設定をまとめると、イメージは次のようになります。 CLI での認証に向けた設定作業 以下、このイメージに沿って設定作業を進めていきます。 キーペアと証明書の準備 最初に、opensslで 秘密鍵 と 自己署名証明書 を準備します。 この手順は比較的よくある手順であり、詳しくは割愛します。 Salesforce DXの公式ドキュメントに沿った手順としては以下が参照可能です。 https://developer.salesforce.com/docs/atlas.ja-jp.238.0.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_key_and_cert.htm また、 GitHub の secrets で 秘密鍵 の内容を保持できるようにするため、 秘密鍵 を BASE64 したものを控えておきます。 以下はそのコマンドイメージです。 UNIX 系の場合: cat server.key | base64 Windows の場合: openssl base64 -A -in server.key -out sever_base64.key Sandbox側の設定 Salesforce の Sandbox に管理者でログインし、一連の設定を実施します。 プロファイルの作成と権限付与、ユーザーの作成はよくある手順ですので、詳細は割愛します。 接続用のプロファイルの準備 「設定」画面にて、「クイック検索」 ボックスに「プロファイル」と入力し、「プロファイル」を選択、設定画面に遷移します。 新しいプロファイルを作り、上述の「プロファイルの設定」で示した権限を与えます。 このプロファイルは、のちに接続アプリケーションに紐づけることになりますので、名前を控えておきます。 (今回は、「sfdx_connect」というプロファイル名を設定することとしました) 仮に他のプロファイルをコピーして作った場合には、アクセス元 IPアドレス の許可レンジが自社 IPアドレス のままなどになっている場合があるでしょう。 今回のアクセス元は GitHub Actions のサーバになるので、その指定の変更を忘れないようにしましょう。 接続用のユーザーの準備 同様に、「クイック検索」 ボックスに「ユーザ」と入力しユーザー設定画面に遷移します。 ユーザーを新規作成し、作ったプロファイルにユーザーを割り当てます。 作ったユーザーは GitHub Actionsでの接続に利用されますので、ユーザー名を控えておきます。 接続アプリケーションの準備 Salesforce DX の認証を実施するため、接続アプリケーションの設定を行います。 この一連の設定方法は、 Salesforce DXのドキュメントの以下を参照します。 https://developer.salesforce.com/docs/atlas.ja-jp.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_connected_app.htm 基本的にはこの設定手順に沿いますが、「JWTベアラー トーク ンフロー」なので「(JWTのみ)」と書いてある項目も設定が必要です。 「設定」画面にて、「クイック検索」 ボックスに「アプリケーションマネージャ」と入力し、「アプリケーションマネージャ」を選択、設定画面に遷移します。 「新規接続アプリケーション」をクリックします。 接続アプリケーションの「基本情報」を入力します。 「接続アプリケーション名」: ここでは「sfdx」などとします。 「 API 参照名」: ここでは「sfdx」などとします。 「取引先責任者 メール」: ここでは、開発チームが利用することになるため、開発者のメールアドレスを設定することでよいでしょう。 上記以外は空欄でOKです 「OAuth 設定の有効化」を選択します。 コールバック URL に「 http://localhost:1717/OauthRedirect 」と入力します。JWTベアラー トーク ンフローでは使われない設定なのですが、必須項目なので設定する必要があります。 「デジタル署名を使用」をチェックします。 「ファイルを選択」をクリックし、用意した証明書ファイルをアップロードします。 次の OAuth 範囲を追加します。 API を使用してユーザデータを管理 ( api ) Web ブラウザを使用してユーザデータを管理 (web) いつでも要求を実行 (refresh_token, offline_ access ) 残りはデフォルトとし、「保存」をクリックします。 作成した接続アプリケーションに対し、 セキュリティポリシー を設定します。 CI/CDで利用する場合には、接続のたびに認証( sfdx auth:jwt:grant コマンド)を行うため、セッション時間などは短くしておいて問題ないという考え方になります。 また、許可するユーザーもユーザー自身が登録するフローは利用できないので、事前に管理者がプロファイルとして許可したユーザーのみがアクセス可能であるように設定します。 作成した接続アプリケーションの画面から、「Manage」をクリックします。 「ポリシーを編集」 をクリックします。 「OAuth ポリシー」セクションの「更新 トーク ンポリシー」項目で「次の時間が経過したら更新 トーク ンを期限切れにする:」をクリックし、90 日以下を入力します。(ここでは1時間) 「セッションポリシー」セクションで「 タイムアウト 値」を 15 分に設定します。 「OAuth ポリシー」セクションで、「許可されているユーザ」に「管理者が承認したユーザは事前承認済み」を選択し、「OK」をクリックします。 「保存」をクリックします。 接続アプリケーションに、作成したプロファイルを関連付けます。 「プロファイルを管理する」をクリックし、接続用に準備したプロファイルを選択します。 続いて、「コンシューマ鍵」を取得します。 これは、 CLI での認証時に指定されるもので、 GitHub の secrets に登録されるものとなります。 作成した接続アプリケーションの画面から、「コンシューマの詳細を管理」をクリックします。 場合によってはID検証が実行されますので、その場合は管理者の認証を行います。 「顧客の詳細」の「コンシューマ鍵」の内容をコピーし、控えておきます。 GitHub リポジトリ 側の設定 GitHub にログインし、 リポジトリ の画面から設定を行います。 Secretsの設定 Salesforce への接続情報を secrets に設定します。 接続する リポジトリ の「Settings」タブを選択します。 左側のメニューの「Security」-「Secrets」-「Actions」を選択します。 「New repository secret」ボタンをクリックし、secrets の登録画面に遷移します。 secrets の登録画面で、以下の3つを登録します。 ORG_USER: Salesforce で作成したユーザーのユーザー名 CLIENT_ID: 接続アプリケーションのコンシューマ鍵 PRIVATE_KEY_BASE64ED: 秘密鍵 を BASE64 したもの GitHub Actions ワークフローの作成 次の GitHub Actions ワークフローを作り、統合用ブランチの .github/workflows ディレクト リに、 deploy-to-sandbox.yml などの名前で作成、プッシュします。 ここでは、統合用ブランチの名前は「integration」としています。 name: salesforce ci on: pull_request: branches: - integration jobs: deploy_to_sandbox: runs-on: ubuntu-latest steps: - name: Check out code uses: actions/checkout@v3 - name: Make temporary directory run: | mkdir ./temp # Install Salesforce CLI - name: Install Salesforce CLI run: | wget https://developer.salesforce.com/media/salesforce-cli/sfdx/channels/stable/sfdx-linux-x64.tar.xz mkdir ./temp/sfdx-cli tar xJf sfdx-linux-x64.tar.xz -C ./temp/sfdx-cli --strip-components 1 echo "./temp/sfdx-cli/bin" >> $GITHUB_PATH - name: Display sfdx version run: sfdx version # Save into private-key - name: Save into private-key run: echo -n ${{ secrets.PRIVATE_KEY_BASE64ED }} | base64 -d > ./temp/server.key # Authenticate to access the sandbox - name: Authenticate to access the sandbox run: sfdx force:auth:jwt:grant --instanceurl=https://test.salesforce.com/ --jwtkeyfile ./temp/server.key --username ${{ secrets.ORG_USER }} --clientid ${{ secrets.CLIENT_ID }} ワークフローの流れとしては以下のようになっています。 Pull Request で GitHub Actions が実行されるようにしています。 チェックアウトののち、 Salesforce DX CLI の最新版を wget で取得して一時 ディレクト リにインストール、パスを通しています。 secrets に登録しておいた 秘密鍵 を BASE64 デコードして一時ファイルに書き出しています。 最後に、これらを使って sfdx force:auth:jwt:grant コマンドで Salesforce に接続/認証しにいきます。 GitHub Actions ワークフローの接続検証 この状態で何か統合用ブランチに対してPull Request すれば、このワークフローが実行されるでしょう。 Actionsタブからワークフローの「 salesforce ci」を見つけ、ワークフローの実行結果を確認します。 「Authenticate to access the sandbox」の部分が、以下のように表示されていれば成功です。 CLI 認証後の操作 認証さえできてしまえば、あとは通常の CLI 操作と変わりません。 デプロイやそのための事前チェックであれば sfdx force:source:deploy コマンドを利用することになるでしょう。 接続時の トラブルシューティング のヒント Salesforce 側のID検証履歴を確認 接続アプリケーションであっても、原理としては Salesforce ユーザーを介して Salesforce にログインすることになります。 このため、 Salesforce 側の「ID検証履歴」を見ることで、ある程度どういう状況であるかを確認できます。 https://help.salesforce.com/s/articleView?id=sf.security_verification_history.htm&type=5 「設定」画面にて、「クイック検索」 ボックスに「検証履歴」と入力し、「ID 検証履歴」を選択、履歴表示画面に遷移します。 CLI で利用するユーザーによるログインもこの履歴にエントリーされます。 もし、この履歴にログがない場合、以下のような状況であると思われます。 接続処理に至る前の GitHub Actions の処理で失敗している その Sandbox には指定のユーザーが存在していない 接続したいSandbox組織とログインURLが合っていない(SandboxなのにログインURLに login. salesforce .com が指定されている、あるいはその逆など) 接続に失敗した状況が履歴に記載されているようであれば、その内容をもとにして対応します。 典型的には以下のような原因が考えられるでしょう。 ユーザーに適切なプロファイルが割り当たっていない プロファイルに設定された権限が不正 アクセス元の IPアドレス で弾かれている 余談 今回は、 Salesforce CLI を wget で取得してインストールしました。 実際には、以下のに ホスティング されている Action を利用することも可能でしょう。 https://github.com/forcedotcom/salesforcedx-actions ただ、(Unofficial)という記述があるので、今回については手動でインストールしています。 実行速度などを考慮するとこちらを使ってみてもいいかもしれません。 執筆: @horikoshi.yuji 、レビュー: @hashizume.hideki ( Shodo で執筆されました )
アバター
電通国際情報サービス 、X イノベーション 本部デジタルエンゲージメントセンターの堀越です。 Salesforce の開発でも GitHub を使って CI/CD をできるようにしたいのですが、この記事ではそのやり方などについて書きます。 最近の Salesforce の開発では、 Salesforce DX というコンセプトのもと、 CLI を使って Salesforce 上のローコード設定を XML で取得したり反映したりできます。 XML として取り扱えれば、 GitHub などで構成管理したり、環境間の差異がないかの比較をしたりということも可能です。 当然ながらローコードだけでなくApexやVisualforce、Lightning コンポーネント といったプログラムコードも CLI で取り扱うことができます。 ここまでは 個々の開発者で CLI とGitを利用すれば実現できるところです。 が、せっかく GitHub で構成管理するのであれば、Pull Request した際に自動テストやデプロイ可否のチェック(いわゆるCI/CD)もやりたくなりますね。 これを踏まえて、ここでは Salesforce DX の CLI を日ごろから使っている & プロジェクト構成が GitHub 上の リポジトリ に登録されていることを前提に、CI/CDを組み込んでみたいと思います。 CI/CD の実行には、 GitHub 標準装備の GitHub Actions を使いたいと思います。 やりたいことのイメージは次のようなものです。 統合用のブランチにSandboxを対応させて、Pull Request されたときにそのSandboxにデプロイできるかを自動チェックできるようにしたいと思います。 CLIによる Sandbox への接続 秘密鍵とそれとペアになった証明書の用意 Salesforce 側の準備 プロファイルの許可IPアドレス設定 プロファイルに与える権限 GitHub側の準備 セキュリティの考慮で secrets を使う CLIでの接続設定のイメージ CLIでの認証に向けた設定作業 キーペアと証明書の準備 Sandbox側の設定 接続用のプロファイルの準備 接続用のユーザーの準備 接続アプリケーションの準備 GitHubリポジトリ側の設定 Secretsの設定 GitHub Actions ワークフローの作成 GitHub Actions ワークフローの接続検証 CLI認証後の操作 接続時のトラブルシューティングのヒント Salesforce側のID検証履歴を確認 余談 CLI による Sandbox への接続 Salesforce DX の CLI では、まず Sandbox に接続(認証)し、それから取得やデプロイなどの操作を行う必要があります。 CLI による認証にはいくつか方式が提供されていますが、CI/CDで利用可能なのは「JWTベアラー トーク ンフロー」です。 JWTベアラー トーク ンフローでの接続には、以下の準備が必要です。 秘密鍵 とそれとペアになった証明書( 自己署名証明書 でOK)の用意 Salesforce 側の準備 GitHub 側の準備 秘密鍵 とそれとペアになった証明書の用意 opensslで 秘密鍵 と 自己署名証明書 を準備します。 自己署名証明書 は、 Salesforce 側の「接続アプリケーション」設定に登録されることになります。 また、 秘密鍵 は GitHub 側で利用されることになります。 Salesforce 側の準備 Salesforce 側がJWTベアラー トーク ンフローでアクセスを受けるためには、「接続アプリケーション」の設定が必要となります。 「接続アプリケーション」では大きく以下の要素の設定が必要です。 JWTベアラー トーク ンフローを有効化する諸設定 JWT を検証するための証明書のアップロード 接続アプリケーションで利用するプロファイル(または権限セット)とユーザー プロファイルまたは権限セットでSandbox内の操作可否を制御する認可の設定をします。 今回は、CI/CDでの利用のため、デプロイやテストを実行するための権限を与えておく必要があります。 また、そのプロファイルまたは権限セットに属する Salesforce ユーザーで接続することになりますので、そのためのユーザーも用意しておく必要があります。 今回は、セキュリティを考慮し、デプロイやテストを実行するための最小の権限を持った専用ユーザーと専用プロファイルを用意することにしました。 また、このユーザーはブラウザでのログインを行わないものとし、 API 呼出専用のユーザーとして用意しておくことにします。 これらの一連の設定方法は、 Salesforce DXのドキュメントの以下が参照できます。 https://developer.salesforce.com/docs/atlas.ja-jp.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_connected_app.htm プロファイルの許可 IPアドレス 設定 プロファイルには、ログインが許可できるアクセス元 IPアドレス 範囲の指定が可能で、 GitHub からのアクセスを許可するように設定するようにします。 ただ、つぶさに設定するのは数が多くて現実的ではないので広めのレンジにならざるを得ないものと思います。 その分、クレデンシャル情報はしっかりと管理しておく必要があるでしょう。 なお、 GitHub のIPレンジは以下から取得できます。 https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/about-githubs-ip-addresses プロファイルに与える権限 プロファイルで与える権限(システム権限)は、以下になります。 「アプリケーションのカスタマイズ」(Customize Application) 「 メタデータ API 関数を使用した メタデータ の変更」(Modify Metadata Through Metadata API Function) 「 API の有効化」( API Enabled) 「 API 限定ユーザ」( API Only User) 「すべてのデータの編集」(Modify All Data) 必要な権限についての情報は以下を参照しています。 https://developer.salesforce.com/docs/atlas.ja-jp.238.0.api_meta.meta/api_meta/meta_modify_metadata_perm.htm なお、「すべてのデータの編集」は、全てのオブジェクトに対する CRUD 操作を行える権限となります。 デプロイに伴ってApexのテストコードの実行が必要であり、それに伴ってオブジェクトの CRUD 操作が必要となることから、この権限を与えておくのが無難でしょう。 GitHub 側の準備 JWTベアラー トーク ンフローで認証する際には、 CLI コマンドで以下を指定する必要があります。 JWT を署名するための 秘密鍵 のファイル Sandboxへの接続に利用するユーザー名 接続アプリケーションのコンシューマ鍵(OAuthのクライアントID) Salesforce 環境のログインURL 認証のコマンドは以下のようなイメージとなります。 sfdx auth:jwt:grant --instanceurl=https://test.salesforce.com/ --jwtkeyfile 【秘密鍵ファイル名】 --username 【接続ユーザー名】 --clientid 【接続アプリケーションのコンシューマ鍵】 ここで、 https://test.salesforce.com/ はログインURLであり、今回はSandboxを利用するためにこちらのURLとなっています。 もし本番環境に接続したい場合は Salesforce の「私の ドメイン 」で指定したURLを適切に指定する必要があると思われます。 「接続アプリケーションのコンシューマ鍵」は、準備した接続アプリケーション設定から取得します。 また、「接続ユーザー名」も同様に Salesforce 側の準備で作成したものを利用します。 セキュリティの考慮で secrets を使う コンシューマ鍵や 秘密鍵 ファイルなどはクレデンシャル情報なので リポジトリ 内に含めるわけにはいきません。 そこで、 GitHub の secrets に登録しておくものとします。 また 秘密鍵 ファイルはX.509形式ですが、改行が含まれるため、そのまま secrets で扱うことはできません。 そこで、 BASE64 エンコード して secrets に登録しておき、それを実行時に取り出して BASE64 デコード、一時ファイルに書き出して鍵ファイルとするものとします。 今回は secrets を利用しましたが、接続先の Sandbox が増えるようであれば、 Environments 機能を利用するのが良いでしょう。 CLI での接続設定のイメージ この接続設定をまとめると、イメージは次のようになります。 CLI での認証に向けた設定作業 以下、このイメージに沿って設定作業を進めていきます。 キーペアと証明書の準備 最初に、opensslで 秘密鍵 と 自己署名証明書 を準備します。 この手順は比較的よくある手順であり、詳しくは割愛します。 Salesforce DXの公式ドキュメントに沿った手順としては以下が参照可能です。 https://developer.salesforce.com/docs/atlas.ja-jp.238.0.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_key_and_cert.htm また、 GitHub の secrets で 秘密鍵 の内容を保持できるようにするため、 秘密鍵 を BASE64 したものを控えておきます。 以下はそのコマンドイメージです。 UNIX 系の場合: cat server.key | base64 Windows の場合: openssl base64 -A -in server.key -out sever_base64.key Sandbox側の設定 Salesforce の Sandbox に管理者でログインし、一連の設定を実施します。 プロファイルの作成と権限付与、ユーザーの作成はよくある手順ですので、詳細は割愛します。 接続用のプロファイルの準備 「設定」画面にて、「クイック検索」 ボックスに「プロファイル」と入力し、「プロファイル」を選択、設定画面に遷移します。 新しいプロファイルを作り、上述の「プロファイルの設定」で示した権限を与えます。 このプロファイルは、のちに接続アプリケーションに紐づけることになりますので、名前を控えておきます。 (今回は、「sfdx_connect」というプロファイル名を設定することとしました) 仮に他のプロファイルをコピーして作った場合には、アクセス元 IPアドレス の許可レンジが自社 IPアドレス のままなどになっている場合があるでしょう。 今回のアクセス元は GitHub Actions のサーバになるので、その指定の変更を忘れないようにしましょう。 接続用のユーザーの準備 同様に、「クイック検索」 ボックスに「ユーザ」と入力しユーザー設定画面に遷移します。 ユーザーを新規作成し、作ったプロファイルにユーザーを割り当てます。 作ったユーザーは GitHub Actionsでの接続に利用されますので、ユーザー名を控えておきます。 接続アプリケーションの準備 Salesforce DX の認証を実施するため、接続アプリケーションの設定を行います。 この一連の設定方法は、 Salesforce DXのドキュメントの以下を参照します。 https://developer.salesforce.com/docs/atlas.ja-jp.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_connected_app.htm 基本的にはこの設定手順に沿いますが、「JWTベアラー トーク ンフロー」なので「(JWTのみ)」と書いてある項目も設定が必要です。 「設定」画面にて、「クイック検索」 ボックスに「アプリケーションマネージャ」と入力し、「アプリケーションマネージャ」を選択、設定画面に遷移します。 「新規接続アプリケーション」をクリックします。 接続アプリケーションの「基本情報」を入力します。 「接続アプリケーション名」: ここでは「sfdx」などとします。 「 API 参照名」: ここでは「sfdx」などとします。 「取引先責任者 メール」: ここでは、開発チームが利用することになるため、開発者のメールアドレスを設定することでよいでしょう。 上記以外は空欄でOKです 「OAuth 設定の有効化」を選択します。 コールバック URL に「 http://localhost:1717/OauthRedirect 」と入力します。JWTベアラー トーク ンフローでは使われない設定なのですが、必須項目なので設定する必要があります。 「デジタル署名を使用」をチェックします。 「ファイルを選択」をクリックし、用意した証明書ファイルをアップロードします。 次の OAuth 範囲を追加します。 API を使用してユーザデータを管理 ( api ) Web ブラウザを使用してユーザデータを管理 (web) いつでも要求を実行 (refresh_token, offline_ access ) 残りはデフォルトとし、「保存」をクリックします。 作成した接続アプリケーションに対し、 セキュリティポリシー を設定します。 CI/CDで利用する場合には、接続のたびに認証( sfdx auth:jwt:grant コマンド)を行うため、セッション時間などは短くしておいて問題ないという考え方になります。 また、許可するユーザーもユーザー自身が登録するフローは利用できないので、事前に管理者がプロファイルとして許可したユーザーのみがアクセス可能であるように設定します。 作成した接続アプリケーションの画面から、「Manage」をクリックします。 「ポリシーを編集」 をクリックします。 「OAuth ポリシー」セクションの「更新 トーク ンポリシー」項目で「次の時間が経過したら更新 トーク ンを期限切れにする:」をクリックし、90 日以下を入力します。(ここでは1時間) 「セッションポリシー」セクションで「 タイムアウト 値」を 15 分に設定します。 「OAuth ポリシー」セクションで、「許可されているユーザ」に「管理者が承認したユーザは事前承認済み」を選択し、「OK」をクリックします。 「保存」をクリックします。 接続アプリケーションに、作成したプロファイルを関連付けます。 「プロファイルを管理する」をクリックし、接続用に準備したプロファイルを選択します。 続いて、「コンシューマ鍵」を取得します。 これは、 CLI での認証時に指定されるもので、 GitHub の secrets に登録されるものとなります。 作成した接続アプリケーションの画面から、「コンシューマの詳細を管理」をクリックします。 場合によってはID検証が実行されますので、その場合は管理者の認証を行います。 「顧客の詳細」の「コンシューマ鍵」の内容をコピーし、控えておきます。 GitHub リポジトリ 側の設定 GitHub にログインし、 リポジトリ の画面から設定を行います。 Secretsの設定 Salesforce への接続情報を secrets に設定します。 接続する リポジトリ の「Settings」タブを選択します。 左側のメニューの「Security」-「Secrets」-「Actions」を選択します。 「New repository secret」ボタンをクリックし、secrets の登録画面に遷移します。 secrets の登録画面で、以下の3つを登録します。 ORG_USER: Salesforce で作成したユーザーのユーザー名 CLIENT_ID: 接続アプリケーションのコンシューマ鍵 PRIVATE_KEY_BASE64ED: 秘密鍵 を BASE64 したもの GitHub Actions ワークフローの作成 次の GitHub Actions ワークフローを作り、統合用ブランチの .github/workflows ディレクト リに、 deploy-to-sandbox.yml などの名前で作成、プッシュします。 ここでは、統合用ブランチの名前は「integration」としています。 name: salesforce ci on: pull_request: branches: - integration jobs: deploy_to_sandbox: runs-on: ubuntu-latest steps: - name: Check out code uses: actions/checkout@v3 - name: Make temporary directory run: | mkdir ./temp # Install Salesforce CLI - name: Install Salesforce CLI run: | wget https://developer.salesforce.com/media/salesforce-cli/sfdx/channels/stable/sfdx-linux-x64.tar.xz mkdir ./temp/sfdx-cli tar xJf sfdx-linux-x64.tar.xz -C ./temp/sfdx-cli --strip-components 1 echo "./temp/sfdx-cli/bin" >> $GITHUB_PATH - name: Display sfdx version run: sfdx version # Save into private-key - name: Save into private-key run: echo -n ${{ secrets.PRIVATE_KEY_BASE64ED }} | base64 -d > ./temp/server.key # Authenticate to access the sandbox - name: Authenticate to access the sandbox run: sfdx force:auth:jwt:grant --instanceurl=https://test.salesforce.com/ --jwtkeyfile ./temp/server.key --username ${{ secrets.ORG_USER }} --clientid ${{ secrets.CLIENT_ID }} ワークフローの流れとしては以下のようになっています。 Pull Request で GitHub Actions が実行されるようにしています。 チェックアウトののち、 Salesforce DX CLI の最新版を wget で取得して一時 ディレクト リにインストール、パスを通しています。 secrets に登録しておいた 秘密鍵 を BASE64 デコードして一時ファイルに書き出しています。 最後に、これらを使って sfdx force:auth:jwt:grant コマンドで Salesforce に接続/認証しにいきます。 GitHub Actions ワークフローの接続検証 この状態で何か統合用ブランチに対してPull Request すれば、このワークフローが実行されるでしょう。 Actionsタブからワークフローの「 salesforce ci」を見つけ、ワークフローの実行結果を確認します。 「Authenticate to access the sandbox」の部分が、以下のように表示されていれば成功です。 CLI 認証後の操作 認証さえできてしまえば、あとは通常の CLI 操作と変わりません。 デプロイやそのための事前チェックであれば sfdx force:source:deploy コマンドを利用することになるでしょう。 接続時の トラブルシューティング のヒント Salesforce 側のID検証履歴を確認 接続アプリケーションであっても、原理としては Salesforce ユーザーを介して Salesforce にログインすることになります。 このため、 Salesforce 側の「ID検証履歴」を見ることで、ある程度どういう状況であるかを確認できます。 https://help.salesforce.com/s/articleView?id=sf.security_verification_history.htm&type=5 「設定」画面にて、「クイック検索」 ボックスに「検証履歴」と入力し、「ID 検証履歴」を選択、履歴表示画面に遷移します。 CLI で利用するユーザーによるログインもこの履歴にエントリーされます。 もし、この履歴にログがない場合、以下のような状況であると思われます。 接続処理に至る前の GitHub Actions の処理で失敗している その Sandbox には指定のユーザーが存在していない 接続したいSandbox組織とログインURLが合っていない(SandboxなのにログインURLに login. salesforce .com が指定されている、あるいはその逆など) 接続に失敗した状況が履歴に記載されているようであれば、その内容をもとにして対応します。 典型的には以下のような原因が考えられるでしょう。 ユーザーに適切なプロファイルが割り当たっていない プロファイルに設定された権限が不正 アクセス元の IPアドレス で弾かれている 余談 今回は、 Salesforce CLI を wget で取得してインストールしました。 実際には、以下のに ホスティング されている Action を利用することも可能でしょう。 https://github.com/forcedotcom/salesforcedx-actions ただ、(Unofficial)という記述があるので、今回については手動でインストールしています。 実行速度などを考慮するとこちらを使ってみてもいいかもしれません。 執筆: @horikoshi.yuji 、レビュー: @hashizume.hideki ( Shodo で執筆されました )
アバター
こんにちは。X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの耿です。 Amazon CloudWatch RUM は Webブラウザ で発生したアプリケーションのエラーやパフォーマンス情報を収集し、モニタリングするための機能です。 ECSのブルーグリーンデプロイメントを利用してWebアプリをデプロイしているのですが、CloudWatch RUMを利用するにあたって本番昇格前のテスト環境からのデータが、分析の際のノイズにならないよう、本番環境からのデータと混ざらないようにしたいと思いました。そこで今回はテスト環境からはCloudWatch RUMにデータを送信せず、本番環境に昇格した時のみデータを送信する方法について書きます。 インフラ構成 CloudWatch RUMの利用開始方法 テスト環境のデータが混ざってしまう 解決方法 CloudFront用TLS証明書の用意 Webアプリで外部からコードスニペットを取得する コードスニペット格納用のS3バケットを作成 S3バケットのアクセス制御 S3バケットにコードスニペットをファイルで追加する CloudFrontディストリビューションの作成 ドメインのルーティング 動きの確認 インフラ構成 以下の構成でアプリケーションが稼働しています。 Webアプリケーションをコンテナとしてビルドし、ECRにイメージをプッシュ ECSサービス(Fargate)として ホスティング ECSのブルーグリーンデプロイメントを利用(詳細は こちらの記事 にて) 本番環境を443ポート、テスト環境を8443ポートとしてALBで異なるターゲットグループにルーティング カスタム ドメイン の TLS 証明書をALBで使用 CloudWatch RUMの利用開始方法 CloudWatch RUMを利用するには、まずマネジメントコンソールからアプリケーションモニターを追加します。 作成すると JavaScript の コードスニペット が表示され、それをアプリケーションに追加するだけでブラウザからデータが収集されるようになります。 テスト環境のデータが混ざってしまう アプリケーションモニターを追加する際にはデータを収集するアプリの ドメイン を指定するので、それ以外の ドメイン から送信されたデータは受け付けてくれません。すなわち localhost などでアプリを実行した場合のデータがアプリケーションモニターに登録されることはありません。 しかしデータ収集元のアプリのポート番号は、記事執筆時点では指定できませんでした。ECSのブルーグリーンデプロイメントでは同一 ドメイン の異なるポート番号で本番環境とテスト環境が存在するため、テスト環境にアクセスしたときのデータもCloudWatch RUMに登録されてしまいます。本番 トラフィック に比べてテスト トラフィック が十分に少なければ気にしなくても良いかもしれませんが、今回は本番環境からのみデータが送信される仕組みを作ってみます。 解決方法 ブルーグリーンデプロイメントの場合、本番環境とテスト環境は同一の構成であり、ルーティングだけが異なります。つまり本番環境にだけCloudWatch RUMの コードスニペット を含めたり、コンテナに渡す 環境変数 によってデータ送信の有効化を制御したりすることはできません。 そこでCloudWatch RUMの コードスニペット を直接アプリに含めるのではなくブラウザで外部から取得するようにし、取得した スクリプト へのブラウザ内アクセスをCORSで制限するようにしました。こうすることで、テスト環境では スクリプト がブラウザで実行されず、データはCloudWatch RUMに送信されません。テスト環境ではブラウザのコンソールにCORSエラーが出ますが、本番環境ではないので問題ないでしょう。 具体的にはイン フラリ ソースとしてS3 バケット を作成してCORSを設定し、そこに コードスニペット をファイルで追加します。これだけでも動くとは思いますが、S3 バケット をパブリックにしたくないため、 バケット 自体は非公開のままでCloudFront経由でコンテンツを配信するようにします。CloudFront ディストリビューション には 独自ドメイン の TLS 証明書を関連付けました。CORSを効かせるために、アプリの ドメイン とはクロス ドメイン になるようにします。 以下では順を追って設定方法を説明します。 CloudFront用 TLS 証明書の用意 TLS 証明書をあらかじめ発行しておきます。今回はアプリ ドメイン my-domain.com の サブドメイン として、 static.my-domain.com を利用するとします。CORSのオリジンは プロトコル 、 ドメイン 、ポートの3点セットで区別されるため、アプリ ドメイン とはクロスオリジンの関係になります。 参考までにCDKの場合のコードサンプルを掲載します。(証明書はCloudFrontで利用するため、us-east-1 リージョンにデプロイします) const hostedZone = route53.PublicHostedZone.fromHostedZoneAttributes ( this , "MyHostedZone" , { hostedZoneId: "<ホストゾーンID>" , zoneName: "my-domain.com" , } ); const cloudfrontCertificate = new certificatemanager.DnsValidatedCertificate ( this , "CloudFrontCertificate" , { domainName: "static.my-domain.com" , hostedZone: hostedZone , validation: certificatemanager.CertificateValidation.fromDns ( hostedZone ), } ); Webアプリで外部から コードスニペット を取得する アプリケーションモニターの コードスニペット を直接コードに含めるのではなく、以下の形で src として読み込んでもらうことを考えます。 < script src = "https://static.my-domain.com/rum.js" ></ script > <script> タグの src で外部からファイルを取得する場合、GETによる単純リク エス トになるため、CORSの プリフライトリクエスト は発生しません。すなわちOPTIONSリク エス トは送信されず、443ポートでも8443ポートでもGETリク エス トでリソースは取得され、実行されます。 そこで crossorigin属性 を利用します。これを指定することによって リクエストモード が cors となり、クロスオリジン環境下ではサイトの Origin が スクリプト を取得する際の Access-Control-Allow-Origin レスポンスヘッダーに含まれない限り、ロードした スクリプト がブラウザで実行されなくなります。(crossorigin属性を付けない場合、 <script> タグのリク エス トモードは no-cors となり、サイトの Origin に関わらずロードした スクリプト がブラウザで実行されます) (参考) https://nhiroki.jp/2021/01/07/crossorigin-attribute 以下のように、Webアプリの <head> タグ内でアプリケーションモニターの コードスニペット を読み込むようにし、crossorigin属性を設定します( rum.js ファイルはのちにS3 バケット を作成したときに追加します)。 < head > < script src = "https://static.my-domain.com/rum.js" crossorigin = "anonymous" ></ script > </ head > またcrossorigin属性を付けることにより、 スクリプト を取得する際のGETリク エス トに Origin ヘッダーが付与されるようになります。これは次に述べるS3 バケット からのレスポンスヘッダーにも影響します。 図にまとめると、crossorigin属性を使用しない場合、本番環境でもテスト環境でも スクリプト が実行されてしまいます。 crossorigin属性を使用する場合は次のようになり、本番環境のみ スクリプト が実行されます。 コードスニペット 格納用のS3 バケット を作成 S3 バケット を作成し、本番環境のみを許可するCORSを設定します。 const myBucket = new s3.Bucket ( this , "MyBucket" , { encryption: s3.BucketEncryption.S3_MANAGED , blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL , objectOwnership: s3.ObjectOwnership.BUCKET_OWNER_ENFORCED , enforceSSL: true , cors: [ { allowedHeaders: [ "*" ] , allowedMethods: [ s3.HttpMethods.GET ] , allowedOrigins: [ "https://my-domain.com" ] , } , ] , } ); この設定をした場合の動きを確認してみました。リク エス トヘッダーに Origin: https://my-domain.com が含まれている場合、以下のレスポンスヘッダーが付与されました。 Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: GET Access-Control-Allow-Origin: https://my-domain.com リク エス トヘッダーが Origin: https://my-domain.com:8443 となっている場合、以上の3つの Access-Control-* レスポンスヘッダーは付与されていませんでした。 S3 バケット のアクセス制御 CORSの設定とは関係ありませんが、CloudFrontの OAC(オリジンアクセスコントロール) を利用し、S3 バケット へのアクセスを次のステップで作成するCloudFront ディストリビューション からのみに制限します。 執筆時点でCDKのL2コンスト ラク トではまだOACがサポートされていないため、以下はOACではなくOAIを利用する場合のコードサンプルです。L2コンスト ラク トでOACがサポートされたらそれを利用するのが良いでしょう。 const oai = new cloudfront.OriginAccessIdentity ( this , "MyOAI" ); myBucket.addToResourcePolicy ( new iam.PolicyStatement ( { effect: iam.Effect.ALLOW , actions: [ "s3:GetObject" ] , principals: [ new iam.CanonicalUserPrincipal ( oai.cloudFrontOriginAccessIdentityS3CanonicalUserId ) ] , resources: [ ` ${ myBucket.bucketArn } /*` ] , } ) ); S3 バケット に コードスニペット をファイルで追加する アプリケーションモニターの コードスニペット のうち、 <script> タグを除外した部分をコピーした JavaScript ファイルを作成します。今回は rum.js というファイル名としてS3 バケット にアップロードします。 CloudFront ディストリビューション の作成 CloudFront ディストリビューション を作成します。ここで重要なのは 3つのポリシー です。 まずはキャッシュポリシーとして、 Origin ヘッダーをキャッシュキーに含めるようにします。すなわちリク エス トの Origin ヘッダーが異なる値の場合は、異なるコンテンツを要求しているとみなし、本番環境とテスト環境での振る舞いを切り替えます。 const cachePolicy = new cloudfront.CachePolicy ( this , "MyCachePolicy" , { defaultTtl: cdk.Duration.days ( 1 ), maxTtl: cdk.Duration.days ( 1 ), minTtl: cdk.Duration.days ( 1 ), headerBehavior: cloudfront.CacheHeaderBehavior.allowList ( "Origin" ), } ); 次にオリジンリク エス トポリシーとして、CloudFrontからオリジンへのリク エス トに Origin ヘッダーを含めて転送するようにします。これにより、S3 バケット で設定したCORSが機能するようになります。 const originRequestPolicy = new cloudfront.OriginRequestPolicy ( this , "MyOriginRequestPolicy" , { headerBehavior: cloudfront.CacheHeaderBehavior.allowList ( "Origin" ), } ); 最後にレスポンスヘッダーポリシーとして、CloudFrontからレスポンスを返すときにCORSヘッダーを含めるようにします。 const responseHeadersPolicy = new cloudfront.ResponseHeadersPolicy ( this , "MyResponseHeadersPolicy" , { corsBehavior: { accessControlAllowCredentials: false , accessControlAllowHeaders: [ "*" ] , accessControlAllowMethods: [ "GET" ] , accessControlAllowOrigins: [ "https://my-domain.com" ] , originOverride: false , } , } ); 以上のポリシーを利用してCloudFront ディストリビューション を作成します。今回の構成ではOPTIONSメソッドは送信されないため、許可するメソッドにOPTIONSは含めていません。 const distribution = new cloudfront.Distribution ( this , "MyDistribution" , { defaultBehavior: { allowedMethods: cloudfront.AllowedMethods.ALLOW_GET_HEAD , cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD , cachePolicy , originRequestPolicy , responseHeadersPolicy , viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS , origin: new cloudfrontOrigins.S3Origin ( myBucket ), } , priceClass: cloudfront.PriceClass.PRICE_CLASS_200 , geoRestriction: cloudfront.GeoRestriction.allowlist ( "JP" ), sslSupportMethod: cloudfront.SSLMethod.SNI , minimumProtocolVersion: cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021 , certificate: cloudfrontCertificate , domainNames: [ "static.my-domain.com" ] , } ); ドメイン のルーティング 作成したCloudFront ディストリビューション に、 static.my-domain.com のルーティングを向けて完了です。 new route53.ARecord ( this , "StaticARecord" , { zone: hostedZone , recordName: "static" , target: route53.RecordTarget.fromAlias (new route53Targets.CloudFrontTarget ( distribution )), } ); 動きの確認 本番環境の https://my-domain.com にアクセスすると、 https://static.my-domain.com/rum.js の取得に成功していることを確認できました。実際にはさらに https://client.rum.us-east-1.amazonaws.com/1.5.x/cwr.js より スクリプト の本体をロードしており、 https://dataplane.rum.ap-notheast-1.amazonaws.com/appmonitors/ にブラウザのクライアントデータを送信していました。マネジメントコンソールのCloudWatch RUMの画面にアクセスすると、データが取得されていることがわかります。 一方、テスト環境の https://my-domain.com:8443 にアクセスすると、 https://static.my-domain.com/rum.js からのレスポンスステータスは200で返りますが、クロスオリジンの読み込みが許可されていないためブラウザは スクリプト にアクセスできず、実行されません。 これでECSのブルーグリーンデプロイメントの本番環境のみ、CloudWatch RUMにデータ送信を実現できました。 私たちは同じチームで働いてくれる仲間を大募集しています!たくさんのご応募をお待ちしています。 - セキュリティエンジニア(セキュリティ設計) 執筆: @kou.kinyo 、レビュー: @yamada.y ( Shodo で執筆されました )
アバター
こんにちは。X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの耿です。 Amazon CloudWatch RUM は Webブラウザ で発生したアプリケーションのエラーやパフォーマンス情報を収集し、モニタリングするための機能です。 ECSのブルーグリーンデプロイメントを利用してWebアプリをデプロイしているのですが、CloudWatch RUMを利用するにあたって本番昇格前のテスト環境からのデータが、分析の際のノイズにならないよう、本番環境からのデータと混ざらないようにしたいと思いました。そこで今回はテスト環境からはCloudWatch RUMにデータを送信せず、本番環境に昇格した時のみデータを送信する方法について書きます。 インフラ構成 CloudWatch RUMの利用開始方法 テスト環境のデータが混ざってしまう 解決方法 CloudFront用TLS証明書の用意 Webアプリで外部からコードスニペットを取得する コードスニペット格納用のS3バケットを作成 S3バケットのアクセス制御 S3バケットにコードスニペットをファイルで追加する CloudFrontディストリビューションの作成 ドメインのルーティング 動きの確認 インフラ構成 以下の構成でアプリケーションが稼働しています。 Webアプリケーションをコンテナとしてビルドし、ECRにイメージをプッシュ ECSサービス(Fargate)として ホスティング ECSのブルーグリーンデプロイメントを利用(詳細は こちらの記事 にて) 本番環境を443ポート、テスト環境を8443ポートとしてALBで異なるターゲットグループにルーティング カスタム ドメイン の TLS 証明書をALBで使用 CloudWatch RUMの利用開始方法 CloudWatch RUMを利用するには、まずマネジメントコンソールからアプリケーションモニターを追加します。 作成すると JavaScript の コードスニペット が表示され、それをアプリケーションに追加するだけでブラウザからデータが収集されるようになります。 テスト環境のデータが混ざってしまう アプリケーションモニターを追加する際にはデータを収集するアプリの ドメイン を指定するので、それ以外の ドメイン から送信されたデータは受け付けてくれません。すなわち localhost などでアプリを実行した場合のデータがアプリケーションモニターに登録されることはありません。 しかしデータ収集元のアプリのポート番号は、記事執筆時点では指定できませんでした。ECSのブルーグリーンデプロイメントでは同一 ドメイン の異なるポート番号で本番環境とテスト環境が存在するため、テスト環境にアクセスしたときのデータもCloudWatch RUMに登録されてしまいます。本番 トラフィック に比べてテスト トラフィック が十分に少なければ気にしなくても良いかもしれませんが、今回は本番環境からのみデータが送信される仕組みを作ってみます。 解決方法 ブルーグリーンデプロイメントの場合、本番環境とテスト環境は同一の構成であり、ルーティングだけが異なります。つまり本番環境にだけCloudWatch RUMの コードスニペット を含めたり、コンテナに渡す 環境変数 によってデータ送信の有効化を制御したりすることはできません。 そこでCloudWatch RUMの コードスニペット を直接アプリに含めるのではなくブラウザで外部から取得するようにし、取得した スクリプト へのブラウザ内アクセスをCORSで制限するようにしました。こうすることで、テスト環境では スクリプト がブラウザで実行されず、データはCloudWatch RUMに送信されません。テスト環境ではブラウザのコンソールにCORSエラーが出ますが、本番環境ではないので問題ないでしょう。 具体的にはイン フラリ ソースとしてS3 バケット を作成してCORSを設定し、そこに コードスニペット をファイルで追加します。これだけでも動くとは思いますが、S3 バケット をパブリックにしたくないため、 バケット 自体は非公開のままでCloudFront経由でコンテンツを配信するようにします。CloudFront ディストリビューション には 独自ドメイン の TLS 証明書を関連付けました。CORSを効かせるために、アプリの ドメイン とはクロス ドメイン になるようにします。 以下では順を追って設定方法を説明します。 CloudFront用 TLS 証明書の用意 TLS 証明書をあらかじめ発行しておきます。今回はアプリ ドメイン my-domain.com の サブドメイン として、 static.my-domain.com を利用するとします。CORSのオリジンは プロトコル 、 ドメイン 、ポートの3点セットで区別されるため、アプリ ドメイン とはクロスオリジンの関係になります。 参考までにCDKの場合のコードサンプルを掲載します。(証明書はCloudFrontで利用するため、us-east-1 リージョンにデプロイします) const hostedZone = route53.PublicHostedZone.fromHostedZoneAttributes ( this , "MyHostedZone" , { hostedZoneId: "<ホストゾーンID>" , zoneName: "my-domain.com" , } ); const cloudfrontCertificate = new certificatemanager.DnsValidatedCertificate ( this , "CloudFrontCertificate" , { domainName: "static.my-domain.com" , hostedZone: hostedZone , validation: certificatemanager.CertificateValidation.fromDns ( hostedZone ), } ); Webアプリで外部から コードスニペット を取得する アプリケーションモニターの コードスニペット を直接コードに含めるのではなく、以下の形で src として読み込んでもらうことを考えます。 < script src = "https://static.my-domain.com/rum.js" ></ script > <script> タグの src で外部からファイルを取得する場合、GETによる単純リク エス トになるため、CORSの プリフライトリクエスト は発生しません。すなわちOPTIONSリク エス トは送信されず、443ポートでも8443ポートでもGETリク エス トでリソースは取得され、実行されます。 そこで crossorigin属性 を利用します。これを指定することによって リクエストモード が cors となり、クロスオリジン環境下ではサイトの Origin が スクリプト を取得する際の Access-Control-Allow-Origin レスポンスヘッダーに含まれない限り、ロードした スクリプト がブラウザで実行されなくなります。(crossorigin属性を付けない場合、 <script> タグのリク エス トモードは no-cors となり、サイトの Origin に関わらずロードした スクリプト がブラウザで実行されます) (参考) https://nhiroki.jp/2021/01/07/crossorigin-attribute 以下のように、Webアプリの <head> タグ内でアプリケーションモニターの コードスニペット を読み込むようにし、crossorigin属性を設定します( rum.js ファイルはのちにS3 バケット を作成したときに追加します)。 < head > < script src = "https://static.my-domain.com/rum.js" crossorigin = "anonymous" ></ script > </ head > またcrossorigin属性を付けることにより、 スクリプト を取得する際のGETリク エス トに Origin ヘッダーが付与されるようになります。これは次に述べるS3 バケット からのレスポンスヘッダーにも影響します。 図にまとめると、crossorigin属性を使用しない場合、本番環境でもテスト環境でも スクリプト が実行されてしまいます。 crossorigin属性を使用する場合は次のようになり、本番環境のみ スクリプト が実行されます。 コードスニペット 格納用のS3 バケット を作成 S3 バケット を作成し、本番環境のみを許可するCORSを設定します。 const myBucket = new s3.Bucket ( this , "MyBucket" , { encryption: s3.BucketEncryption.S3_MANAGED , blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL , objectOwnership: s3.ObjectOwnership.BUCKET_OWNER_ENFORCED , enforceSSL: true , cors: [ { allowedHeaders: [ "*" ] , allowedMethods: [ s3.HttpMethods.GET ] , allowedOrigins: [ "https://my-domain.com" ] , } , ] , } ); この設定をした場合の動きを確認してみました。リク エス トヘッダーに Origin: https://my-domain.com が含まれている場合、以下のレスポンスヘッダーが付与されました。 Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: GET Access-Control-Allow-Origin: https://my-domain.com リク エス トヘッダーが Origin: https://my-domain.com:8443 となっている場合、以上の3つの Access-Control-* レスポンスヘッダーは付与されていませんでした。 S3 バケット のアクセス制御 CORSの設定とは関係ありませんが、CloudFrontの OAC(オリジンアクセスコントロール) を利用し、S3 バケット へのアクセスを次のステップで作成するCloudFront ディストリビューション からのみに制限します。 執筆時点でCDKのL2コンスト ラク トではまだOACがサポートされていないため、以下はOACではなくOAIを利用する場合のコードサンプルです。L2コンスト ラク トでOACがサポートされたらそれを利用するのが良いでしょう。 const oai = new cloudfront.OriginAccessIdentity ( this , "MyOAI" ); myBucket.addToResourcePolicy ( new iam.PolicyStatement ( { effect: iam.Effect.ALLOW , actions: [ "s3:GetObject" ] , principals: [ new iam.CanonicalUserPrincipal ( oai.cloudFrontOriginAccessIdentityS3CanonicalUserId ) ] , resources: [ ` ${ myBucket.bucketArn } /*` ] , } ) ); S3 バケット に コードスニペット をファイルで追加する アプリケーションモニターの コードスニペット のうち、 <script> タグを除外した部分をコピーした JavaScript ファイルを作成します。今回は rum.js というファイル名としてS3 バケット にアップロードします。 CloudFront ディストリビューション の作成 CloudFront ディストリビューション を作成します。ここで重要なのは 3つのポリシー です。 まずはキャッシュポリシーとして、 Origin ヘッダーをキャッシュキーに含めるようにします。すなわちリク エス トの Origin ヘッダーが異なる値の場合は、異なるコンテンツを要求しているとみなし、本番環境とテスト環境での振る舞いを切り替えます。 const cachePolicy = new cloudfront.CachePolicy ( this , "MyCachePolicy" , { defaultTtl: cdk.Duration.days ( 1 ), maxTtl: cdk.Duration.days ( 1 ), minTtl: cdk.Duration.days ( 1 ), headerBehavior: cloudfront.CacheHeaderBehavior.allowList ( "Origin" ), } ); 次にオリジンリク エス トポリシーとして、CloudFrontからオリジンへのリク エス トに Origin ヘッダーを含めて転送するようにします。これにより、S3 バケット で設定したCORSが機能するようになります。 const originRequestPolicy = new cloudfront.OriginRequestPolicy ( this , "MyOriginRequestPolicy" , { headerBehavior: cloudfront.CacheHeaderBehavior.allowList ( "Origin" ), } ); 最後にレスポンスヘッダーポリシーとして、CloudFrontからレスポンスを返すときにCORSヘッダーを含めるようにします。 const responseHeadersPolicy = new cloudfront.ResponseHeadersPolicy ( this , "MyResponseHeadersPolicy" , { corsBehavior: { accessControlAllowCredentials: false , accessControlAllowHeaders: [ "*" ] , accessControlAllowMethods: [ "GET" ] , accessControlAllowOrigins: [ "https://my-domain.com" ] , originOverride: false , } , } ); 以上のポリシーを利用してCloudFront ディストリビューション を作成します。今回の構成ではOPTIONSメソッドは送信されないため、許可するメソッドにOPTIONSは含めていません。 const distribution = new cloudfront.Distribution ( this , "MyDistribution" , { defaultBehavior: { allowedMethods: cloudfront.AllowedMethods.ALLOW_GET_HEAD , cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD , cachePolicy , originRequestPolicy , responseHeadersPolicy , viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS , origin: new cloudfrontOrigins.S3Origin ( myBucket ), } , priceClass: cloudfront.PriceClass.PRICE_CLASS_200 , geoRestriction: cloudfront.GeoRestriction.allowlist ( "JP" ), sslSupportMethod: cloudfront.SSLMethod.SNI , minimumProtocolVersion: cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021 , certificate: cloudfrontCertificate , domainNames: [ "static.my-domain.com" ] , } ); ドメイン のルーティング 作成したCloudFront ディストリビューション に、 static.my-domain.com のルーティングを向けて完了です。 new route53.ARecord ( this , "StaticARecord" , { zone: hostedZone , recordName: "static" , target: route53.RecordTarget.fromAlias (new route53Targets.CloudFrontTarget ( distribution )), } ); 動きの確認 本番環境の https://my-domain.com にアクセスすると、 https://static.my-domain.com/rum.js の取得に成功していることを確認できました。実際にはさらに https://client.rum.us-east-1.amazonaws.com/1.5.x/cwr.js より スクリプト の本体をロードしており、 https://dataplane.rum.ap-notheast-1.amazonaws.com/appmonitors/ にブラウザのクライアントデータを送信していました。マネジメントコンソールのCloudWatch RUMの画面にアクセスすると、データが取得されていることがわかります。 一方、テスト環境の https://my-domain.com:8443 にアクセスすると、 https://static.my-domain.com/rum.js からのレスポンスステータスは200で返りますが、クロスオリジンの読み込みが許可されていないためブラウザは スクリプト にアクセスできず、実行されません。 これでECSのブルーグリーンデプロイメントの本番環境のみ、CloudWatch RUMにデータ送信を実現できました。 私たちは同じチームで働いてくれる仲間を大募集しています!たくさんのご応募をお待ちしています。 - セキュリティエンジニア(セキュリティ設計) 執筆: @kou.kinyo 、レビュー: @yamada.y ( Shodo で執筆されました )
アバター
去る10/9に実施された IPA さんの秋期 情報処理技術者試験 ですが、最近は試験直後に過去問が公開されるようになっているのを知っていますか。最近の過去問はなかなかに味わい深いと思っているので、所属部門で「味わう会」をやってみた、というお話をご紹介したいと思います。金融ソリューション事業部 石沢がレポートします。  ISIDでは応用情報以上の 情報処理技術者試験 の受験は強制でなく、昇格などの条件でもありません(新卒採用の場合、 基本情報技術者 資格の取得は原則必須としています)。一方で、受験費用は社費負担ですし、通信教育を利用することも可能です(通信教育は修了かつ試験に合格すれば社費負担になります)。というわけで、自分の スキルアップ 、腕試しなどで利用しやすい制度となっています。余談ですが、情報処理安全確保支援士など合格後に資格を維持する場合の費用も同様です(助かる~)。 今回紹介した過去問 時間の関係もあったので、令和4年度秋期 情報処理試験 のうち以下の過去問、試験区分を取り上げました。 プロジェクトマネージャ試験 午後Ⅰと午後Ⅱ データベーススペシャリスト 試験 午後Ⅰ システム監査技術者試験 午後Ⅰ 過去問はこちらのURLから参照可能です。以下の記事が面白いと感じられた人は実際の問題もぜひご確認ください。 IPA 独立行政法人 情報処理推進機構:過去問題 なお実際の「味わう会」は実際の試験日(10/9)の3日後にスピード勝負でやってみました。受験したばかりの人の記憶が薄れないうちに…… 過去問の紹介方法 紹介の目的は問題の正解を解説することでなく「試験問題を面白がる」ことにフォーカスしていたので、 ざっくりどんな問題が出たかを見てみる 受験した人が感想や意見を述べる という感じで紹介をしました。 個人の感想ですが、 IPA の 情報処理技術者試験 は継続的にアップデートされ、特に高度試験では日常われわれが直面するような課題を提示していると思っています。最近のトレンドなども割と反映されているのが味わい深いです。 具体的な紹介内容(プロジェクトマネージャ試験 編) 午後Ⅰ問2: ECサイト 刷新プロジェクトにおけるプロジェクト計画の問題 情報システム部の部長(兼PM)となった気持ちで、老舗アパレル企業の ECサイト を刷新するプロジェクトを担当する 仮想店舗( メタバース )を活用した新規事業開発がテーマ 新技術への匂い(DevOps、仮想店舗) 以上を背景にプロジェクト計画を立案する プロジェクトの最優先課題は何か 知見蓄積のためにどういう活動が必要か CI/CD導入のために組織を超えて行う活動は何か 顧客が自宅にいながら アバター として仮想店舗に来店して試着できる システム開発 プロジェクトのPMとは……。ちょっと想像しただけで大変そうです。ざっくりとした問題を紹介した上で、あーだこーだと意見交換しました(以下、同様です)。 午後Ⅰ問3:プロジェクトにおけるチームビルディングに関する問題 支配型・統制型リーダーシップが支配する玩具製造業F社においてDX推進を進めるプロジェクト。 CDO が旗を振っており、そのもとでシステム部長G氏がPMとしてプロジェクトをけん引します PMはDXを実現するために事業戦略的なITプロジェクトが必要と判断。部門横断のチーム組成を行い、自己組織化されたチーム作りを目指します いわゆるDXプロジェクトのPMです。いやぁ、こんな問題が出るとは(遠い目)。 午後Ⅱ問2: ステークホルダー とのコミュニケーション 午後Ⅱは小論文を書く問題です。問2は自身の経験に基づき「 ステークホルダー とのコミュニケーション」について記述する問題でしたが、実際に受験をしてこの設問を選んだ人にどのような事を書いたのかを紹介してもらいました。 具体的な紹介内容( データベーススペシャリスト 試験 編) 午後Ⅰ問1:アフターサービス業務の概念 モデリング 住宅設備メーカーA社が、アフターサービス業務のシステム再構築プロジェクトで業務分析を行い、概念データモデルと関係 スキーマ を作成したという状況 問題文には業務分析の ヒアリ ング結果と、新システムでの要求事項が( 自然言語 で)ズラーっと書いてある 設問は、まず現状の概念データモデルを完成させ、次に新システムの要求事項を考慮した修正後の概念データモデルを穴埋め問題で完成させるもの 受託開発などのシチュエーションでよくある局面です。特に要件定義などを実施する人はさらっと解きたい。 午後Ⅰ問2: クラウド PaaSを用いたデータベースの実装 専門商社のBは見積システムのマスター保守改善を行いつつ、 パブリッククラウド へ移行する方針 見積システムでは商品履歴の管理が出来ていないので、まずこれはDBトリガーでなんとかする さらに クラウド リフトするので、非機能の検討も行った 設問は上記の結果の穴埋め問題 保守小規模エンハンスでもありそうな機能レベルアップを DBMS だけでなんとかする問題と、 クラウド リフト案件として非機能要件(RPOやRTOなど)検討という、二つの問題を合体させたような欲張りな問題です。 午後Ⅰ問3:オンプレ販売管理システムのDBパフォーマンス改善 事務用品販売C社の運用中の販売管理システムにおける RDBMS 課題に関する問題 主要なテーブル構成、業務利用方法、現在の課題(業務ピーク日にバッチ遅延が原因の出庫遅延発生)が本文で説明されている 分析の結果 ①アクセス数の多いテーブルの再編成を検討したが、問題があったので見送りとした ② バッチ処理 の多重化を検討し、 デッドロック が発生するリスクも分析をした ③出庫遅延に関しては ボトルネック の調査を行った 問題は上記①~③の穴埋め問題、およびそれぞれの作業に関するリスクを文章で答えさせる形式 DBパフォーマンス改善、これもよくある話ですね。 具体的な紹介内容(システム監査技術者 編) 午後Ⅰ問1: ECサイト における改正 個人情報保護法 対応の十分性の監査 個人情報を取り扱う ECサイト に関して、改正 個人情報保護法 の対応が適切にされているかを監査する問題 サイトに関する監査の結果(予備調査、本調査)が問題文には示され、「どうしてそのような結論になったか。その際に調査すべき観点と対象は何か」を答えさせるもの システム監査の観点だけではなく、改正 個人情報保護法 の論点も理解できる問題でした。 午後Ⅰ問2:リモートワークに即したWF利用等業務改善の推進状況の監査 数年前にワークフロー(WF)システムを導入済の企業が、コロナ対策でリモートワークを推進したことをきっかけに「 働き方改革 」「業務効率化(申請事務の廃止やペーパーレス化)」を現在全社的に推進している 経営方針に即して対応が進められているか監査を実施した。監査の結果が問題文で示され、問ではそれぞれの調査をどのように行ったのか(確認手段と確認観点)を回答させる問題 極めて現代的な問題。ISIDもリモートワークを推進していますが、業務効率化って大変だなとしみじみ感じられる問題です。 午後Ⅰ問3:金融機関のシステム運用(再委託)適切性の監査 金融機関Cは、 クラウド サービスの活用なども進めているが、一方で既存システムの安定稼働は重要な経営課題と認識。システム部は情報システムの安定稼働の対策を継続して実施中 C社は運用を子会社D社に委託。D社は複数社に再委託している。夜間の運用は再委託先のみで実施しているが、障害発生時にD社保守担当に連絡が取れない事もあるので、その場合はD社運用管理部責任者の承認により必要最低限の対応を行うことになっている この状況を監査するにあたって、予備調査でいろいろと気になる点が出てきた。それをもとにどのような本調査を計画するかが問題となっている 「味わう会」を実施した金融ソリューション事業部としては、まさに日常的な風景な問題です。監査の際にどのような点が論点になるのかもわかる問題でした。 やってみた感想 参加者からは「想像していたよりも実務的な内容でびっくりした」「自分のチェックしていなかった試験区分に興味を持てた」などのリアクションがありました。 ソフトウェアを開発するにあたっては、スキルと経験が重要だと思っています。スキルはいいとしても、多様な経験を積むには時間を要するので、こういった問題に触れることは不足する経験を補う良いト レーニン グだと考えています。 世間的にも、また当然社内でも「資格試験は実務と乖離していて、勉強する意義はない」「内容は古臭くて、現代の業務に合っていない(から勉強する意味はない)」といった声があるのは事実ですが、実際に問題を眺めてみるとそうではないことがわかります。 本記事で興味をもった皆さんには、周囲の方と一緒に問題を眺めながら意見交換してみることをお勧めします。 私たちは同じグループで共に働いていただける仲間を募集しています。 金融システムプロジェクトマネージャー  他多数募集中です。 仕事をしながら学ぶことへの支援制度は今回ご紹介したもの以外も充実しています。また、 情報処理技術者試験 の過去問を語り合ったりする組織に興味のある方も、ぜひご検討よろしくお願いします。 執筆: Ishizawa Kento (@kent) 、レビュー: @nakamura.toshihiro ( Shodo で執筆されました )
アバター
去る10/9に実施された IPA さんの秋期 情報処理技術者試験 ですが、最近は試験直後に過去問が公開されるようになっているのを知っていますか。最近の過去問はなかなかに味わい深いと思っているので、所属部門で「味わう会」をやってみた、というお話をご紹介したいと思います。金融ソリューション事業部 石沢がレポートします。  ISIDでは応用情報以上の 情報処理技術者試験 の受験は強制でなく、昇格などの条件でもありません(新卒採用の場合、 基本情報技術者 資格の取得は原則必須としています)。一方で、受験費用は社費負担ですし、通信教育を利用することも可能です(通信教育は修了かつ試験に合格すれば社費負担になります)。というわけで、自分の スキルアップ 、腕試しなどで利用しやすい制度となっています。余談ですが、情報処理安全確保支援士など合格後に資格を維持する場合の費用も同様です(助かる~)。 今回紹介した過去問 時間の関係もあったので、令和4年度秋期 情報処理試験 のうち以下の過去問、試験区分を取り上げました。 プロジェクトマネージャ試験 午後Ⅰと午後Ⅱ データベーススペシャリスト 試験 午後Ⅰ システム監査技術者試験 午後Ⅰ 過去問はこちらのURLから参照可能です。以下の記事が面白いと感じられた人は実際の問題もぜひご確認ください。 IPA 独立行政法人 情報処理推進機構:過去問題 なお実際の「味わう会」は実際の試験日(10/9)の3日後にスピード勝負でやってみました。受験したばかりの人の記憶が薄れないうちに…… 過去問の紹介方法 紹介の目的は問題の正解を解説することでなく「試験問題を面白がる」ことにフォーカスしていたので、 ざっくりどんな問題が出たかを見てみる 受験した人が感想や意見を述べる という感じで紹介をしました。 個人の感想ですが、 IPA の 情報処理技術者試験 は継続的にアップデートされ、特に高度試験では日常われわれが直面するような課題を提示していると思っています。最近のトレンドなども割と反映されているのが味わい深いです。 具体的な紹介内容(プロジェクトマネージャ試験 編) 午後Ⅰ問2: ECサイト 刷新プロジェクトにおけるプロジェクト計画の問題 情報システム部の部長(兼PM)となった気持ちで、老舗アパレル企業の ECサイト を刷新するプロジェクトを担当する 仮想店舗( メタバース )を活用した新規事業開発がテーマ 新技術への匂い(DevOps、仮想店舗) 以上を背景にプロジェクト計画を立案する プロジェクトの最優先課題は何か 知見蓄積のためにどういう活動が必要か CI/CD導入のために組織を超えて行う活動は何か 顧客が自宅にいながら アバター として仮想店舗に来店して試着できる システム開発 プロジェクトのPMとは……。ちょっと想像しただけで大変そうです。ざっくりとした問題を紹介した上で、あーだこーだと意見交換しました(以下、同様です)。 午後Ⅰ問3:プロジェクトにおけるチームビルディングに関する問題 支配型・統制型リーダーシップが支配する玩具製造業F社においてDX推進を進めるプロジェクト。 CDO が旗を振っており、そのもとでシステム部長G氏がPMとしてプロジェクトをけん引します PMはDXを実現するために事業戦略的なITプロジェクトが必要と判断。部門横断のチーム組成を行い、自己組織化されたチーム作りを目指します いわゆるDXプロジェクトのPMです。いやぁ、こんな問題が出るとは(遠い目)。 午後Ⅱ問2: ステークホルダー とのコミュニケーション 午後Ⅱは小論文を書く問題です。問2は自身の経験に基づき「 ステークホルダー とのコミュニケーション」について記述する問題でしたが、実際に受験をしてこの設問を選んだ人にどのような事を書いたのかを紹介してもらいました。 具体的な紹介内容( データベーススペシャリスト 試験 編) 午後Ⅰ問1:アフターサービス業務の概念 モデリング 住宅設備メーカーA社が、アフターサービス業務のシステム再構築プロジェクトで業務分析を行い、概念データモデルと関係 スキーマ を作成したという状況 問題文には業務分析の ヒアリ ング結果と、新システムでの要求事項が( 自然言語 で)ズラーっと書いてある 設問は、まず現状の概念データモデルを完成させ、次に新システムの要求事項を考慮した修正後の概念データモデルを穴埋め問題で完成させるもの 受託開発などのシチュエーションでよくある局面です。特に要件定義などを実施する人はさらっと解きたい。 午後Ⅰ問2: クラウド PaaSを用いたデータベースの実装 専門商社のBは見積システムのマスター保守改善を行いつつ、 パブリッククラウド へ移行する方針 見積システムでは商品履歴の管理が出来ていないので、まずこれはDBトリガーでなんとかする さらに クラウド リフトするので、非機能の検討も行った 設問は上記の結果の穴埋め問題 保守小規模エンハンスでもありそうな機能レベルアップを DBMS だけでなんとかする問題と、 クラウド リフト案件として非機能要件(RPOやRTOなど)検討という、二つの問題を合体させたような欲張りな問題です。 午後Ⅰ問3:オンプレ販売管理システムのDBパフォーマンス改善 事務用品販売C社の運用中の販売管理システムにおける RDBMS 課題に関する問題 主要なテーブル構成、業務利用方法、現在の課題(業務ピーク日にバッチ遅延が原因の出庫遅延発生)が本文で説明されている 分析の結果 ①アクセス数の多いテーブルの再編成を検討したが、問題があったので見送りとした ② バッチ処理 の多重化を検討し、 デッドロック が発生するリスクも分析をした ③出庫遅延に関しては ボトルネック の調査を行った 問題は上記①~③の穴埋め問題、およびそれぞれの作業に関するリスクを文章で答えさせる形式 DBパフォーマンス改善、これもよくある話ですね。 具体的な紹介内容(システム監査技術者 編) 午後Ⅰ問1: ECサイト における改正 個人情報保護法 対応の十分性の監査 個人情報を取り扱う ECサイト に関して、改正 個人情報保護法 の対応が適切にされているかを監査する問題 サイトに関する監査の結果(予備調査、本調査)が問題文には示され、「どうしてそのような結論になったか。その際に調査すべき観点と対象は何か」を答えさせるもの システム監査の観点だけではなく、改正 個人情報保護法 の論点も理解できる問題でした。 午後Ⅰ問2:リモートワークに即したWF利用等業務改善の推進状況の監査 数年前にワークフロー(WF)システムを導入済の企業が、コロナ対策でリモートワークを推進したことをきっかけに「 働き方改革 」「業務効率化(申請事務の廃止やペーパーレス化)」を現在全社的に推進している 経営方針に即して対応が進められているか監査を実施した。監査の結果が問題文で示され、問ではそれぞれの調査をどのように行ったのか(確認手段と確認観点)を回答させる問題 極めて現代的な問題。ISIDもリモートワークを推進していますが、業務効率化って大変だなとしみじみ感じられる問題です。 午後Ⅰ問3:金融機関のシステム運用(再委託)適切性の監査 金融機関Cは、 クラウド サービスの活用なども進めているが、一方で既存システムの安定稼働は重要な経営課題と認識。システム部は情報システムの安定稼働の対策を継続して実施中 C社は運用を子会社D社に委託。D社は複数社に再委託している。夜間の運用は再委託先のみで実施しているが、障害発生時にD社保守担当に連絡が取れない事もあるので、その場合はD社運用管理部責任者の承認により必要最低限の対応を行うことになっている この状況を監査するにあたって、予備調査でいろいろと気になる点が出てきた。それをもとにどのような本調査を計画するかが問題となっている 「味わう会」を実施した金融ソリューション事業部としては、まさに日常的な風景な問題です。監査の際にどのような点が論点になるのかもわかる問題でした。 やってみた感想 参加者からは「想像していたよりも実務的な内容でびっくりした」「自分のチェックしていなかった試験区分に興味を持てた」などのリアクションがありました。 ソフトウェアを開発するにあたっては、スキルと経験が重要だと思っています。スキルはいいとしても、多様な経験を積むには時間を要するので、こういった問題に触れることは不足する経験を補う良いト レーニン グだと考えています。 世間的にも、また当然社内でも「資格試験は実務と乖離していて、勉強する意義はない」「内容は古臭くて、現代の業務に合っていない(から勉強する意味はない)」といった声があるのは事実ですが、実際に問題を眺めてみるとそうではないことがわかります。 本記事で興味をもった皆さんには、周囲の方と一緒に問題を眺めながら意見交換してみることをお勧めします。 私たちは同じグループで共に働いていただける仲間を募集しています。 金融システムプロジェクトマネージャー  他多数募集中です。 仕事をしながら学ぶことへの支援制度は今回ご紹介したもの以外も充実しています。また、 情報処理技術者試験 の過去問を語り合ったりする組織に興味のある方も、ぜひご検討よろしくお願いします。 執筆: Ishizawa Kento (@kent) 、レビュー: @nakamura.toshihiro ( Shodo で執筆されました )
アバター
電通国際情報サービス 、オープン イノベーション ラボの 比嘉康雄 です。 Web3開発入門シリーズ with Algorand(アルゴランド)、今回のテーマは、 TestNetでALGOをゲット です。 今回の記事のGoogle Colab用のノートブックはこちらになります。ブラウザだけでブロックチェーンに対するコードを、実際に動かしながら試せるので、おすすめです。 Web3開発入門 with Algorandの全てのコンテンツ アカウント TestNetでALGOをゲット 支払い アセットの作成 MainNet TestNet BetaNet Algorand Dispenser ALGOの残高を確認する まとめ 仲間募集 Algorand には、目的に合わせて、いくつかのネットワークが用意されています。 MainNet Algorand の本番用のネットワーク。みんなが Algorand と思っているのはこのネットワークです。 TestNet テスト用のネットワーク。 MainNet を使う前に、テストするために使います。基本は、 MainNet と同じバージョンです。 入門シリーズで使うのはこのネットワークです。 BetaNet ベータ版の Algorand をテストするためのネットワーク。コアな開発者向けなので、あまり使うことはないでしょう。 Algorand Dispenser Algorand は、 トランザクション 手数料が0.05円(0.001 ALGO)と非常に安価ですが、 トランザクション を処理してもらうためには必ず手数料がかかります。 MainNet では、クレジットカードや暗号資産取引所を通じて、有料でALGOを手に入れます。 TestNet では、 Algorand Dispenser のサイトで、 ALGO を無料でゲットできます。 アカウントを作成するために、 py-algorand-sdk をインストールしましょう。 下記のコードを実行してください。 !pip3 install py-algorand-sdk アカウントを作成しましょう。 下記のコードを実行してください。 from algosdk import account private_key, address = account.generate_account() print("Address:", address) 出力結果の例です。 Address: NPDQGX5PSKDOUDUK22CRCCEPMZXQY62YWE25APS73F4MNAWJQLUN5SDFRA Address: の後ろの部分のアドレスをコピーしてください。 Algorand Dispenser のサイトにアクセスし、 I'm not a roboot をチェックし、 target address の入力エリアに先ほどコピーしたアドレスをペーストします。 Dispense のボタンをクリックしてください。 Status: Code 200 success のように表示されればOKです。 ALGOの残高を確認する 先程のアカウントに本当に ALGO が入金されたのか確認してみましょう。 Algorand にアクセスするので、 AlgodClient オブジェクトを作成します。 下記のコードを実行してください。 from algosdk.v2client.algod import AlgodClient algod = AlgodClient("", "https://node.testnet.algoexplorerapi.io:443") AlgodClient オブジェクトを作成するときに、 https://node.testnet.algoexplorerapi.io:443 を指定していますね。これにより Algoexplorer の TestNet のノードに接続します。 https://node.algoexplorerapi.io:443 にすると、 MainNet に接続できます。 アカウントの情報は、 AlgodClientオブジェクト.account_info() を呼び出して取得します。 下記のコードを実行してください。 info = algod.account_info(address) info オブジェクトの amount 属性に ALGO の残高が入っています。 下記のコードを実行してください。 print("micro ALGO amount", info["amount"]) print("ALGO amount", info["amount"] / 1000000) Algorand 内部では、 ALGO は micro ALGO という単位で管理されています。1000000 micro ALGO が1 ALGO に相当します。 つまり、 micro ALGO を1000000(0六個)で割れば、 ALGO になります。 Algorand Dispenser で10 ALGOをゲットできましたね。 まとめ TestNet では、 Algorand Dispenser で簡単に ALGO をゲットできることが体験できたと思います。 次回は、 支払い です。 なにか感想があれば、 Twitter で @yasuo_algo にメンションしてつぶやいてください。 仲間募集 私たちは同じグループで共に働いていただける仲間を募集しています。 現在、以下のような職種を募集しています。 ソリューションアーキテクト AIエンジニア 執筆: @higa 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
アバター
電通国際情報サービス 、オープン イノベーション ラボの 比嘉康雄 です。 Web3開発入門シリーズ with Algorand(アルゴランド)、今回のテーマは、 TestNetでALGOをゲット です。 今回の記事のGoogle Colab用のノートブックはこちらになります。ブラウザだけでブロックチェーンに対するコードを、実際に動かしながら試せるので、おすすめです。 Web3開発入門 with Algorandの全てのコンテンツ アカウント TestNetでALGOをゲット 支払い アセットの作成 MainNet TestNet BetaNet Algorand Dispenser ALGOの残高を確認する まとめ 仲間募集 Algorand には、目的に合わせて、いくつかのネットワークが用意されています。 MainNet Algorand の本番用のネットワーク。みんなが Algorand と思っているのはこのネットワークです。 TestNet テスト用のネットワーク。 MainNet を使う前に、テストするために使います。基本は、 MainNet と同じバージョンです。 入門シリーズで使うのはこのネットワークです。 BetaNet ベータ版の Algorand をテストするためのネットワーク。コアな開発者向けなので、あまり使うことはないでしょう。 Algorand Dispenser Algorand は、 トランザクション 手数料が0.05円(0.001 ALGO)と非常に安価ですが、 トランザクション を処理してもらうためには必ず手数料がかかります。 MainNet では、クレジットカードや暗号資産取引所を通じて、有料でALGOを手に入れます。 TestNet では、 Algorand Dispenser のサイトで、 ALGO を無料でゲットできます。 アカウントを作成するために、 py-algorand-sdk をインストールしましょう。 下記のコードを実行してください。 !pip3 install py-algorand-sdk アカウントを作成しましょう。 下記のコードを実行してください。 from algosdk import account private_key, address = account.generate_account() print("Address:", address) 出力結果の例です。 Address: NPDQGX5PSKDOUDUK22CRCCEPMZXQY62YWE25APS73F4MNAWJQLUN5SDFRA Address: の後ろの部分のアドレスをコピーしてください。 Algorand Dispenser のサイトにアクセスし、 I'm not a roboot をチェックし、 target address の入力エリアに先ほどコピーしたアドレスをペーストします。 Dispense のボタンをクリックしてください。 Status: Code 200 success のように表示されればOKです。 ALGOの残高を確認する 先程のアカウントに本当に ALGO が入金されたのか確認してみましょう。 Algorand にアクセスするので、 AlgodClient オブジェクトを作成します。 下記のコードを実行してください。 from algosdk.v2client.algod import AlgodClient algod = AlgodClient("", "https://node.testnet.algoexplorerapi.io:443") AlgodClient オブジェクトを作成するときに、 https://node.testnet.algoexplorerapi.io:443 を指定していますね。これにより Algoexplorer の TestNet のノードに接続します。 https://node.algoexplorerapi.io:443 にすると、 MainNet に接続できます。 アカウントの情報は、 AlgodClientオブジェクト.account_info() を呼び出して取得します。 下記のコードを実行してください。 info = algod.account_info(address) info オブジェクトの amount 属性に ALGO の残高が入っています。 下記のコードを実行してください。 print("micro ALGO amount", info["amount"]) print("ALGO amount", info["amount"] / 1000000) Algorand 内部では、 ALGO は micro ALGO という単位で管理されています。1000000 micro ALGO が1 ALGO に相当します。 つまり、 micro ALGO を1000000(0六個)で割れば、 ALGO になります。 Algorand Dispenser で10 ALGOをゲットできましたね。 まとめ TestNet では、 Algorand Dispenser で簡単に ALGO をゲットできることが体験できたと思います。 次回は、 支払い です。 なにか感想があれば、 Twitter で @yasuo_algo にメンションしてつぶやいてください。 仲間募集 私たちは同じグループで共に働いていただける仲間を募集しています。 現在、以下のような職種を募集しています。 ソリューションアーキテクト AIエンジニア 執筆: @higa 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
アバター
電通国際情報サービス 、オープン イノベーション ラボの 比嘉康雄 です。 Web3開発入門シリーズ with Algorand(アルゴランド)、今回のテーマは、アカウントです。 Ethereum の開発入門記事として、以前に Gethはじめました 、 スマートコントラクト入門 を書いていたのですが、 Ethereum から Algorand に興味が移ってしまったということもあり、今後は、 Algorand の技術記事を書いていきたいと思います。 Algorand開発者ポータル Algorand は、日本では知らない人が多いと思いますが、TPS(Transaction per second)は6000、Finality(Transactionが確定するまでの時間)は3.8秒、取引手数料が1件あたり0.05円とかなり優秀なチェーンです。 また、スマート コントラ クトを Python で記述できるので、 Google Colabを使ってブラウザでほとんどの機能が試せるのも大きな魅力です。 今回の記事のGoogle Colab用のノートブックはこちらになります。ブラウザだけでブロックチェーンに対するコードを、実際に動かしながら試せるので、おすすめです。 Web3開発入門 with Algorandの全てのコンテンツ アカウント TestNetでALGOをゲット 支払い アセットの作成 アカウントとは py-algorand-sdkのインストール アカウントの作成 ニーモニック まとめ 仲間募集 アカウントとは アカウントは、アドレスと秘密キーでできています。 アドレスは、 3ZY7ST5EXOHBN7Y5VGMICALT6IGE44QRZULGPO7PRWVNMM7KQNWRBWTS64 のような58文字のIDです。 だれかにALGO(Algorandのネイティブな暗号資産)を送るときには、送り先として誰かのアドレスを指定します。 誰にでも公開して構いません。 秘密キーは、あなたが確かにそのアカウントの所有者であることを証明するために使います。 秘密キーを知っている == そのアカウントの所有者である なので、秘密キーは誰にも知られてはいけません。 秘密キーは、 ニーモニック と言われる英単語の集まりから、再作成できます。Algorandの場合、 ニーモニック は25単語です。 py-algorand- sdk のインストール Algorandの機能を使うには、 py-algorand-sdk をインストールする必要があります。 下記のコードを実行してください。 !pip3 install py-algorand-sdk アカウントの作成 アカウントを作成するには、 generate_account() を呼び出します。 下記のコードを実行してください。 from algosdk import account private_key, address = account.generate_account() print("Address:", address) print("Private Key:", private_key) 出力結果の例です。 Address: TP67T7UHMQ55F7PQ7KZK6HY6O3J37YEB6PXLTOXCJNCJQD3QQ2ZODCTNXE Private Key: gSD3T1pgXn27Omq5gZQnWxwl6GOEYvr48KxSd+hz+OOb/fn+h2Q70v3w+rKvHx5207/ggfPuubriS0SYD3CGsg== generate_account() を呼びだすと、 private_key (秘密キー)と address (アドレス)が返ってくることがわかります。 ニーモニック 秘密キーは、 ニーモニック と言われる英単語の集まりに変換できます。秘密キーを ニーモニック に変換するには、 from_private_key() を呼び出します。 下記のコードを実行してください。 from algosdk import mnemonic mn = mnemonic.from_private_key(private_key) print("Mnemonic:", mn) print("The length of mnemonic:", len(mn.split(" "))) 出力結果の例です。 Mnemonic: awake symptom child aisle rubber tent still health damp faith need shield enforce wheel cart glad butter sentence filter inside special brother cabin abstract thunder The length of mnemonic: 25 秘密キーが25単語からなる ニーモニック に変換されていますね。 mn.split(" ") で、 ニーモニック をブランク区切りで分割しています。 len() で分割した ニーモニック の個数を数えています。 ニーモニック を秘密キーに変換するには、 to_private_key() を呼び出します。 下記のコードを実行してください。 print("Private Key:", mnemonic.to_private_key(mn)) 出力結果の例です。 Private Key: gSD3T1pgXn27Omq5gZQnWxwl6GOEYvr48KxSd+hz+OOb/fn+h2Q70v3w+rKvHx5207/ggfPuubriS0SYD3CGsg== generate_account() で作った秘密キーと同じですね。 まとめ 記念すべきWeb3開発入門 with Algorand第一回。今回は、アカウントについて説明しました。 次回は、 TestNetでALGOをゲット です。 仲間募集 私たちは同じグループで共に働いていただける仲間を募集しています。 現在、以下のような職種を募集しています。 ソリューションアーキテクト AIエンジニア 執筆: @higa 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
アバター
電通国際情報サービス 、オープン イノベーション ラボの 比嘉康雄 です。 Web3開発入門シリーズ with Algorand(アルゴランド)、今回のテーマは、アカウントです。 Ethereum の開発入門記事として、以前に Gethはじめました 、 スマートコントラクト入門 を書いていたのですが、 Ethereum から Algorand に興味が移ってしまったということもあり、今後は、 Algorand の技術記事を書いていきたいと思います。 Algorand開発者ポータル Algorand は、日本では知らない人が多いと思いますが、TPS(Transaction per second)は6000、Finality(Transactionが確定するまでの時間)は3.8秒、取引手数料が1件あたり0.05円とかなり優秀なチェーンです。 また、スマート コントラ クトを Python で記述できるので、 Google Colabを使ってブラウザでほとんどの機能が試せるのも大きな魅力です。 今回の記事のGoogle Colab用のノートブックはこちらになります。ブラウザだけでブロックチェーンに対するコードを、実際に動かしながら試せるので、おすすめです。 Web3開発入門 with Algorandの全てのコンテンツ アカウント TestNetでALGOをゲット 支払い アセットの作成 アカウントとは py-algorand-sdkのインストール アカウントの作成 ニーモニック まとめ 仲間募集 アカウントとは アカウントは、アドレスと秘密キーでできています。 アドレスは、 3ZY7ST5EXOHBN7Y5VGMICALT6IGE44QRZULGPO7PRWVNMM7KQNWRBWTS64 のような58文字のIDです。 だれかにALGO(Algorandのネイティブな暗号資産)を送るときには、送り先として誰かのアドレスを指定します。 誰にでも公開して構いません。 秘密キーは、あなたが確かにそのアカウントの所有者であることを証明するために使います。 秘密キーを知っている == そのアカウントの所有者である なので、秘密キーは誰にも知られてはいけません。 秘密キーは、 ニーモニック と言われる英単語の集まりから、再作成できます。Algorandの場合、 ニーモニック は25単語です。 py-algorand- sdk のインストール Algorandの機能を使うには、 py-algorand-sdk をインストールする必要があります。 下記のコードを実行してください。 !pip3 install py-algorand-sdk アカウントの作成 アカウントを作成するには、 generate_account() を呼び出します。 下記のコードを実行してください。 from algosdk import account private_key, address = account.generate_account() print("Address:", address) print("Private Key:", private_key) 出力結果の例です。 Address: TP67T7UHMQ55F7PQ7KZK6HY6O3J37YEB6PXLTOXCJNCJQD3QQ2ZODCTNXE Private Key: gSD3T1pgXn27Omq5gZQnWxwl6GOEYvr48KxSd+hz+OOb/fn+h2Q70v3w+rKvHx5207/ggfPuubriS0SYD3CGsg== generate_account() を呼びだすと、 private_key (秘密キー)と address (アドレス)が返ってくることがわかります。 ニーモニック 秘密キーは、 ニーモニック と言われる英単語の集まりに変換できます。秘密キーを ニーモニック に変換するには、 from_private_key() を呼び出します。 下記のコードを実行してください。 from algosdk import mnemonic mn = mnemonic.from_private_key(private_key) print("Mnemonic:", mn) print("The length of mnemonic:", len(mn.split(" "))) 出力結果の例です。 Mnemonic: awake symptom child aisle rubber tent still health damp faith need shield enforce wheel cart glad butter sentence filter inside special brother cabin abstract thunder The length of mnemonic: 25 秘密キーが25単語からなる ニーモニック に変換されていますね。 mn.split(" ") で、 ニーモニック をブランク区切りで分割しています。 len() で分割した ニーモニック の個数を数えています。 ニーモニック を秘密キーに変換するには、 to_private_key() を呼び出します。 下記のコードを実行してください。 print("Private Key:", mnemonic.to_private_key(mn)) 出力結果の例です。 Private Key: gSD3T1pgXn27Omq5gZQnWxwl6GOEYvr48KxSd+hz+OOb/fn+h2Q70v3w+rKvHx5207/ggfPuubriS0SYD3CGsg== generate_account() で作った秘密キーと同じですね。 まとめ 記念すべきWeb3開発入門 with Algorand第一回。今回は、アカウントについて説明しました。 次回は、 TestNetでALGOをゲット です。 仲間募集 私たちは同じグループで共に働いていただける仲間を募集しています。 現在、以下のような職種を募集しています。 ソリューションアーキテクト AIエンジニア 執筆: @higa 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
アバター
こんにちは。X イノベーション 本部ソフトウェアデザインセンターの陳です。 CI推進活動の一環として、話題のCI/CDツールDaggerを使ってみました。 この記事では、DaggerでNext.jsプロジェクトのCIを構築して、ローカルと GitHub Actionsで実行する方法について紹介します。 Daggerについて みなさんはどのCI/CDツールを使っていますか?私が所属する部署では GitHub Actionsを使うことが多いです。 従来のCI/CDでは、 GitHub ActionsやCircle CIなどのサービスごとにCI/CD スクリプト を作成する必要があります。 移行するときには移行先のサービスに合わせて スクリプト を書き換えないので、大変なことになります。 一方、Daggerを使えばCI/CD スクリプト をポータブルにできます。 Dagger とは、特定の基盤を依存せずに、CI/CDパイプラインを素早く構築しどこでも実行できるツールです。 Daggerを利用して作成したCI/CD スクリプト は、 GitHub ActionsやCircle CIなど様々なサービスで共通に使えます。 Dagger はDockerの 創始者 のSolomon Hykesが立ちあげた会社です。DaggerはDockerコンテナ上で動作します。 CI/CD スクリプト の設定ファイルはCUE言語で記述します。 環境構築 今回はNext.js+TypeScriptのプロジェクトを使ってDaggerでCIを構築してみました。 ここからは環境構築の手順をまとめます。 まずは 公式ドキュメント に従って、Daggerをインストールします。 私は macOS を使っています。Homebrewを使って簡単にインストールできました。 $ brew install dagger/tap/dagger Windows 、 Linux のインストール方法は公式ドキュメントに記載されていますので、ここでは省略します。 こちらのコマンドでバージョンおよびインストールされた場所を確認できます。 $ dagger version $ type dagger 続いて、プロジェクトのルート ディレクト リで以下のコマンドを実行し、Daggerを初期化します。 $ dagger project init ルート ディレクト リで cue.mod のフォルダが作成されます。 以下のコマンドを実行してDaggerのパッケージをインストールします。 $ dagger project update pkg フォルダーに以下の2つのパッケージが作成されました。 - dagger.io - Daggerエンジン本体を動かすためのアクション(core actions)が実装されたパッケージ - universe.dagger.io - bash 、yarn、go、 Python などDaggerから提供された複合アクションが実装されたパッケージ また、Daggerの全ての動作はDockerコンテナ上で実行されるため、Docker DesktopなどのDockerを実行できる環境のセットアップも必要です。 上記の手順でDaggerを利用できるようになりました。 ローカルでDaggerを実行してみた dagger.cueファイルの作成 DaggerでCIを動かすためには、以下のようにCUE言語でCI スクリプト を作成する必要があります。 package main import ( "dagger.io/dagger" "dagger.io/dagger/core" "universe.dagger.io/bash" "universe.dagger.io/docker" "universe.dagger.io/netlify" ) dagger.#Plan & { client: { filesystem: { // ... } env: { // ... } } actions: { deps: docker.#Build & { // ... } test: bash.#Run & { // ... } build: { run: bash.#Run & { // ... } contents: core.#Subdir & { // ... } } deploy: netlify.#Deploy & { // ... } } } dagger.#Plan の中で actions を宣言し、 actions の中でビルドやテストなどのアクションを宣言できます。 actions 以外にも client を dagger.#Plan の中で宣言し、ローカルファイルの読み取りや書き込み、 環境変数 の参照などができます。詳細は こちら を参照してください。 アクションの実行は以下のコマンドを使います。 $ dagger do {アクション名} 今回は 公式のサンプル を参考に以下のCI スクリプト を作成しました。 ルート ディレクト リで dagger.cue ファイルを作成します。 //dagger.cue package main import ( "dagger.io/dagger" "dagger.io/dagger/core" "universe.dagger.io/yarn" ) dagger.#Plan & { actions: { checkoutCode: core.#Source & { path: "." exclude: [ "node_modules", ".next", ".swc", "*.cue", "*.md", ".git", ] } build: { install: yarn.#Install & { source: checkoutCode.output } build: yarn.#Script & { source: checkoutCode.output name: "build" } test: yarn.#Script & { source: checkoutCode.output name: "test" } } } } Daggerの universe のyarnパッケージを使って、ビルドとテストのアクションを build に定義しました。以下のコマンドを実行すると、インストール、ビルド、テストのアクションが順番に実行されます。 $ dagger do build 以下のログが表示され、ビルドおよびテストが完了しました。 Jestのエラー test を actions の中で直接に宣言しテストを動かすと、 jest の以下のエラーが発生しました。 Field Value logs """\n yarn run v1.22.17\n $ jest --maxWorkers=1\n jest-haste-map: Haste module naming collision: test\n The following files share their name; please adjust your hasteImpl:\n * <rootDir>/cue.mod/pkg/universe.dagger.io/yarn/test/data/foo/package.json\n * <rootDir>/cue.mod/pkg/universe.dagger.io/yarn/test/data/bar/package.json\n\n Done in 6.81s.\n\n """ jest.config.js に以下の設定を追加するとこのエラーを解消できました。 //jest.config.js const customJestConfig = { modulePathIgnorePatterns: ["<rootDir>/cue.mod"], }; ローカルでアプリケーションを動かしてみた Next.jsでは next dev のコマンドを実行することで、開発モードでアプリケーションをローカルで起動できます。daggerを利用する場合は、 actions に以下のコードを追加します。 //dagger.cue dagger.#Plan & { actions: { checkoutCode: core.#Source & { path: "." } dev: yarn.#Script & { source: checkoutCode.output name: "dev" } } } dagger do dev コマンドを実行すると、 localhost:3000 でアプリケーションを確認できます。 ただし、daggerの全ての動作はDockerコンテナ上で実行されるため、コードを変更したら dagger do dev を再実行(つまりコンテナを更新)しないと反映されません。 universe パッケージのyarnと bash Daggerで yarn のアクションを実行する際に、 universe パッケージの universe.dagger.io/yarn 以外にも、 universe.dagger.io/bash を利用して シェルスクリプト で実行できます。 例えば、インストール、ビルド、テストを順番に実行させたい場合は以下の actions を宣言します。 //dagger.cue package main import ( "dagger.io/dagger" "dagger.io/dagger/core" "universe.dagger.io/bash" ) dagger.#Plan & { actions: { checkoutCode: core.#Source & { path: "." } build: { //yarnとbashがインストールされたイメージをpullする pull: docker.#Pull & { source: "node:lts" } //コンテナのfilesystemにファイルをコピーする copy: docker.#Copy & { input: pull.output contents: checkoutCode.output } //コンテナでbashスクリプトを実行する build: bash.#Run & { input: copy.output script: contents: """ yarn install --frozen-lockfile yarn run build yarn run test """ } } } } ただし、 bash は yarn より実行時間が長いです。ローカルでくインストール、ビルド、テストのアクションを行してみた結果、 yarn の実行時間は bash より1分以上も早くなります。 bash 1分35秒 yarn 13秒 bash と yarn 両方が使えるようでしたら、より実行時間の短い yarn を利用したほうがよさそうですね。 npm を利用したい場合は、 yarn のような直接に使える公式パッケージが実装されていないので、 bash を使います。 詳細は公式の サンプル を参照してください。 既存のDockerfileの実行もできる 以下のように、 unverse の docker パッケージを利用すれば、外部のDockerfileを読み込んで実行できます。 またDockerfileの内容を docker.#Dockerfile & {} にも記述できます。詳細は こちら をご参照ください。 //dagger.cue package main import ( "dagger.io/dagger" "dagger.io/dagger/core" "universe.dagger.io/docker" ) dagger.#Plan & { actions: { checkoutCode: core.#Source & { path: "." } build: docker.#Dockerfile & { source: checkoutCode.output } } } GitHub ActionsでDaggerを実行してみた ルート ディレクト リで .github/workflows フォルダを作成し、以下のように yaml ファイルに GitHub Actionsの設定を記述します。pushをトリガーに GitHub Actionsを走らせ、アプリケーションのビルドおよびテストを実行させます。 //build-test-on-push.yml on: push: name: Build and Test on Push jobs: build-and-test: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Build and Test uses: dagger/dagger-for-github@v3 with: cmds: | project update do build dagger/dagger-for-github を利用して、 dagger.cue に定義されたアクションを GitHub Actions上で簡単に動かせます。 従来であれば、 GitHub Actions上にNode.jsをインストールして、 yarn install やビルド、テストそれぞれの設定をしないといけないです。Daggerを利用する場合は、既存のCUEファイルを GitHub Actions上に実行させればOKなので、 GitHub Actionsの yaml ファイルもだいぶスッキリします。 使ってみた感想 CI スクリプト をローカルと GitHub Actionsで同じように実行できるのは便利ですね。ローカルで通ったテストを GitHub Actionsで実行するとなぜか通らなくなった、みたいなことも回避できそうです。また、Daggerを使うと、 yaml ファイルで頑張ってCI スクリプト を書かなくていいので、 GitHub Actionsでの設定もだいぶ簡単になります。 今回は GitHub ActionsでDaggerを試してみましたが、他にもCircle CI、GitLab、Jenkinsなど多数のCIサービスに対応しています。サービス間の移行をより簡単に実現できるので、他のCIサービスでもDaggerを使ってみたいですね。 ただし、使いづらいところもあります。 GitHub Actionsなどの設定が簡単になりますが、CUE言語やDaggerのパッケージの使い方を理解しないとDaggerの利用が難しく感じます。また現時点で、Daggerの公式サイトにある universe パッケージに関するドキュメントはあまり詳しくなく、複雑なCI/CDを構築したい場合はコードを読んで試行錯誤を重ねる必要があるかもしれません。 まとめ この記事では、DaggerでNext.jsプロジェクトのCIを動かしてみたことについてまとめました。 Daggerを使って基盤に依存しないポータブルなCIを簡単に構築できます。みなさんも是非使ってみてください。 私たちは同じチームで働いてくれる仲間を探しています。今回のエントリで紹介したような仕事に興味のある方、ご応募お待ちしています。 ソリューションアーキテクト 執筆: @chen.xinying 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
アバター
こんにちは。X イノベーション 本部ソフトウェアデザインセンターの陳です。 CI推進活動の一環として、話題のCI/CDツールDaggerを使ってみました。 この記事では、DaggerでNext.jsプロジェクトのCIを構築して、ローカルと GitHub Actionsで実行する方法について紹介します。 Daggerについて みなさんはどのCI/CDツールを使っていますか?私が所属する部署では GitHub Actionsを使うことが多いです。 従来のCI/CDでは、 GitHub ActionsやCircle CIなどのサービスごとにCI/CD スクリプト を作成する必要があります。 移行するときには移行先のサービスに合わせて スクリプト を書き換えないので、大変なことになります。 一方、Daggerを使えばCI/CD スクリプト をポータブルにできます。 Dagger とは、特定の基盤を依存せずに、CI/CDパイプラインを素早く構築しどこでも実行できるツールです。 Daggerを利用して作成したCI/CD スクリプト は、 GitHub ActionsやCircle CIなど様々なサービスで共通に使えます。 Dagger はDockerの 創始者 のSolomon Hykesが立ちあげた会社です。DaggerはDockerコンテナ上で動作します。 CI/CD スクリプト の設定ファイルはCUE言語で記述します。 環境構築 今回はNext.js+TypeScriptのプロジェクトを使ってDaggerでCIを構築してみました。 ここからは環境構築の手順をまとめます。 まずは 公式ドキュメント に従って、Daggerをインストールします。 私は macOS を使っています。Homebrewを使って簡単にインストールできました。 $ brew install dagger/tap/dagger Windows 、 Linux のインストール方法は公式ドキュメントに記載されていますので、ここでは省略します。 こちらのコマンドでバージョンおよびインストールされた場所を確認できます。 $ dagger version $ type dagger 続いて、プロジェクトのルート ディレクト リで以下のコマンドを実行し、Daggerを初期化します。 $ dagger project init ルート ディレクト リで cue.mod のフォルダが作成されます。 以下のコマンドを実行してDaggerのパッケージをインストールします。 $ dagger project update pkg フォルダーに以下の2つのパッケージが作成されました。 - dagger.io - Daggerエンジン本体を動かすためのアクション(core actions)が実装されたパッケージ - universe.dagger.io - bash 、yarn、go、 Python などDaggerから提供された複合アクションが実装されたパッケージ また、Daggerの全ての動作はDockerコンテナ上で実行されるため、Docker DesktopなどのDockerを実行できる環境のセットアップも必要です。 上記の手順でDaggerを利用できるようになりました。 ローカルでDaggerを実行してみた dagger.cueファイルの作成 DaggerでCIを動かすためには、以下のようにCUE言語でCI スクリプト を作成する必要があります。 package main import ( "dagger.io/dagger" "dagger.io/dagger/core" "universe.dagger.io/bash" "universe.dagger.io/docker" "universe.dagger.io/netlify" ) dagger.#Plan & { client: { filesystem: { // ... } env: { // ... } } actions: { deps: docker.#Build & { // ... } test: bash.#Run & { // ... } build: { run: bash.#Run & { // ... } contents: core.#Subdir & { // ... } } deploy: netlify.#Deploy & { // ... } } } dagger.#Plan の中で actions を宣言し、 actions の中でビルドやテストなどのアクションを宣言できます。 actions 以外にも client を dagger.#Plan の中で宣言し、ローカルファイルの読み取りや書き込み、 環境変数 の参照などができます。詳細は こちら を参照してください。 アクションの実行は以下のコマンドを使います。 $ dagger do {アクション名} 今回は 公式のサンプル を参考に以下のCI スクリプト を作成しました。 ルート ディレクト リで dagger.cue ファイルを作成します。 //dagger.cue package main import ( "dagger.io/dagger" "dagger.io/dagger/core" "universe.dagger.io/yarn" ) dagger.#Plan & { actions: { checkoutCode: core.#Source & { path: "." exclude: [ "node_modules", ".next", ".swc", "*.cue", "*.md", ".git", ] } build: { install: yarn.#Install & { source: checkoutCode.output } build: yarn.#Script & { source: checkoutCode.output name: "build" } test: yarn.#Script & { source: checkoutCode.output name: "test" } } } } Daggerの universe のyarnパッケージを使って、ビルドとテストのアクションを build に定義しました。以下のコマンドを実行すると、インストール、ビルド、テストのアクションが順番に実行されます。 $ dagger do build 以下のログが表示され、ビルドおよびテストが完了しました。 Jestのエラー test を actions の中で直接に宣言しテストを動かすと、 jest の以下のエラーが発生しました。 Field Value logs """\n yarn run v1.22.17\n $ jest --maxWorkers=1\n jest-haste-map: Haste module naming collision: test\n The following files share their name; please adjust your hasteImpl:\n * <rootDir>/cue.mod/pkg/universe.dagger.io/yarn/test/data/foo/package.json\n * <rootDir>/cue.mod/pkg/universe.dagger.io/yarn/test/data/bar/package.json\n\n Done in 6.81s.\n\n """ jest.config.js に以下の設定を追加するとこのエラーを解消できました。 //jest.config.js const customJestConfig = { modulePathIgnorePatterns: ["<rootDir>/cue.mod"], }; ローカルでアプリケーションを動かしてみた Next.jsでは next dev のコマンドを実行することで、開発モードでアプリケーションをローカルで起動できます。daggerを利用する場合は、 actions に以下のコードを追加します。 //dagger.cue dagger.#Plan & { actions: { checkoutCode: core.#Source & { path: "." } dev: yarn.#Script & { source: checkoutCode.output name: "dev" } } } dagger do dev コマンドを実行すると、 localhost:3000 でアプリケーションを確認できます。 ただし、daggerの全ての動作はDockerコンテナ上で実行されるため、コードを変更したら dagger do dev を再実行(つまりコンテナを更新)しないと反映されません。 universe パッケージのyarnと bash Daggerで yarn のアクションを実行する際に、 universe パッケージの universe.dagger.io/yarn 以外にも、 universe.dagger.io/bash を利用して シェルスクリプト で実行できます。 例えば、インストール、ビルド、テストを順番に実行させたい場合は以下の actions を宣言します。 //dagger.cue package main import ( "dagger.io/dagger" "dagger.io/dagger/core" "universe.dagger.io/bash" ) dagger.#Plan & { actions: { checkoutCode: core.#Source & { path: "." } build: { //yarnとbashがインストールされたイメージをpullする pull: docker.#Pull & { source: "node:lts" } //コンテナのfilesystemにファイルをコピーする copy: docker.#Copy & { input: pull.output contents: checkoutCode.output } //コンテナでbashスクリプトを実行する build: bash.#Run & { input: copy.output script: contents: """ yarn install --frozen-lockfile yarn run build yarn run test """ } } } } ただし、 bash は yarn より実行時間が長いです。ローカルでくインストール、ビルド、テストのアクションを行してみた結果、 yarn の実行時間は bash より1分以上も早くなります。 bash 1分35秒 yarn 13秒 bash と yarn 両方が使えるようでしたら、より実行時間の短い yarn を利用したほうがよさそうですね。 npm を利用したい場合は、 yarn のような直接に使える公式パッケージが実装されていないので、 bash を使います。 詳細は公式の サンプル を参照してください。 既存のDockerfileの実行もできる 以下のように、 unverse の docker パッケージを利用すれば、外部のDockerfileを読み込んで実行できます。 またDockerfileの内容を docker.#Dockerfile & {} にも記述できます。詳細は こちら をご参照ください。 //dagger.cue package main import ( "dagger.io/dagger" "dagger.io/dagger/core" "universe.dagger.io/docker" ) dagger.#Plan & { actions: { checkoutCode: core.#Source & { path: "." } build: docker.#Dockerfile & { source: checkoutCode.output } } } GitHub ActionsでDaggerを実行してみた ルート ディレクト リで .github/workflows フォルダを作成し、以下のように yaml ファイルに GitHub Actionsの設定を記述します。pushをトリガーに GitHub Actionsを走らせ、アプリケーションのビルドおよびテストを実行させます。 //build-test-on-push.yml on: push: name: Build and Test on Push jobs: build-and-test: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Build and Test uses: dagger/dagger-for-github@v3 with: cmds: | project update do build dagger/dagger-for-github を利用して、 dagger.cue に定義されたアクションを GitHub Actions上で簡単に動かせます。 従来であれば、 GitHub Actions上にNode.jsをインストールして、 yarn install やビルド、テストそれぞれの設定をしないといけないです。Daggerを利用する場合は、既存のCUEファイルを GitHub Actions上に実行させればOKなので、 GitHub Actionsの yaml ファイルもだいぶスッキリします。 使ってみた感想 CI スクリプト をローカルと GitHub Actionsで同じように実行できるのは便利ですね。ローカルで通ったテストを GitHub Actionsで実行するとなぜか通らなくなった、みたいなことも回避できそうです。また、Daggerを使うと、 yaml ファイルで頑張ってCI スクリプト を書かなくていいので、 GitHub Actionsでの設定もだいぶ簡単になります。 今回は GitHub ActionsでDaggerを試してみましたが、他にもCircle CI、GitLab、Jenkinsなど多数のCIサービスに対応しています。サービス間の移行をより簡単に実現できるので、他のCIサービスでもDaggerを使ってみたいですね。 ただし、使いづらいところもあります。 GitHub Actionsなどの設定が簡単になりますが、CUE言語やDaggerのパッケージの使い方を理解しないとDaggerの利用が難しく感じます。また現時点で、Daggerの公式サイトにある universe パッケージに関するドキュメントはあまり詳しくなく、複雑なCI/CDを構築したい場合はコードを読んで試行錯誤を重ねる必要があるかもしれません。 まとめ この記事では、DaggerでNext.jsプロジェクトのCIを動かしてみたことについてまとめました。 Daggerを使って基盤に依存しないポータブルなCIを簡単に構築できます。みなさんも是非使ってみてください。 私たちは同じチームで働いてくれる仲間を探しています。今回のエントリで紹介したような仕事に興味のある方、ご応募お待ちしています。 ソリューションアーキテクト 執筆: @chen.xinying 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
アバター
こんにちはXI本部、AIトランスフォーメーションセンターの徳原光です 現在、私が所属しているAIトランスフォーメーションセンター(通称:AITC)では、新卒、中途問わず、データサイエンティストとして働いてくださる方を絶賛募集中です。 AITCwebサイト 採用情報ページ|AITCwebサイト 例年、AITCへの配属が内定する新卒向けデータサイエンティスト職採用を実施していますが、今年も実施します。詳しい情報が出ましたら、こちらのページでお知らせします。 といいつつ、「いきなりうちの部で働いてください!」と言われても、判断に困ると思うので、自分の働き方をアンケート形式でまとめてみました(同じアンケートを中途の方を含め数人の方に答えていただいているので、順次テックブログまたはAITC webサイトで公開していきます)。 担当されているプロジェクトについて教えてください 1つ目はデータ活用、データ活用・AI導入支援プロジェクトです。お客様は一般消費者向けの製品を開発しているメーカー企業で(おそらく読者の方もこの会社の製品を使ったことがあると思います)、社内にある顧客情報や受注データ、オプション部品情報などのデータを活用して、売上向上を図る施策を提案・実装しています。 企業内で溜まっているけど活用されていないデータを整理しながら、様々な部署に ヒアリ ングを実施します。そして、在庫管理、サービス向上、 マーケティング などの視点でデータ活用案を提示し、データ処理のための スクリプト の実装や 機械学習 モデルの構築などを行っています。 データ活用のための戦略を立てる部分から、実際に実現可能か検証(PoC)するための実装までを担う必要があり、提案した施策を実運用にこぎつけるにはいろいろな困難がありますが、その分学ぶことが多いプロジェクトだと思ってます。 2つ目は精密部品メーカーのお客様に対して実施している、製品検査支援AIシステムの開発です。製品の検査画像から欠陥の可能性がある部分を画像処理AIで検出することで、検査員の方の作業を軽減するシステムを開発しています。 こちらのシステムはすでにお客様の工場で稼働しているので、現在はよりビジネス的な価値を創出できるように検出精度を向上させるための試行錯誤(モデルの再学習や異常判定 アルゴリズム の改善)を行っています。 この他に、ISIDの1年目の方に向けて半年間実施される新人研修の運営や部署サイトの更新作業、部内で開発しているAIソフトウェアの マーケティング などを担当しています。 一日の流れについて教えてください 一週間の中で月曜日と金曜日は会議が多いです。月に2, 3回、お客様に対する進捗報告会を実施しています。AIを活用したプロジェクトではプロジェク実施前に結果が予想しにくく、コンセプト検証(PoC)という形で、プロジェクト実施中にお客様と実施事項を逐次検討する必要があります。 読書会や勉強会は毎期実施しています。AITC内の勉強会の他に、他部署の方と実施しているインフラや システム開発 に関する勉強会にも参加しています。勉強会はスキルの向上だけじゃなく、社内の交流の場にもなっていると思います。 作業が多めの日ではコーディングや資料作成を主に行っています。現在実施しているプロジェクトはお客様の企業内にある様々なデータ(発注情報や顧客情報)を活用してビジネス価値を生み出すという案件なので、モデルに入力するためのデータを準備するために、データクレンジングや複数テーブルのデータを結合するための前処理 スクリプト を実装しています。モブプロ形式で実装することもあり、データを扱うノウハウやテクニックを先輩から学ぶ(盗む)ことができます。 週に一度会社の同期のメンバーでフットサルをやっています。同期ど うしの つながりは他の会社と比較しても強いほうだと思っています。会社の同期とはプライベートでも頻繁に会いますし、仕事でも部署を超えたプロジェクトを実施する際は、部のメンバーレベルで話合う前に、相手の部に所属している同期と予め情報交換しておいたり、内容をすり合わせたりするので、ある意味一つの社内組織のように機能していると思います。 今の仕事に対して気に入っている点はなんですか? AITCの良いところは若い年次から能動的に挑戦できる環境があることに尽きると思っています。これは会社全体に言えることですが、大企業的に少しづつタスクを指示されながら徐々に裁量を増やすのではなく、ISIDでは個人の自発的な行動が最も重視されるので、最初から自主的に挑戦したい仕事に アサイ ンしてもらうことができます。 さらに、AITCが取り組んでいるAIプロジェクトは「こうすればうまくいく」という方法がないので、一人一人が若手、ベテラン関係なくどうすればプロジェクトを成功に導けるか考えて行動することが求められます。 私は最初からうまくいく方法を学ぶのではなく、どうすればうまくいくのか試行錯誤しながら、答えを出すためのスキルを学びたいと考えているので、ワクワクしながら仕事に取り組めています。 さらに、様々な業界でデータサイエンティストやMLエンジニアとして活躍してきた方と一緒に働いているので、自分だけでは太刀打ちできない課題に直面してもすぐにバックアップしていただける安心感もありますね。 逆に気に入ってない点はありますか? 他部との交流が少ないです。AITCが所属しているXI本部は クラウド 、 VR 、UX、構成管理など様々な分野のプロフェッショナルが集まった組織ですし、都市OSや SaaS 型のパッケージシステムの開発など魅力的なプロジェクトに携わっている方が多く在籍していますが、AITCの部として結束力が強いせいか、プロジェクトレベルでの協力関係はあまりないと感じています。 もちろん、プライベートや勉強会などでは交流する機会はありますが、他の事業部の人も含めて仕事を通して協力しあえる場面が増えるといいと思っています( シナジー を生み出す的な)。 最近は社内でデータ分析やAIモデル構築のスキルを身に着けたい人が増えてきているので、そのような他部署の方に少しづつAITCのプロジェクトに参加していただいています。さらに、これからはデータ以外のことを学ぶために自分が部署外のプロジェクトに参加してみたいですね。 就職活動(転職活動)の際に、自己のキャリアで最も重視したポイントはなんですか? なかなか 言語化 しにくい概念ですが、自分と価値観が似ている人がイキイキと働いている職場に行きたいなと考えていました。働くことの意義はお金を貰えることだけじゃないと就活生時代考えていましたし、今もそう思っています。 ただ、何を持ってやりがいや達成感を感じるかは人によって違うので、自分と同じような考え方をする人が楽しそうに働ける環境に身を置くことを重視していました。 実際に入ってみてどうでしたか? 日々の業務の中で、挑戦したいことや頑張りたいことがたくさんあるので、就活生時代の自分の見立ては間違ってなかったと思っています。 もちろんやりたい仕事ばかりじゃなくて、やる意味を見いだせないタスクもあります。そういうときは自分から声を上げてやり方を変えたり、そもそも実施するか検討できるので不満はないです。ただ、いろいろ考えたあげく結局やるしかないという結論に至ることも多いですが。 「自分と価値観が似ている人がイキイキと働いている」というのは確かにそうだったのですが、ISIDとして、AITCとしてこういう価値観であるべきというものが特にないので、いろんな価値観の人が自分らしく働ける環境だと思います。ただ、組織としてスタンダードがないので、初めて組む人と仕事をするときは、相手に合わせて自分も相手も活かすということをメンバー全員が個人レベルで行う必要があるなと感じていて、そこが今の自分の課題だと思っています。 今後の目標している キャリアパス について教えて下さい XI本部の他の部署を含め、AITCでは、 スペシャ リストとして、データサイエンティストやMLエンジニアのキャリアを突き詰めてい行きたいと考えている人が多いように思えますが、自分はIT全般に精通して、会社単位でITを用いてビジネス価値を創出するにはどういうすればいいのか、ビジネス全般を導けるような人材になりたいと考えています。 そのために最も大事なことがデータに精通することだと考えています。ITの力で実際に扱うことができるのは現実に存在する商品やサービスではなくデータだけです(IoT機器やロボットアームを制御すれば物体に直 接触 れるのは一応可能ですね)。 ですが、お客様のデータを触っていく中で、現実に存在する物体とデータは一対一の関係を持っていて、データを加工したり、新しい情報を生み出すことで、対応する商品やサービスにも影響を与えられる感覚をなんとなくですが理解した気がしています(多分気がしているだけです)。 正直今は自分の判断や仕事の質に自信が持てない状態ですが、この「現実とデータの関係」という概念を突き詰めていくことで、いつか自分はITを使ってビジネス価値を生み出すことをマクロな視点でとらえられるようになると自信をもって思っています。今の自分の立場はデータサイエンティストとしてズカズカとお客様の経営と現場両方向に浸食していけるので、日々必要な知識を吸収することができます。 最後に就活生or転職者の方に一言! おそらくですが、このテックブログではすでに、情報技術に精通している学生や転職者の方に向けたメッセージが多いと思うので、自分はあえてそもそもIT業界で働くか検討している段階の方に向けてメッセージを書きたいと思います。 私は学生時代から学校や研究室で情報っぽいことをやってましたし、就活時代もIT企業にこだわって就職活動を進めていました。ですが、周りに技術に対して情熱を燃やしながら向き合っている人に囲まれながら、最近はあまり特定の技術に対して執着しなくなってきました。自分の中ではあくまでITは手段であり、目的ではないと思っています(逆に周りにはITと無縁だった人で今は技術に熱心に取り組まれている方が多いですね)。 ただ、確実にいえることは、ISIDで取り扱っている情報技術、とりわけ自分が所属しているAITCが取り組んでいるデータサイエンスやAIの技術は現在世の中に存在するあらゆる業界、分野の中で最も強力な手法であるということです。 必ずしも、それ(IT)がやりたいわけじゃないけれど、自分が叶えたいことを実現するには確かに今向き合ているものが必要になるのです。なので、今の環境は自分の現時点のキャリアにとって最高とは言いませんが、いい環境だと思ってます。 そのためには、辛抱強く今ある現実の鏡としてのデータと向き合うことが大切だと思います。もちろん、やり方を変えたり、0から作り直すことも必要ですが、目の前にあるデータからできるだけ価値を絞り出すことが大事だと今は思っています。よく、就活イベントで就活生からITのスキルや知識は必要かと聞かれますが、一 番役 に立つのは忍耐力です。諦めなければスキルはあとからついてくると信じて仕事をしています。 ということで、むむっと思った方は気軽にお声掛けください。現在AITCwebサイト内にカジュアル面談用のフォームを作成していますので、下のフォームからご応募ください。データサイエンティスト職に関する面談はもちろん、ISIDの総合職に関する面談も可能です(適切な方にお繋ぎします)。 AITCデータサイエンティスト職カジュアル面談申し込みフォーム AITCwebサイトでは技術に関するコラムや日々の活動の記録を公開していますのでぜひ御覧ください 採用情報ページ|AITCwebサイト AITCコラム一覧 「2022年度 製品開発グループ夏合宿」を開催しました データサイエンティストの勉強会をご紹介! オンラインならではの工夫とは? それでは。 執筆: @tokuhara.hikaru 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
アバター