åŒç€Ÿã§ã¯æ¥åPCãšããŠããŒãPCãæ¯çµŠãããŸãããå€ä»ãããŒããŒããããŠã¹ãå©çšãããæ¹ã¯è¿œå æ¯çµŠããŠãããããšãã§ããŸããã§ããèªå奜ã¿ã®ããŒããŒãã»ããŠã¹ãå©çšãããæ¹ã¯ãå人ã®è²¬ä»»ã§æã¡èŸŒãã§å©çšããããšãèªããããŠããŸãã ãã®æµãã§ç§ã¯èªäœããããŒããŒããæ¥åPCã«æ¥ç¶ããŠäœ¿ã£ãŠããŸããããã®ããŒããŒããäœæããéã®ç¥èŠãå°ããŸãšããŸããã èªäœããŒããŒãã§äœ¿ããœãããŠã§ã¢ã«ã€ã㊠ç§ã¯èªäœããŒããŒãã§ qmk_firmware ïŒQuantum Mechanical KeyboardïŒãšãããªãŒãã³ãœãŒã¹ã®ãã¡ãŒã ãŠã§ã¢ãšãã®æŽŸçç©ã䜿ã£ãŠããŸãã qmkã®ããŒå
¥ååŠçã倧ãŸãã«ä¿¯ç°ãããšã以äžã®ãããªæµãã«ãªããŸã ãŸã倧å
ã«ãªãã¡ã€ã³ã«ãŒãããããŸãã ããããåŒã³åºãã颿°ã§ããŒã¹ã€ããã®ãããªã¯ã¹ã確èªããŸãã åå確èªããç¶æ
ãããããªã¯ã¹ã«å€åãããã°ãããããã®å€æŽç¹ã«ã€ããŠactionãçºè¡ããŠãã¥ãŒã«ç©ã¿ãŸãã æåŸã«USBããŒã¿ãéä¿¡ããŸãã ãããªã¯ã¹ã確èªããŠactionãçºè¡ããéã«èªäœããŒããŒãç¹æã®TapDanceïŒ1ã€ã®ããŒã«è€æ°ã®æ©èœãå²ãåœãŠãæ©èœïŒãComboïŒè€æ°ã®ããŒã®çµã¿åããã§ç¹å®ã®æ©èœãåŒã³åºãæ©èœïŒãªã©ã®äŸ¿å©æ©èœã«å±éããããã§ãã ããŒã®å
¥åãããªã¯ã¹ qmkã¯Cèšèªã§èšè¿°ãããäžèšãããªã¯ã¹ã®ç¶æ
ã¯ã°ããŒãã«é
å倿°ã«ãªã£ãŠããŸããã ãšããããšã¯ãåãããã°ã©ã ã®äžãªãå¥ã®ãœãŒã¹ãã¡ã€ã«ãããåç
§ããããšãã§ããŸãã ããŒããããåç
§ããã«ã¯ãkeymap.cãã¡ã€ã«ãªã©ã§ä»¥äžã®å®£èšãããŸãã extern matrix_row_t raw_matrix[MATRIX_ROWS]; ããã§ãããªã¯ã¹ãåç
§ã§ããããã«ãªãã®ã§ãããŒã¿ããã®ãŸãŸOLEDïŒææ©ELãã£ã¹ãã¬ã€ïŒã®è¡šç€ºé¢æ° oled_write_raw_P() ã«æž¡ãããšã§ããŸã°ããªç¹ã®éãŸãã§ããããŒã®å
¥åç¶æ
ã確èªã§ããããã«ãªããŸããã oled_write_raw_P((char*)raw_matrix, sizeof(raw_matrix)); åŠçäžã®ããŒã¿ãçŽæ¥ãªã¢ã«ã¿ã€ã ã§ç¢ºèªã§ããOLEDã¯ããããã°ããã©ãã«èª¿æ»ã§éåžžã«äŸ¿å©ã§ããïŒç»åã§ã¯æãã«ç¹ã䞊ãã§ããŸããããã®ç¹ã¯ç·åœãããããªã¯ã¹ã®colãšrowãç¹ããã€ãªãŒãã®åœ±é¿ã§ããïŒ ããŒã¹ã€ãã以å€ã®ããŒå
¥åææ®µ æåã«ã話ãããããŒã¹ãã£ã³ã®æµããããé©åãªãã©ã€ããç¡ãããã€ã¹ããæ¢åã®ãã©ã€ããšæåãå€ããããšãã«ã¯ã以äžã®æ¹æ³ããããŸã ãŠãŒã¶ã®æäœã§on/offãæå³çã«æäœãããããŒãªããŒããçºçãããå Žåã«ã¯ãaction_exec() ã§onãšoffãéœåºŠçºè¡ããŸãã åçºã®ããŒå
¥åãã§ããã°ããå Žåã«ã¯ãon/offãã»ããã§çºè¡ããŠããã tap_code_delay() ã䜿ããŸããããã«ãããç¬éçãªããŒã¯ãæãã€ã€å
¥åã«å¿
èŠãªæéééã§onãšoffãçºè¡ããŠãããŸãã ãã€ãããã¯ããŒãããå€æŽ èªäœããŒããŒãã調ã¹ãŠåããšããã¡ãŒã ãŠã§ã¢ããã«ãããéã«ããŒãšå
¥åãããããŒã³ãŒãã®å¯Ÿå¿ã決å®ããã ãã§ãªã via, remap, vialãªã©ã®ããŒã«ã䜿ã£ãŠããŒããããåçã«å€æŽã§ããããã«ããŠããããšãæ±ããããŠããããã§ãã ãããã®ããŒã«ã¯åºæ¬çã«ä»¥äžã®æ¹æ³ã§åäœããŸã ããŒãããªã¯ã¹ã®ç¯å²ã§ç¢ºä¿ãããé
åãçšæããŸãã ãããªã¯ã¹ã®rowïŒè¡ïŒãšcolïŒåïŒã®äº€ç¹ãçµã³ã€ãã衚ãäœæããŸãã PCããRAW HIDã®æé ã§æžãæãæç€ºãåãåã äžèšã®è¡šãæžãæããããšã§ããŒãããã倿ŽããŸãã ããŒã«ã䜿ã£ãå Žåã§ããããªã¯ã¹ã®äº€ç¹äœçœ®ãåçã«å€æŽããããšã¯ç¡ããããããŒããŒãããšã«äžè²«ããåºæã®ãã®ã決ããŠãããã©ã®ããã«å©çšãããã工倫ãããšããããã¡ãŒã äœæã®ééå³ãšæããŠããŸãã æªå®è£
ã¹ã€ãããšãããªã¯ã¹ã¹ãã£ã³ ãããªã¯ã¹ã®ãªãã§ã¹ã€ãããå®è£
ããŠããªãã ãã§ããã°æªåœ±é¿ã®å¯èœæ§ã¯äœãã§ãããrowãšcolãå
±çšããŠãã€ãªãŒãã§æå³ãèªã¿æ¿ãã圢ã®ç·åœãããããªã¯ã¹ïŒæ¹è¯äºä¹ãããªã¯ã¹ãªã©ä»ã®åŒã³æ¹ããããŸãïŒã䜿ãéãrow=colã®äœçœ®ã¯èªã¿é£ã°ãå¿
èŠããããããã#define MATRIX_MASKEDããèšå®ããŸãã MATRIX_MASKEDã«ã€ããŠã¯ããã¯èª€è§£ããŠããã®ã§ãããã¹ãã£ã³ãææ¢ããã®ã§ã¯ãªãã¹ãã£ã³ã®çµæå
¥åãããŠããŠãç¡èŠããæåãšãªã£ãŠãããŸããããã¯æéçå¶çŽãå³ããGPIOæäœåšèŸºã®ã³ãŒããã·ã³ãã«ã«ä¿ã¡ã€ã€ãå¹çãé«ããããã§ã¯ãªãããšèããŸãã ãã®æåã¯quantum/matrix.cã® matrix_scan() ã®ã¹ãã£ã³éšåãšãquantum/matrix_common.cã® matrix_get_row() ã§ã¹ãã£ã³çµæããã¹ã¯ããŠè¿çããããšãã確èªã§ããŸãã å
¥åãããããŒãç¡å¹ãšããŠæ±ãæ¹æ³ã¯ä»¥äžã®ãããªæ¹æ³ããããŸãããèšç®éãèæ
®ãããšMATRIX_MASKEDã軜éã§æé©ã§ã MATRIX_MASKEDã䜿çšãã process_record_user()ã§çºçããããŒã³ãŒããåŠå®ãã process_record_user()ã§matrix[]é
åãçŽæ¥æäœãã ãŸãããã¹ã¯ãããäœçœ®ãèªã¿åºãã§ç¡å¹åããã®ã¿ã§ä»ã®ç®æã§å€å®ããªãçŸåšã®å®è£
ã¯ãæªå®è£
ã¹ã€ãããä»ã®ã¹ã€ããããã€ã¹ã®å
¥åã«è»¢çšããããšãããããããªã£ãŠããŸããããã®è©±ã¯ãŸãå¥ã®æ©äŒã«ã話ããããŠããã ããããšæããŸãã ãããã« èªäœããŒããŒãã®ãã¡ãŒã ãŠã§ã¢ã¯ãœãããŠã§ã¢ãšé»ååè·¯ãæ©æ¢°çãªäºæãŸã§å¹
åºãç¥èã身ã«çããããã®ã§ãœãããŠã§ã¢ãšã³ãžãã¢ãšããŠå¹
ãåºããã«ã¯ãã課é¡ã§ã¯ãªãã§ããããã ããŒããŒããšèšãæ¯æ¥äœ¿ãããã€ã¹ã§ãã®ã§ã掻åã®çµæãQOLã«çŽçµããç¹ãçŽ æŽããããšæããŸãã ãã®èšäºã§èå³ãæã£ãŠäžäººã§ãå€ãã®ä»²éãçŸããããšãæåŸ
ããŠããŸãã
ã¯ããã« ããã«ã¡ã¯ããããã£æ ªåŒäŒç€Ÿã®å³¶ç°ã§ãã ä»åã¯GitHub Actionsã¹ããŒã¿ã¹ã®ãã£ããããããžãREADMEã«åºãæ¹æ³ã«ã€ããŠç޹ä»ããŸãã â»ãã¡ãã®èšäºã¯ç€Ÿå
ã®ã¬ããŒãDBãã転èŒããèšäºã§ã ããã¯äœïŒ READMEã«ãããããã£ãããã¹ããŒã¿ã¹ãããžãã€ããããããã«ãªããŸãã GitHub Actionsã®ã¹ããŒã¿ã¹ã衚瀺ãã å®ã¯ããããšãŠãç°¡åã§ãã GitHub Actionsã®ã¯ãŒã¯ãããŒèšå®ç»é¢ããããCreate status badgeããæŒãã°ãªã³ã¯ãåããŸãã®ã§ããããREADME.mdã«è²Œãã ãã§ãã ãããªé¢šã«ãããšãããžãã¯ãªãã¯ããéã®ãªã³ã¯å
ããç»åã§ã¯ãªãã¯ãŒã¯ãããŒã®è©³çްããŒãžã«ãªã£ãŠå¬ããã§ãã [](<https://github.com/${repository}/actions/workflows/CI-Master.yaml>) èªäœã®ã¹ããŒã¿ã¹ãåºã(Coverageãšã) ãããž shields.ioãšãããµãŒãã¹ãå©çšãããšã奜ããªæ
å ±ããããžã«ã§ããŸãã 以äžã®ãããªåœ¢åŒã®urlãäœããšããæãã®svgãåããŸãã <https://img.shields.io/badge/go%20report-A+-brightgreen.svg?style=flat&logo=go> ãªããšãªã以äžã¿ãããªæãã§ãã ãã¡ããurlãšã³ã³ãŒãã¯å¿
èŠã§ã: https://shields.io/badges <https://img.shields.io/badge/${title}-${status}-${color}.svg?style=flat&logo=${logo}> Shell script ãããžãçµã¿ç«ãŠãããã«è²ã
ããŸãã äŸãã°ãããªæãã§ãã grade=$1 case $grade in A+) curl -o go-report.svg "https://img.shields.io/badge/go%20report-A+-brightgreen.svg?style=flat&logo=go" ;; A) curl -o go-report.svg "https://img.shields.io/badge/go%20report-A-green.svg?style=flat&logo=go" ;; B) curl -o go-report.svg "https://img.shields.io/badge/go%20report-B-yellowgreen.svg?style=flat&logo=go" ;; C) curl -o go-report.svg "https://img.shields.io/badge/go%20report-C-yellow.svg?style=flat&logo=go" ;; D) curl -o go-report.svg "https://img.shields.io/badge/go%20report-D-orange.svg?style=flat&logo=go" ;; E) curl -o go-report.svg "https://img.shields.io/badge/go%20report-E-red.svg?style=flat&logo=go" ;; F) curl -o go-report.svg "https://img.shields.io/badge/go%20report-F-red.svg?style=flat&logo=go" ;; *) exit 1 ;; esac Actions ãããèã§ãã é©åœã«curlãšãã§svgãã¡ã€ã«ãåºåããããã«ããŸãã svgãã¡ã€ã«ã®ã¿ãaddããŠpushå
ãmasterã§ãªããã©ã³ãã«ããŸãã ããã¯ãsvgã®ã¿ãcommitããããšããçç±ãšãmasterã«pushãããšåžžã«ç»åã®å·®åãåºãŠããŸãã®ãé¿ããããã§ãã name: badge on: push: branches: [ master ] jobs: goreportcard: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 with: go-version-file: go.mod cache: true - name: Setup goreportcard run: | mkdir /tmp/goreportcard cd $_ git clone https://github.com/gojp/goreportcard.git cd goreportcard make install go install ./cmd/goreportcard-cli - name: Generate go-report.svg run: | goreportcard-cli /bin/bash grade.sh `goreportcard-cli -j | jq -r ".GradeFromPercentage"` - name: Generate coverage.svg run: | go test ./internal/... -covermode=count -coverprofile=coverage.out fmt go tool cover -func=coverage.out -o=coverage.out cat coverage.out rate=$([[ `grep "total:" coverage.out` =~ [0-9]+.[0-9]%$ ]] && echo $BASH_REMATCH | cut -d% -f1) /bin/bash coverage.sh $rate - name: Push run: | git config user.name "bot" git config user.email "bot@example.com" git add go-report.svg coverage.svg git commit -m "generated" git push -f -u origin master:badge README.md README.mdã§ããããžãçæã»ç®¡çããŠãããã©ã³ãã®SVGç»åãåç
§ããããã«èšè¿°ããŸãã [](<https://github.com/${repository}/actions/workflows/badge.yaml>) ã ããããããªæãã§ãã [](<https://github.com/${repository}/actions/workflows/${workflow}>) ãããã« ä»åã¯GitHub Actionsã¹ããŒã¿ã¹ã®ãã£ããããããžãREADMEã«åºãæ¹æ³ã«ã€ããŠç޹ä»ããŸããã GitHub Actionsã®ã¹ããŒã¿ã¹ã®ãããžãã€ããŠã¿ããæ¹ã¯ãã²äœ¿ã£ãŠã¿ãŠãã ããã åè https://shields.io/ https://qiita.com/ma91n/items/6c572c5887a50223c2b1
ãã®èšäºã¯ããªã¬ãŒããã°äŒç»ãCI/CDãªã¬ãŒããã°ãã®èšäºã§ãã ã¯ããã« åããŸããŠïŒ ã〠ãããã£ããŒã ã®å¯ºå³¶ã§ãã æ®æ®µã¯ã¹ããŒããã©ã³åãã®ã¢ããªã±ãŒã·ã§ã³éçºã«æºãã£ãŠããŸãã ããã°éå¶ããŒã ã®ã¡ã³ããŒã§ããããŸãïŒ ä»åã¯ãªã¬ãŒããã°ã®ã¢ã³ã«ãŒãšããŠãããã°ããŒã 代衚ãšããŠèµ°ãããŠããã ããŸãïŒ CI/CDã®ãªã¬ãŒããã°ãçãäžãããšãã倧ããªãç®çã®ããã«ãåã
ããæ°ã«ã¯ãªã£ãŠããã®ã ããã©äžã
éãè
°ãäžããããªãã£ããXcode Cloudã®CI/CDãäœéšããŠãããããã°ã«ããŠã¿ãŸããïŒ äžç³äºé³¥ã§ããïŒïŒ ããããXcode Cloudãšã¯ XcodeãšåŒã°ããApple補ã®IDEãå©çšããŠãCI/CDãç°¡åã«è¡ããããã«ãããµãŒãã¹ãä»çµã¿ã®ããšã§ãã Xcode Cloudã¯ãXcodeã«çµã¿èŸŒãŸããç¶ç¶çã€ã³ãã°ã¬ãŒã·ã§ã³ããã³ããªããªãŒãµãŒãã¹ã§ãAppleãããããã®ããã«èšèšããããã®ã§ããã¢ããªã®ãã«ããè€æ°ã®èªåãã¹ãã®äžŠåå®è¡ããã¹ã¿ãŒãžã®ã¢ããªã®é
ä¿¡ããŠãŒã¶ãŒãã£ãŒãããã¯ã®è¡šç€ºãšç®¡çã«åœ¹ç«ã€ãã¯ã©ãŠãããŒã¹ã®ããŒã«ãäžãæã§å©çšã§ãããããé«å質ãªã¢ããªã®éçºãšé
ä¿¡ãé«éåãããŸãã https://developer.apple.com/jp/xcode-cloud/ ç®æã圢 TestFlightã®å
¬éãŸã§ç®æããŸãïŒ ã³ãŒã倿Žâmainãžåæ âåæ ã®æ€ç¥âãã¹ãã®å®è¡âTestFlightå
¬é ã®æµãã«ããããšæããŸãã ä»åã¯ãiOSã¢ããªã§ç¢ºèªããããšæããŸãã åææ¡ä»¶ GitHubãå©çšããŸã ãã©ã³ãã¯mainãã©ã³ãã®ã¿ãå©çšããŸã Xcode Cloudãå©çšããŸã Apple Developer Programã«åå ããã¢ã«ãŠã³ããå©çšããŸã iOSã¢ããªã®äœæã確èªããŸã äºåæºå æ°ãããããžã§ã¯ã(iOSã¢ããªçš)ãç«ã¡äžããŸãã GitHubã®ãªããžããªãæ°èŠã«çšæããŸãã ç°¡åãªè¡šç€ºãè¡ãViewãšã衚瀺ã«äœ¿çšããã¡ãœããã®ãã¹ããäœæããŸãã äœæããã³ãŒãã¯çšæãããªã¢ãŒããªããžããªã«PushããŸãã ååã¯ããªããžããªã®çŽä»ããè¡ããšWorkflowãå®è¡ããBuildãããŸãã åå以éã¯ãmainãã©ã³ãã®å€æŽãæ€ç¥oræåã§Workflowãå®è¡ãããããã«ãªããŸãã ãã£ã¬ã¯ããªæ§æ(å®æç³»ã€ã¡ãŒãž) ãã¡ãã¯ãããŸã§ã€ã¡ãŒãžãšãªããŸãã Xcodeäžã§è¡šç€ºããããã¡ã€ã«ãšåããã圢ã«ãªããŸãã ãŸãInfo.plistã¯èšå®ãå
¥ããŠããªããšè¡šç€ºãããªãã®ã§ããããžã§ã¯ãç«ã¡äžãæã«ãªããŠãåé¡ãããŸããã åŸã®æé ã§èšå®ãè¡ããšåºãŠããŸãã . âââ SampleProject006 â âââ Info.plist â âââ Preview Content â âââ Assets.xcassets â âââ ContentView.swift â âââ SampleProject006App.swift âââ SampleProject006Tests âââ SampleProject006Tests.swift å©çšã³ãŒã ContentView helloã¡ãœããã®æ»ãå€ãTextã§Viewã«è¡šç€ºããããã«ããŠããŸãã import SwiftUI struct ContentView: View { var body: some View { VStack { Text(hello()) } } } func hello() -> String { return "Hello, Swift!" } #Preview { ContentView() } SampleProject006Tests helloã¡ãœããã®æ»ãå€ã Hello, Swift! ã§ããããšã確èªãããã¹ãã§ãã import Testing struct SampleProject006Tests { @Test("äžèŽããããšããã¹ã") func match() { #expect(hello() == "Hello, Swift!") } } GitHubãžåæ ä»åã¯mainããã®ãŸãŸå€æŽâPushãã圢ã§ç¢ºèªããŸãã ãªã¢ãŒããã©ã³ããžæ°ãããããžã§ã¯ããPushããŠãããŸãã Xcode Cloudã詊ããŠã¿ã Xcode Cloudããªã¢ãŒããªããžããªãžçŽã¥ãã Buildã確èªãã Xcodeãšãªããžããªã®çŽä»ã XcodeããXcode Cloudãå©çšããããããžã§ã¯ããéžæããŸã Workflowã¯ããã©ã«ãèšå®ã®ãŸãŸã«ããŸã å©çšããŠããéçºè
ã¢ã«ãŠã³ããXcode Cloudãå©çšã§ããããã«ããŸã éçºè
ã¢ã«ãŠã³ããšGitHubã®çµç¹ãçŽã¥ããŸã çŽã¥ããçµç¹å
ã®ãªããžããªãšé£æºããŸã Xcodeã®ãµã€ãããŒãããGet Started…ããéžæããŸãã æ°ãããŠã£ã³ããŠãç«ã¡äžããã®ã§ãããã¯ããéžæãããNextããéžæããŸãã Workflowã®è©³çްèšå®ã«ã€ããŠã®é
ç®ãéžæã§ãããŠã£ã³ããŠã衚瀺ãããŸãããä»åãã¡ãã¯ããã©ã«ãã®ãŸãŸå
ã«é²ããŸãã(åŸã»ã©webäžã§èšå®ãè¡ããŸãã) ãNextããéžæããŸãã ããã§ãªããžããªãéžæãããŠã£ã³ããŠã衚瀺ãããŸãã ãGrant Access…ããéžæããŸãã(次ããXcode以å€ã§ã®èšå®ã«ãªããŸãã) èªåã§ãã©ãŠã¶ãç«ã¡äžãã£ãŠããŸãã ãŸãã¯App Store Connectãžãã°ã€ã³ããŸãã Xcode CloudãGitHubã«æ¥ç¶ããç»é¢ã衚瀺ãããŸãã ãããããå
·äœçãªã¢ã«ãŠã³ããžGitHubãžã®æ¥ç¶ã®èš±å¯ãšããªããžããªã®çŽä»ããè¡ãªã£ãŠãããŸãã ãGitHubã§ã¹ããã1ãçµäºããããéžæããŸãã ä»åºŠã¯GitHubã®ããŒãžãéããŸãã Xcodeãã€ã³ã¹ããŒã«ãããçµç¹ãéžæããŸãã ããã§éžæããã®ã¯ãå
ã»ã©äœæãããªããžããªã®æå±ããçµç¹ã§ãã ããã«ããªããžããªãéžæããŸãã ãAll repositoriesãã§ãã¹ãŠã®ãªããžããªãžã®ã¢ã¯ã»ã¹ãèš±å¯ãããããOnly select repositoriesãã§ç¹å®ã®ãªããžããªã®ã¿ã«æš©éãäžããããéžæããŸãã ä»åã¯ãAllã§äžããçç±ãç¹ã«ãªãã®ã§å
ã»ã©çšæãããªããžããªã®ã¿ã«èš±å¯ãäžããŸãã éžæããããInstallããå®è¡ããŸãã ãInstallãéžæåŸãæ£åžžã«æ¥ç¶ãããŸãããšè¡šç€ºãããå®äºã§ãã Xcodeã«æ»ã£ãŠãå
ã»ã©çŽä»ããè¡ã£ããªããžããªã«ç·ã®ãã§ãã¯ããŒã¯ãå
¥ã£ãŠããããšã確èªã§ããŸãã ã¢ããªãäžåºŠãApp Store Connectãžé£æºããŠããªããšãååã«äœæã確èªãããã€ã¢ãã°ã衚瀺ãããŸãã äœæããªããšXcode Cloudã¯å©çšã§ããªãã®ã§ããCompleteãã§äœæãèš±å¯ããŸãã æåŸã«ããStart Buildãã§å®äºã§ãïŒ ããã§ãXcode Cloudäžã§Buildãèµ°ããŸãã ä»åã¯ç¹ã«Workflowãèšå®ããŠããªãã®ã§ãã·ã³ãã«ãªBuildãå®è¡ãããŠçµäºããŸãã App Store Connectã§ç¢ºèªãããšäžèšã®ãããªç»é¢ã«ãªããŸãã ã¹ããŒã¿ã¹ã«ç·ã®ãã§ãã¯ããŒã¯ãå
¥ã£ãŠããã°ç¡äºã«Buildå®äºã§ãã Xcode CloudãšGitHubã®ãªããžããªãæ£ãã飿ºã§ããŠããŸãã Xcode Cloudã®èšå®ãå€ããŠè©ŠããŠã¿ã ç¡äºã«é£æºã§ããã®ã§ãè²ã
詊ããŠã¿ãããšæããŸãã TestFlightãžèªåã§å
¬éããããã«èšå®ã倿ŽããŸã Buildæã«ãã¹ããå®è¡ããããã«èšå®ã倿ŽããŸã ãã¹ãã®é
ç®ãå¢ãããŸã 倿Žå
容ãmainãžpushããŸã å®è¡å
容ã確èªããŸã TestFlightãžã®å
¬éã倱æããŠããã®ã§ãä¿®æ£ããŠå床BuildããŸã å®è¡å
容ã確èªããŸã App Store Connectã®Xcode Cloudã¿ãã®ãµã€ãããŒãããã¯ãŒã¯ãããŒã®ç®¡çããéžæããŸãã ä»åäœæããã¯ãŒã¯ãããŒã§ãããDefaultããéžæããŸãã Defaultã¯ãŒã¯ãããŒã®èšå®ããŒãžãžé·ç§»ããã®ã§ãã¢ã¯ã·ã§ã³ã»ã¯ã·ã§ã³ã®äžããã¢ãŒã«ã€ãé
ç®ãéžæããŸãã ããã©ã«ãã§ã¯é
ä¿¡æºåãããªããã«èšå®ãããŠããŸãã®ã§ãä»åã®ç®æšã§ãããTestFlight(å
éšãã¹ãã®ã¿)ããéžæããŸãã ç¶ããŠãã¹ãã®å®è¡ã远å ããŸãã ã¢ã¯ã·ã§ã³ã»ã¯ã·ã§ã³ã®ã¿ã€ãã«ã®æšªã«ãããïŒãããŒã¯ãã¯ãªãã¯ããŠããã¹ãããéžæããŸãã æ°ããããã¹ãã«å¯Ÿããå
¥åæ¬ã远å ãããã®ã§å¿
èŠé
ç®ãå
¥åããŠãããŸãã äžèšã®ç»åã®ããã«ãªãããã«ããŸãã åºæ¬çã«ã¯ãæåã«äœæãããã¹ãã«ã€ããŠé©çšããŠãã圢ã«ãªããŸãã ãã¹ãã³ãŒãã远å ããŸãã helloã¡ãœããã®è¿ãå€ãäžèŽããªãããšã確èªãããã¹ãã远å ããŸãã @Test("äžèŽããªãããšããã¹ã") func doesNotMatch() { #expect(hello() != "Hello, World!") } 倿ŽãcommitããŠmainãã©ã³ããpushããŸãã mainãã©ã³ã以å€ã§äœæ¥ããŠããå Žåã¯ãmainãã©ã³ããžmargeããŸãã mainãæŽæ°ããããšWorkflowãå®è¡ãããŠãå
ã»ã©è¿œå ãããTestFlightããžã®å
¬éãšããã¹ãã®å®è¡ããè¡ãããŸãã ä»åã¯å€±æããŸãã 倱æã®åå ã確èªããŸãã ã¹ããŒã¿ã¹ã®èµ€äžžããå°ããŒã¯ãã¯ãªãã¯ãããšè©³çްããŒãžãžãšé·ç§»ããŸãã å
ã»ã©è¿œå ãããã¹ãã¯åé¡ãªãå®è¡ãå®äºããŠããã§ãã Archiveã§ãšã©ãŒãåºãŠããã¿ãããªã®ã§ããArchive – iOSããã¯ãªãã¯ããŠäžèº«ã確èªããŸãã äžèº«ã確èªãããšè©³çްãªãšã©ãŒå
容ã衚瀺ãããŸãã ä»åã¯ãTestFlightã«å
¬éãè¡ãã®ã«ã¢ããªã±ãŒã·ã§ã³ã«ã¢ã€ã³ã³ãèšå®ããŠããªãã®ãåå ã®ããã§ãã AssetsããApplconã远å ããŸãã å床ã倿Žããªã¢ãŒããªããžããªã®mainãã©ã³ãã«åæ ãããšWorkflowãå®è¡ãããŸãã ä»åºŠã¯æåããããšã確èªã§ããŸãã ã§ãã… TestFlightãžã®å
¬éã¯è¡ãããŠããªãããã§ãã ã¢ããªã®æå·åæžé¡ã«ã€ããŠãäºãéžæããŠããªããšå
¬éãŸã§ã¯é²ã¿ãŸããã ä»åã¯ãç¬èªã®ã¢ã«ãŽãªãºã ã§æå·åãè¡ã£ãŠããªãã®ã§ãInfo.listã«èšå®ã远å ããŠãTestFlightãŸã§å
¬éãããããã«ããŸãã App Uses Non-Exempt Encryption ã远å ããŠãå€ããNOãã«ããŸãã 倿Žããªããžããªã®mainãžåæ ããŸãã Defaultã®Workflowã確èªããŠã¿ããšãBuildã¯æåããŠããŸãã TestFlightã®æ¹ãèŠãŠã¿ããšãå
¬éãŸã§ãããŠããããšã確èªã§ããŸãã ããã㫠以äžã§ãXcode Cloudã®åºæ¬çãªåäœã®äœéšã¯çµããã«ãªããŸãã ãä»ãåãããã ãããããšãããããŸããã å
šãŠã®CI/CDèšå®ãGUIã§å®äºããã®ã¯åããããããšãŠãè¯ããšæããŸããã ä»åã®äœéšãåºã«è€éãªåŠçãªã©è¿œå ããŠãCI/CDããã䜿ããããã«ã¹ã¿ãã€ãºããŠãã¢ããªéçºã®å¹çãäžããŠããããã§ããã(顿) ãªã¬ãŒããã°äŒç»ãCI/CDãªã¬ãŒããã°ãã¯ããã®èšäºã§çµäºãšãªããŸããå·çã«ååããŠããã ããçãããèŠãŠãã ãã£ãçãããããããšãããããŸããã
ãã®èšäºã¯ããªã¬ãŒããã°äŒç»ãCI/CDãã®èšäºã§ãã ã¯ããã« ãã¯ããããããŸããIWSã§ãã ä»åã¯ãCI/CDãªã¬ãŒããã°ããšããããšã§ç§ã®ããŒã ã§äœ¿ãããŠãã GitHub Actions ã䜿ã£ãéçºç°å¢ãžã®CDã玹ä»ããããšæããŸãã ã€ã¡ãŒãž ãã®æ§æã®Webã¢ããªã«å¯ŸããŠCDãã GitHub Actions WF ãäœæããŸããECR ã«ããã€ã¡ãŒãžã䜿ã£ãŠECS ã¿ã¹ã¯ãåããŠããããããæ§æã§ããã ãã®æ§æã«å¯ŸããŠãdevelopãã©ã³ãã«mergeããããšããGitHub Actionsã®ããŒãžãã奜ããªãã©ã³ããæå®ããŠéçºç°å¢ã«ãããã€ã§ããããã«ãªãã®ããŽãŒã«ã§ãã IAM Role ã®çšæ WFãäœæããåã«ããŸãã¯AWSã®ãªãœãŒã¹ãæäœããããã®æš©éåšãã®æºåãããŸãã IAM Userã§ã¢ã¯ã»ã¹ããŒãååŸããŠäœ¿ãæ¹æ³ããããŸãããIAM Role ã䜿ãã°äžæçãªã¯ã¬ãã³ã·ã£ã«ãçºè¡ããããšãã§ãã»ãã¥ãªãã£çã«ã管çã®ããããçã«ã楜ã«ãªãã®ã§ãã¡ããããããã§ãã ID ãããã€ãã®äœæ IAM ã® IDãããã€ã ã®ããŒãžããäœæããŠãããŸãã èšå®å
容ã«ã€ããŠã¯ GitHub Docs ã«ãæžãããŠããŸãã以äžã®ããã«èšå®ããŠããã°OKã§ãã ãããã€ãã®ã¿ã€ã OpenID Connect ãããã€ãã®URL https://token.actions.githubusercontent.com 察象è
sts.amazonaws.com IAM Role ãš Policy ã®äœæ PolicyãæºåããŸãã æäœããããªãœãŒã¹ã«åãããŠActionã®å
容ã¯å€æŽããŠãã ããã ä»åã¯ECSã®æŽæ°ãECRãžã®Pushãªã©ãããã®ã§ãã®ãããã远å ããŠããŸãã "sts:AssumeRoleWithWebIdentity" ããªããšWFãèªèšŒæ
å ±ãåãåããªãã®ã§ããã ãæ³šæã { "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "ecs:UpdateService", "ecs:DescribeServices" ], "Resource": <ECS Sercice ARN> }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "elasticloadbalancing:RegisterTargets", "ecs:RegisterTaskDefinition", "elasticloadbalancing:DescribeTargetHealth", "elasticloadbalancing:DescribeTargetGroups", "elasticloadbalancing:DeregisterTargets", "ecs:TagResource", "ecs:UntagResource", "ecs:DescribeTaskDefinition", "ecr:GetAuthorizationToken", "ecr:CompleteLayerUpload", "ecr:UploadLayerPart", "ecr:InitiateLayerUpload", "ecr:BatchCheckLayerAvailability", "ecr:PutImage", "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "sts:AssumeRoleWithWebIdentity" ], "Resource": "*" } ] } Roleãäœã£ãŠãããŸãããã ä¿¡é Œããããšã³ãã£ãã£ã¿ã€ã ãŠã§ãã¢ã€ãã³ãã£ã㣠ã¢ã€ãã³ãã£ãã£ãããã€ã㌠token.actions.githubusercontent.com Audience sts.amazonaws.com GitHub çµç¹ãGitHub ãªããžããªãGitHub ãã©ã³ã èªåã®ãã®ãèšå® ããã§èšå®ãããªããžããªã«ããWFã«ã®ã¿èªèšŒæ
å ±ãæž¡ããããã«ãªããŸãã æ¬¡ãžé²ãã§å
ã»ã©äœæãã Policy ãèšå®ããã°Roleã®å®æã§ãã ãŠã§ãã¢ã€ãã³ãã£ãã£ã§èšå®ããå
容ã¯ä¿¡é Œããªã·ãŒã«åæ ãããŠããŸãã Condition ã® StringLike ã®éšåã§ Policy ãæž¡ããŠãããçžæãèšå®ããŠããŸããâã®å Žå㯠test-repository å
ã® WF ã«å¯ŸããŠã¯æž¡ããŠãããããšããæãã§ãã { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRoleWithWebIdentity", "Principal": { "Federated": "arn:aws:iam::xxxxxxxxxxxxxxx:oidc-provider/token.actions.githubusercontent.com" }, "Condition": { "StringEquals": { "token.actions.githubusercontent.com:aud": [ "sts.amazonaws.com" ] }, "StringLike": { "token.actions.githubusercontent.com:sub": [ "repo:test-user/test-repository:*" ] } } } ] } ééã£ãŠã "repo:*" ã¿ãããªèšå®ã¯ããªãããã«ããŸãããïŒã©ã®ãªããžããªã«å¯ŸããŠãæš©éãæž¡ããŠããŸãããããèšå®ã«ãªããŸãïŒ // ãã¹ãŠã®ãŠãŒã¶ãŒããªããžããªã«å¯ŸããŠãæš©éãæž¡ããŠããŸãèšå®ïŒ "StringLike": { "token.actions.githubusercontent.com:sub": [ "repo:*" ] } ãããŸã§ã§IAM Roleã䜿ã£ãŠWFããªãœãŒã¹ã®æäœãã§ããããã«ããæºåãçµãããŸããïŒ ããšã¯WFåŽã§ãã®Roleãåãåãã ãã§ãã - name: Configure AWS credentials from IAM Role uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.AWS_ROLE_ARN }} aws-region: ${{ env.AWS_REGION }} å
¬åŒã®Action ãããã®ã§ããã ãã§åãåãããšãã§ããŸã WF ã®äœæ ããããã¯WFãäœæããŸãã 以äžã®éãã«åŠçãè¡ã£ãŠãããŸãã IAM Role ã®ååŸãªã©åææºå Dockerfileã®Build, ECRãžã®Push ECSã®æŽæ° Slackãžã®éç¥ ã³ãŒãå
šäœ å
ã«ã³ãŒãå
šäœã貌ã£ãŠãããŸãã name: deploy ECS development on: workflow_dispatch: inputs: no-cache: description: "Build docker images with no cache" default: false required: false type: boolean push: branches: - develop env: AWS_REGION: "ap-northeast-1" ECR_REPOSITORY: "test-repository" ECS_SERVICE: "test-ecs-service" ECS_CLUSTER: "test-cluster" DESIRE_COUNT: "1" DOCKERFILE: "Dockerfile" SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} AWS_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN }} jobs: deploy: name: Deploy runs-on: ubuntu-latest timeout-minutes: 15 environment: development # GitHubã®OIDCããŒã¯ã³ãšã³ããã€ã³ããšããåãããããã«å¿
èŠ permissions: id-token: write contents: read steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Configure AWS credentials from IAM Role uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.AWS_ROLE_ARN }} aws-region: ${{ env.AWS_REGION }} - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v2 # image ã«ã€ããã¿ã°ãäœæ # GITHUB_SHA ã®å
é 7æåãã¿ã°ã«ããŠããŸã - name: Prepare IMAGE_TAG run: | IMAGE_TAG=$(echo ${GITHUB_SHA} | cut -c 1-7) echo "IMAGE_TAG=$(echo $IMAGE_TAG)" >> $GITHUB_ENV echo "build IMAGE_TAG: $IMAGE_TAG" - name: No Cache Option Check run: | # æå®ããå Žåãšpushã§ããªã¬ãŒãããå Žåã¯ãã£ãã·ã¥ãç¡å¹ã«ãã if [ ${{ inputs.no-cache }} -o ${{ github.event_name }} -eq 'push' ]; then echo "NO_CACHE=true" >> $GITHUB_ENV else echo "NO_CACHE=false" >> $GITHUB_ENV fi # image ã build ã latest ãš github_sha 7æ¡ãã¿ã°ã«ã㊠ECR ã« push - uses: docker/build-push-action@v6 id: build-image env: ECR_PATH: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }} with: file: ${{ env.DOCKERFILE }} push: true # ECRã«pushããã tags: | ${{ env.ECR_PATH }}:${{ env.IMAGE_TAG }} ${{ env.ECR_PATH }}:latest cache-from: type=gha # ãã£ãã·ã¥ã®ãœãŒã¹, GitHub Actionsã«ããã®ãäœ¿çš cache-to: type=gha,mode=max # ãã£ãã·ã¥ã GitHub Actionsã«ä¿ç®¡ããã max:äžéã¹ãããã®ãã¹ãŠã®ã¬ã€ã€ãŒããšã¯ã¹ããŒã no-cache: ${{ env.NO_CACHE }} # ãã£ãã·ã¥ã䜿çšããã provenance: false # Image indexãçæããªã # --force-new-deployment ã§åŒ·å¶çã«ããã〠- name: ECS Update id: update-ecs run: | # ECSæŽæ° aws ecs update-service --cluster $ECS_CLUSTER --service $ECS_SERVICE --desired-count $DESIRE_COUNT --force-new-deployment # Slackéç¥ # æå - name: Slack Notification on Success if: ${{ success() }} uses: rtCamp/action-slack-notify@v2 env: SLACK_TITLE: development Deploy Success SLACK_COLOR: good # 倱æ - name: Slack Notification on Failure if: ${{ failure() }} uses: rtCamp/action-slack-notify@v2 env: SLACK_TITLE: development Deploy Failure SLACK_COLOR: danger ããªã¬ãŒãåææºå ããªã¬ãŒã«ã¯developãã©ã³ãã«pushãããæãšæåå®è¡ãå
¥ããŠããŸããinputsã«ã€ããŠã¯ã®ã¡ã»ã©âŠâŠã envã«ã¯ECRãECSæå®ã®ããã®å€ãIAM Roleã®ARNããstepséšåã«ã€ããŠã¯åææºåãšã㊠actions/checkout ãECRã«ãã°ã€ã³ããããã® aws-actions/amazon-ecr-login ãªã©ãããŠããŸãã name: deploy ECS development on: workflow_dispatch: inputs: no-cache: description: "Build docker images with no cache" default: false required: false type: boolean push: branches: - develop env: # æŽæ°ãã ECS ã® Cluster,Service ãªã©ã®ååãæå® AWS_REGION: "ap-northeast-1" ECR_REPOSITORY: "test-repository" ECS_SERVICE: "test-ecs-service" ECS_CLUSTER: "test-cluster" DESIRE_COUNT: "1" # éçºç°å¢ã®ããã¿ã¹ã¯èµ·åæ°ã¯ "1" DOCKERFILE: "Dockerfile" # build ãã Dockerfile ãæå® SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} AWS_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN }} # äžèšã§äœã£ã IAM Role ã®ARN jobs: deploy: name: Deploy runs-on: ubuntu-latest timeout-minutes: 15 environment: development permissions: id-token: write contents: read steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 # æš©éãåãåã - name: Configure AWS credentials from IAM Role uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.AWS_ROLE_ARN }} aws-region: ${{ env.AWS_REGION }} - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v2 imageã®BuildãšECRãžã®Push jobs: deploy: steps: # ãçç¥ã # image ã«ã€ããã¿ã°ãäœæ # github sha ã®å
é 7æåãã¿ã°ã«ããŠããŸã - name: Prepare IMAGE_TAG run: | IMAGE_TAG=$(echo ${GITHUB_SHA} | cut -c 1-7) echo "IMAGE_TAG=$(echo $IMAGE_TAG)" >> $GITHUB_ENV echo "build IMAGE_TAG: $IMAGE_TAG" - name: No Cache Option Check run: | # æå®ããå Žåãšpushã§ããªã¬ãŒãããå Žåã¯ãã£ãã·ã¥ãç¡å¹ã«ãã if [ ${{ inputs.no-cache }} -o ${{ github.event_name }} -eq 'push' ]; then echo "NO_CACHE=true" >> $GITHUB_ENV else echo "NO_CACHE=false" >> $GITHUB_ENV fi # image ã build ã latest ãš github_sha 7æ¡ãã¿ã°ã«ã㊠ECR ã« push - uses: docker/build-push-action@v6 id: build-image env: ECR_PATH: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }} with: file: ${{ env.DOCKERFILE }} push: true # ECRã«pushããã tags: | ${{ env.ECR_PATH }}:${{ env.IMAGE_TAG }} ${{ env.ECR_PATH }}:latest cache-from: type=gha # ãã£ãã·ã¥ã®ãœãŒã¹, Github Actionsã«ããã®ãäœ¿çš cache-to: type=gha,mode=max # ãã£ãã·ã¥ã Github Actionsã«ä¿ç®¡ããã max:äžéã¹ãããã®ãã¹ãŠã®ã¬ã€ã€ãŒããšã¯ã¹ããŒã no-cache: ${{ env.NO_CACHE }} # ãã£ãã·ã¥ã䜿çšããã provenance: false # Image indexãçæããªã BuildãšPush㯠docker/build-push-action ã䜿ã£ãŠãã£ãŠããŸãããã®actionã䜿ãã ãã§Dockerfileã®BuildãPushããã£ãã·ã¥ä¿åãŸã§ãã£ãŠããããããšããããããã䜿ã£ãŠããã°ãããšæããŸãã éçºç°å¢ã§ããšç¢ºèªã®ããã«äœåããããã€ããâŠâŠãšããããšãããã®ã§ãã£ãã·ã¥ã䜿ã£ãŠBuildã«ãããæéãæžãããã®ã¯ããªãå©ãããŸãããããŠé¢åããããã£ãã·ã¥èšå®ã cache-from , cache-to ã ãã§æžãã®ãããããããšããã§ããã ãã£ãã·ã¥ã®äœ¿çšã¯ no-cache ã« bool ã§éžã¹ãŸãããªã®ã§æåå®è¡ã®é㯠inputs ã§ãã§ãã¯ããã¯ã¹ãçšæããŠãã§ãã¯ãããã䜿çšããªãããšãããµãã«ããŠããŸãã on: workflow_dispatch: inputs: no-cache: description: "Build docker images with no cache" default: false required: false type: boolean ECS ã®æŽæ° éçºç°å¢çšã®WFãªã®ã§ECSã®æŽæ°ãè¡ã£ãŠããŸããé£ããããšã¯ããŠããã AWS CLI ã§ aws ecs update-service --force-new-deployment ãããŠåŒ·å¶æŽæ°ããããŠããã ãã§ãã 䜿çšããã€ã¡ãŒãžã«ã€ããŠã¯ã¿ã¹ã¯å®çŸ©ã§ latest ã䜿ãããã«ããŠãããããæŽæ°ããããã ãã§åãæ¿ããããã«ãªã£ãŠããŸãã # --force-new-deployment ã§åŒ·å¶çã«ããã〠- name: ECS Update id: update-ecs run: | # ECSæŽæ° aws ecs update-service --cluster $ECS_CLUSTER --service $ECS_SERVICE --desired-count $DESIRE_COUNT --force-new-deployment Slackéç¥ æåŸã« action-slack-notify ãšããactionã䜿ã£ãŠWFãæåãããã©ãããéç¥ããŠããŸããGitHub Actions㯠if: ${{ success() }} ãšããã ãã§ æåæ/å€±ææ ã®åå²ãã§ããã®ã楜ã§å¥œãã§ãã jobs: deploy: steps: # ãçç¥ã # Slackéç¥ # æå - name: Slack Notification on Success if: ${{ success() }} uses: rtCamp/action-slack-notify@v2 env: SLACK_TITLE: development Deploy Success SLACK_COLOR: good # 倱æ - name: Slack Notification on Failure if: ${{ failure() }} uses: rtCamp/action-slack-notify@v2 env: SLACK_TITLE: development Deploy Failure SLACK_COLOR: danger ã¡ãªã¿ã«ãã㯠Slack ã® GitHub App ã䜿ã£ãŠãåãããšãã§ããã®ã§ãããªããŠã倧äžå€«ã§ããã奜ããªããæ¹ã§éç¥ããŠã¿ãŠãã ããã ãŸãšã GitHub Actionsã§ã®CDã«ã€ããŠæžãããŠããã ããŸããã ããŸãŸã§ã¯ããã¡ãã¡AWSã®ã³ã³ãœãŒã«ãã CodePipeline ã CodeBuild ãªã©ã®èšå®ã倿ŽããŠãã CodePipelineãå®è¡ããšãããµãã«ããŠããã®ã§ãã®WFã宿ããŠããã¯æ Œæ®µã«æ¥œã«ãããã€ã§ããããã«ãªããŸãããAWSã«ãã°ã€ã³ããŠèšå®ãããã£ãŠå®è¡ãªããŠé¢åãããããšãããŸãŸã§ãããã£ãŠãããªãšæããŸãâŠâŠ ããŸã§ãå
å䟿å©ã ãªãšã¯æããŠã¯ããŸãããä»åºŠã¯GitHubã®ããŒãžãéãã®ãé¢åããããšæã£ãŠããããSlackããçºç«ã§ããããã«ã§ããªãããªãšèããŠããŸãã ãã宿ããããã¡ãããŸãããã°ã«ã§ããããšæã£ãŠããã®ã§ããã®æã¯ãããããé¡ãããŸãã æ¬¡åã¯ãããã°éå¶ããŒã ã®æçš¿ã§ãã ããã®ãã¿ã«ïŒ
ãããã£ãããºã®éçºæ
åœãããŠããæž¡éã§ãã 3/24ã«ãããã£ãéå¶ããåã©ãåããµã€ãããããã£ãããºãã«ãŠãAIã€ãã³ããéå¬ããŸããã åœæ¥ã¯æ°å®¿æ¬ç€Ÿã«10çµã®èŠªåãæããAIã«ã€ããŠåŠãã§ããã ããŸããã 詳现ã«é¢ããŠã¯ PR TIMESã®èšäº ãã確èªãã ããã ä»åã¯ããããã£ãããºã®ãã¹ã³ãããã£ã©ã¯ã¿ãŒã§ãããã²ãããããšäŒè©±ãã§ããAIã²ãããã®è£åŽã話ããŠãããŸããAIã²ãããã¯ã€ãã³ãçšã«æ°ããäœæããŸããã ã·ã¹ãã æ§æ AIã²ãããã¯ããŠãŒã¶ãŒãå
¥åããããã¹ãã«å¯ŸããŠãã²ãããããšããŠå¿çããããæç€ºã«åºã¥ããŠç»åãçæãããããWebã¢ããªã±ãŒã·ã§ã³ã§ããè¿çãããããã¹ãã¯é³å£°åæã«ããèªã¿äžããããŸãã å
šäœçãªã¢ãŒããã¯ãã£ã¯ä»¥äžã®èŠçŽ ã§æ§æãããŠããŸãã ããã³ããšã³ã: ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããããã¯ãšã³ãAPIãšéä¿¡ã ããã¯ãšã³ãAPI: ããžãã¹ããžãã¯ãåŠçããå€éšãµãŒãã¹ïŒçæAIãé³å£°åæïŒãšé£æºã çæAI: ããã¹ãçæãšç»åçæãè¡ãïŒAmazon Bedrockãå©çšïŒã é³å£°åæ: çæãããããã¹ããé³å£°ã«å€æïŒVOICEVOXãå©çšïŒã ã€ã³ãã©: ã¢ããªã±ãŒã·ã§ã³ã®å®è¡ç°å¢ãæäŸïŒAWS App Runner, API Gateway, Lambda, S3ãªã©ãå©çšïŒã ã€ã³ãã© ã€ãã³ãéå¬ãŸã§éãããæéã§ããã®ã§ãæè»ãªéçºãšã¹ã ãŒãºãªãããã€ãå®çŸã§ããã¢ãŒããã¯ãã£ãç®æããŸããããã®ãããã€ã³ãã©æ§ç¯ã管çã®ãªãŒããŒããããå°ãªãAWSã®ãããŒãžããµãŒãã¹ãç©æ¥µçã«æŽ»çšããŸããã ã¢ããªã±ãŒã·ã§ã³å®è¡ç°å¢ ããã¯ãšã³ãAPIãµãŒããŒãVOICEVOXãµãŒããŒã®ãã¹ãã£ã³ã°ã«ã¯ãAWS App Runnerãéžå®ããŸããã App Runnerã®è©³çްã«ã€ããŠã¯ã以åå·çãããã¡ãã®èšäºããåç
§ãã ããã https://engineering.nifty.co.jp/blog/30738 APIãšã³ããã€ã³ã ããã³ããšã³ãããã®ãªã¯ãšã¹ããåãä»ããAPIãšã³ããã€ã³ãã¯ãAPI GatewayãšLambdaãçšããŠãµãŒããŒã¬ã¹æ§æã§æ§ç¯ããŸãããLambda颿°å
ã§ãåŸè¿°ããAmazon Bedrockã®APIãåŒã³åºããŠããŸãã ç»åã¹ãã¬ãŒãž AIã«ãã£ãŠçæãããç»åã¯ãAmazon S3ã«ä¿åãããŸããä¿ååŸãããã³ããšã³ãã§ç»åã衚瀺ããããã«ã眲åä»ãURLãçºè¡ããä»çµã¿ãšããŸããã é³å£°å
¥å é³å£°å
¥åã«ã¯ãGoogle CloudãæäŸããSpeech-to-Textãå©çšããŸããããã®ãµãŒãã¹ã¯APIçµç±ã§å©çšãããããã€ã³ãã©ç®¡çã¯äžèŠã§ãã çæAI ããã¹ãçæãšç»åçæã®ã³ã¢ãšãªãAIæ©èœã«ã¯ãæ§ã
ãªåºç€ã¢ãã«ãAPIçµç±ã§å©çšã§ããAmazon Bedrockãæ¡çšããŸããã ããã¹ãçæ (ãã£ãã) AIã²ããããšã®å¯Ÿè©±æ©èœã«ã¯ãAnthropic瀟ã®Claude 3.7 Sonnetãå©çšããŸããã éçºåœåãããé«éãªClaude 3.5 Haikuã¢ãã«ãæ€èšŒããŸããããAIã²ãããã®ãã£ã©ã¯ã¿ãŒèšå®ïŒè©±ãæ¹ãæ§æ Œãªã©ïŒãããã³ããã§æç€ºããéã«ãSonnetã¢ãã«ã®æ¹ãããå¿ å®ã«ããã€èªç¶ãªå¿çãçæããããšãã§ãããããæçµçã«Sonnetãæ¡çšããŸããã ç»åçæ ã¢ãã«éã®å質æ¯èŒãè¡ãããã Amazon Nova Canvas ãš Titan Image Generator G1 ãéžã¹ãããã«ããŠããŸãã ããã¯ãšã³ãAPI ããã³ããšã³ããšåçš®AIãµãŒãã¹éã®ããã¯ãšã³ãAPIã¯ãGoèšèªã§å®è£
ããŸãããäž»ãªåœ¹å²ã¯ä»¥äžã®éãã§ãã ããã³ããšã³ãããã®ãªã¯ãšã¹ãïŒå¯Ÿè©±ããã¹ããç»åçææç€ºïŒãåãä»ããã ãªã¯ãšã¹ãå
容ã«åºã¥ããAmazon Bedrockã®APIãåŒã³åºããŠããã¹ãçæãç»åçæãå®è¡ããã å¿
èŠã«å¿ããŠVOICEVOXãµãŒããŒã«ãªã¯ãšã¹ããéããããã¹ãã®é³å£°ããŒã¿ãååŸããã çæãããããã¹ããç»åïŒã®URLïŒãé³å£°ããŒã¿ãããã³ããšã³ãã«è¿ãã APIãšããŠã¯ãäž»ã«ä»¥äžã®2çš®é¡ãå®è£
ããŸããã 察話çšAPI: ãŠãŒã¶ãŒå
¥åãšäŒè©±å±¥æŽãåãåããBedrock (Claude) ã§çæãããå¿çããã¹ããšãVOICEVOXã§çæãããé³å£°ããŒã¿ãè¿ãã ç»åçæçšAPI: ç»åçææç€ºã®ããã¹ããåãåããBedrockã§çæãããç»åã®S3 URLãè¿ãã Goèšèªãéžå®ããçç±ã¯å®è¡é床ã®éããéçåä»ãã«ããå
ç¢æ§ã䞊è¡åŠçã®å®¹æããªã©ã§ãã é³å£°åæ AIã²ããããçæããããã¹ãã¡ãã»ãŒãžãããããã£ã©ã¯ã¿ãŒãããèªç¶ãªé³å£°ã§èªã¿äžããããã«ããªãŒãã³ãœãŒã¹ã®é«å質ãªé³å£°åæãœãããŠã§ã¢ã§ããVOICEVOXãå©çšããŸããã ä»åã¯Dockerã³ã³ããçã®VOICEVOXãæ¡çšããããã¯ãšã³ãAPIãµãŒããŒãšåæ§ã«App Runneräžã§ãã¹ãã£ã³ã°ããŸããã ããã«ãããé³å£°åææ©èœãç¬ç«ãããã€ã¯ããµãŒãã¹ãšããŠéçšã§ããã€ã³ãã©ç®¡çã®è² æ
ã軜æžãã€ã€ãã¹ã±ãŒã©ããªãã£ã確ä¿ããããšãã§ããŸããã ããã¯ãšã³ãAPIã¯ããã®VOICEVOXãµãŒããŒã«å¯ŸããŠHTTPãªã¯ãšã¹ããéãããšã§é³å£°ããŒã¿ãååŸããŸãã ããã³ããšã³ã Next.jsãçšããŠæ§ç¯ããŸãããäž»ãªæ©èœã¯ä»¥äžã®éãã§ãã ãŠãŒã¶ãŒãAIã²ããããžã®ã¡ãã»ãŒãžãå
¥åããããã¹ãããã¯ã¹ã AIã²ãããããã®å¿çããã¹ãã®è¡šç€ºã çæãããç»åã®è¡šç€ºã é³å£°ãåçããæ©èœã ããã¯ãšã³ãAPIãšã®éåæéä¿¡ïŒå¯Ÿè©±ãç»åçæãªã¯ãšã¹ãïŒã ãã©ãŠã¶ã®MediaRecorder APIãå©çšããé³å£°é²é³ã»ããŒã¿ååŸåŠçã åºæ¥äžãã£ããã® ãã£ãã ç»åçæ ãŸãšã ä»åã®AIã²ãããéçºãããžã§ã¯ãã§ã¯ãAmazon Bedrockãäžå¿ãšããAWSã®ãããŒãžããµãŒãã¹ãšãVOICEVOXã®ãããªãªãŒãã³ãœãŒã¹ãœãããŠã§ã¢ãçµã¿åãããããšã§ãçæéã§åã©ããã¡ã«æ¥œããã§ããããAIã¢ããªã±ãŒã·ã§ã³ãå®çŸããããšãã§ããŸããã ç¹ã«ãApp RunnerãLambdaãAPI Gatewayãšãã£ããµãŒãã¹ã掻çšããããšã§ãã€ã³ãã©æ§ç¯ã»ç®¡çã®å·¥æ°ã倧å¹
ã«åæžããã¢ããªã±ãŒã·ã§ã³ããžãã¯ãšAI飿ºéšåã®éçºã«éäžã§ããããšããè¿
éãªãªãªãŒã¹ã«ã€ãªãã£ããšèããŠããŸãã
ã¯ããã« ããã«ã¡ã¯ããããã£æ ªåŒäŒç€Ÿã®è¥¿åã§ãã ä»åã¯Rancher Desktopã«ã€ããŠç޹ä»ããŸãã ããããDocker Desktopã®ä»£æ¿ã§Rancher Desktopãå°å
¥ãããæ¹ã®åèã«ãªãã°å¹žãã§ãã èæ¯ Docker Desktopå€äžããã«ãã代æ¿ããŒã«æ¢ãã®è©±ã åŒç€Ÿã®ãããŒãžã£âã Rancher Desktopãããããšããããšãåšç¥ããŠãããã®ã§WSL2ã®ç°å¢ã«ã€ã³ã¹ããŒã«ããããšã«ã WSL2ã£ãŠïŒ Windows Subsystem for Linux (WSL) 㯠Windows ã®æ©èœã§ãããå¥ã®ä»®æ³ãã·ã³ããã¥ã¢ã« ããŒããå¿
èŠãšããã«ãWindows ãã·ã³ã§ Linux ç°å¢ãå®è¡ã§ããŸãã https://learn.microsoft.com/ja-jp/windows/wsl/about https://learn.microsoft.com/ja-jp/windows/wsl/install MacãŠãŒã¶ãŒããã®èªç¥ãå°ãªãããªã®ã§äžå¿èª¬æããŠãããšãWindowsäžã§Linuxåããããã§ããã ãããã€ã .msiãã¡ã€ã«ããŠã³ããŒãããªããšäœãã€ã³ã¹ããŒã«åºæ¥ãªããã ããTeraTermãšãèœãšããŠæ¥ãªããšã©ããã®ãµãŒãã«SSHããããšãã§ããªããã ãã ãšãæã£ãŠãMac掟ã®äººã¯èªèãæ¹ããŠãã ããã ã€ã³ã¹ããŒã«ã§èºãããšãã æåã«Docker Desktopãã¢ã³ã€ã³ã¹ããŒã«ããŠããã¹ãã ã£ãã ããããããªããªã£ãŠã以äžã®æµãã§å°å
¥ããŠããŸããèºããŠããŸã£ãã Rancher Desktopãã€ã³ã¹ããŒã« Docker Desktopãã¢ã³ã€ã³ã¹ããŒã« åããå€ã«ãªã£ãŠRancher Desktop ããªãã¢ã€ã³ã¹ããŒã« å
¬åŒã§ãDocker Desktopæ¶ããŠãããããšæžãããŠããæ°ãããã docker compose ã§ãšã©ãŒã«ãªã docker composeã³ãã³ãå®è¡ããã以äžã®ããã«ãªã£ã $ docker compose up -d docker-credential-secretservice: error while loading shared libraries: libsecret-1.so.0: cannot open shared object file: No such file or directory docker-credential-secretservice: error while loading shared libraries: libsecret-1.so.0: cannot open shared object file: No such file or directory docker-credential-secretservice: error while loading shared libraries: libsecret-1.so.0: cannot open shared object file: No such file or directory docker-credential-secretservice: error while loading shared libraries: libsecret-1.so.0: cannot open shared object file: No such file or directory docker-credential-secretservice: error while loading shared libraries: libsecret-1.so.0: cannot open shared object file: No such file or directory 以äžã§å¯ŸåŠãã sudo apt install libsecret-1-dev ã€ã¡ãŒãžã®pullã§ãšã©ãŒã«ãªã äžèšãå®è¡ããããš docker compose up ãããä»åºŠã¯ä»¥äžã®ãšã©ãŒãåºã $ docker compose up -d [+] Running 0/0 â django Pulling 0.0s â minio Pulling 0.0s â createbuckets Pulling 0.0s â wiremock Pulling 0.0s â mock Pulling 0.0s error getting credentials - err: exit status 1, out: `Could not connect: No such file or directory` error getting credentials – err: exit status 1, out: Could not connect: No such file or directory ~/.docker/config.json ã«ä»¥äžã远å "credsStore": "pass" çŸåšã® ~/.docker/config.json ã®ç¶æ
ãä»¥äž { "cliPluginsExtraDirs":["/mnt/c/Users/UsersName/AppData/Local/Programs/Rancher Desktop/resources/resources/linux/docker-cli-plugins"], "credsStore": "pass" } ç¡äºäœ¿ããããã«ãªããŸããã Rancher Desktopã®äœ¿çšæã«ã€ã㊠ãŸã ãã£ããå©çšã§ããŠããªãã§ãããä»ãŸã§äœ¿ã£ãŠãã docker ã®ã³ãã³ãããã®ãŸãŸäœ¿ããã®ã§éåæãªãå©çšã§ããŠããŸãã ãããã« ä»åã¯Rancher Desktopã«ã€ããŠç޹ä»ããŸããã WSL2ã§Rancher Desktopãå°å
¥ããéã«åèã«ãªãã°å¹žãã§ãã
ã¯ããã« ããã«ã¡ã¯ããããã£æ ªåŒäŒç€Ÿã®å±±ç°ã§ãã ä»åã¯AWS Lambdaã®ãã°ã¬ãã«ãæå³ããç¡å¹åãããŠããäºè±¡ã«ééããã®ã§ããã®äœéšã«ã€ããŠç޹ä»ããŸãã æŠèŠ AWS Lambdaã®åºç€ãã°ãJSON圢åŒã§åºåã§ããããã«ãªã£ããããèšå®ã倿Žãããæå³ãããã°ã¬ãã«ãç¡å¹ã«ãªã£ãŠããŸããã äºè±¡ åæ Lambda Powertoolsã®Loggerã§ãã°ãåºããŠãã POWERTOOLS_LOG_LEVEL ç°å¢å€æ°ã§åºåãã°ã¬ãã«ãå¶åŸ¡ããŠãã èµ·ãã£ãããš AWS Lambdaã®ãã°ã¯AWS CloudWatch Logsã«æµããã®ã§ãJSON圢åŒã§åºåããããšãäžè¬çã§ãã ãšãããLambdaåºç€ãåºãstartãstopãªã©ã®ãã°ã¯ãã¬ãŒã³ããã¹ã圢åŒã§åºå®ãããŠãããæ§é åãããŠããªãããæ€çŽ¢ãå°é£ã§ããã ããã2023/11ã®ã¢ããããŒãã§å€æŽãããJSON圢åŒã§åºåã§ããããã«ãªããŸããã AWS Lambda ã®é«åºŠãªãã°å¶åŸ¡æ©èœã®ãçŽ¹ä» | Amazon Web Services ãšããããã§CDKãã PythonFunction( ... logging_format=LoggingFormat.JSON, ) ãšèšå®ãããšããã ç°å¢å€æ°ã«ãããã°ã¬ãã«èšå®ãå¹ããªããªããINFOã¬ãã«åºå®ãšãªã£ãŠããŸããŸãã ã (å
ã
WARNINGã«èšå®ãããŠãããINFOã«ãªã£ãããšã§AWS CloudWatch Logsã®æéãè·³ãäžããçºèŠããŸãã) åå AWSã³ã³ãœãŒã«ããèŠããšããããããã®ã§ãããJSONãžã®å€æŽã¯ãã ãã©ãŒããããå€ããã ãã§ã¯ãªãã Advanced Logging Control(ALC)ãæå¹ã«ããããšãæå³ããŸã ããããŠã ALCã«ã¯ãã°ã¬ãã«ã®å¶åŸ¡ãå«ãŸããŠããŸãã ã AWSã³ã³ãœãŒã«ããèŠããã®ã³ã°èšå® AWSã³ã³ãœãŒã«ããèŠããã®ã³ã°èšå® AWSã³ã³ãœãŒã«ããèŠããã®ã³ã°èšå® åé¡ãšãªãã®ã¯ã¢ããªã±ãŒã·ã§ã³ãã°ã¬ãã«ã§ããã®èšå®ã«ãã æšæºãã¬ãŒ(Pythonã ãšlogging.Logger)ã®åºåãã°ã¬ãã«ãèšå®å€ã§å¶éãã LoggeråŽãINFOã§ããALCåŽãWARNãªãWARN以äžããåºåãããªã AWS_LAMBDA_LOG_LEVEL ç°å¢å€æ°ã«ãã°ã¬ãã«ãèšå®ãã ãšããåäœã«ãªããŸãã ããã«Lambda Powertools㯠AWS_LAMBDA_LOG_LEVEL ç°å¢å€æ°ãæåªå
ã®ãã°ã¬ãã«èšå®ãšããŠåãæ±ããŸãã Logger – Powertools for AWS Lambda (Python) çµæãšããŠãALCã®ãã°ã¬ãã«ããåç
§ãããŠãããã POWERTOOLS_LOG_LEVEL ç°å¢å€æ°ã¯æ©èœããªãç¶æ
ãšãªã£ãŠããŸããã 察ç POWERTOOLS_LOG_LEVEL ç°å¢å€æ°ããããALCã«ããèšå®ã«å€æŽããŸããã PythonFunction( ... logging_format=LoggingFormat.JSON, + application_log_level_v2=ApplicationLogLevel.WARN, - environment={ - "POWERTOOLS_LOG_LEVEL": "WARNING", - } ) ãŸãšã æ°ããèšå®ãå°å
¥ãããšãã¯ãèšå®ãããå
容ã®ç¯å²ã確èªããããã«ããŸãããã
ãã®èšäºã¯ããªã¬ãŒããã°äŒç»ãCI/CDãã®èšäºã§ãã ã¯ããã« ãããã£ã§WEBãµãŒãã¹ã®éçºã»éçšãæ
åœããŠããæž¡éã§ãã Goã§å®è£
ããè€æ°ã®ããããAWS Lambdaã«ãããã€ããæ©äŒããã£ãã®ã§ããã®ãšãã«å®è£
ããå
容ã玹ä»ããŠãããŸãã æ§æ GitHub Actionsã䜿ã£ãŠãããã€ãå®è£
ããŠããŸãã Lambdaã¯ã³ã³ããããŒã¹ã§ãããã管çããGitHub Actionsã«ãã£ãŠECRãžããã·ã¥ããŸãã éåžžãLambdaãECRã®ããã·ã¥ãããªã¬ãŒã«èªåæŽæ°ãã«ã¯EventBridgeãå¿
èŠã§ãããä»åã¯ç®¡çãç°¡çŽ åãããããLambdaã®æŽæ°ãGitHub Actionsã§çŽæ¥è¡ãããšã«ããŸããã ãã£ã¬ã¯ããªæ§æ 以äžã®ãããªãã£ã¬ã¯ããªæ§é ã§ããããå®è£
ããããšãæ³å®ããŸãã cmd/ãã£ã¬ã¯ããªã®äžã«ãåãããã®ã¡ã€ã³ããžãã¯ãããããã®ãã£ã¬ã¯ããªã«é
眮ãããæ§æã§ãã åããããã£ã¬ã¯ããªã«Dockerfileãèšçœ®ããããããã®ããžãã¯ãç¬ç«ããLambdaïŒãããïŒãšããŠå®è¡ãããŸãã .githubå
ã«ãããã€ãè¡ãã¯ãŒã¯ãããŒãé
眮ããŠããŸãã .github âââ workflows âââ deploy_batch1.yml âââ deploy_batch2.yml âââ deploy_batch3.yml âââ reusable_build_push_docker_image.yml âââ reusable_update_lambda_function_image.yml batch âââ cmd â âââ batch1 â â âââ main.go â â âââ Dockerfile â âââ batch2 â â âââ main.go â â âââ Dockerfile â âââ batch3 â âââ main.go â âââ Dockerfile âââ go.mod âââ go.sum âââ models âââ hoge.go âââ usecase âââ hoge.go Dockerfileã®äžèº« FROM --platform=$BUILDPLATFORM golang:1.24.0-alpine3.21 AS builder ARG TARGETARCH WORKDIR / COPY ./ /. WORKDIR /cmd/batch1 RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build -o batch1 ./main.go FROM alpine:3.21 RUN apk --no-cache add ca-certificates COPY --from=builder /cmd/batch1 . COPY /lambda_layer/ /opt/ ENTRYPOINT [ "/batch1" ] ã¯ãŒã¯ãã㌠ä»åã¯äŸãšããŠ3ã€ã®ããããäœæããããã«ãªã£ãŠããŸãããå®éã«éçšãããšãã¯æ°åå以äžã®ãããã管çããããšããããŸãããã®ãããGitHub Actionsã®ã¯ãŒã¯ãããŒã¯åå©çšã§ããããã«äœã£ãŠãããŸãã ããã«ãä»åã®æ§æã§ã¯ Arm64 åãã«ãã«ãããããšã§ãå®è¡ç°å¢ã§ã®ããã©ãŒãã³ã¹åäžãç®æããŸãã ã¯ãŒã¯ãããŒãäœãåã«ããªããžããªã«ä»¥äžã®èšå®ãå¿
èŠã§ãã AWS_ACCESS_IAM_ROLE AWSãžã®ã¢ã¯ã»ã¹ãOIDCã§è¡ããã 詳现㯠ãã¡ã AWS_REGION ECRãšLambdaããããã€ãããªãŒãžã§ã³ AWS_ECR_REGISTRY_URI ECRã®ã¬ãžã¹ããªURI ãŸããECRãžã€ã¡ãŒãžãããã·ã¥ããã¯ãŒã¯ãããŒãäœããŸãã ARM64ã§åããããã«ããããã®æ¹æ³ã2ãã¿ãŒã³ç޹ä»ããŸãã ãã«ã Linux x86_64ã§åããå Žå GitHub Actions ã®ããã©ã«ãã®å®è¡ç°å¢ã¯ Linux x86_64 ã§ãããã®ãããArm64 åãã«ãã«ããè¡ãã«ã¯ ã¯ãã¹ã³ã³ãã€ã«ãå¿
èŠã«ãªããŸãã Go ã®å Žåãå
¬åŒã«ã¯ãã¹ã³ã³ãã€ã«ããµããŒããããŠãããããç°å¢å€æ°ãæå®ããããšã§æ¯èŒçç°¡åã« Arm64 åãã®ãã€ããªãäœæã§ããŸãã ãŸããDocker ã€ã¡ãŒãžã®ããã« OS/ã¢ãŒããã¯ãã£ã坿¥ã«é¢ä¿ããå Žåã«ã¯ãQEMUïŒãã«ããã©ãããã©ãŒã ã€ã¡ãŒãžã®ãã«ãïŒãçšãããšãã¥ã¬ãŒã·ã§ã³ãšDocker Buildxã䜿ã£ãŠãã«ãã¢ãŒããã¯ãã£å¯Ÿå¿ã®ãã«ããè¡ãæ¹æ³ãæå¹ã§ãã 以äžãã¯ãŒã¯ãããŒã®åŠçã«ãªããŸãã # reusable_build_push_docker_image.yml on: workflow_call: inputs: docker_image_name: # ECRãªããžããªå required: true type: string docker_tag: # ã€ã¡ãŒãžã¿ã°ïŒéåžžã¯latestïŒ required: true type: string dockerfile_path: # Dockerfileã®ãã¹ required: true type: string secrets: AWS_ACCESS_IAM_ROLE: # AWS IAMããŒã« required: true jobs: build_push_docker_image: name: Build and push Docker image runs-on: ubuntu-latest timeout-minutes: 3 environment: ${{ inputs.environment }} permissions: id-token: write # OIDCèªèšŒçš contents: read # ãªããžããªèªã¿åãçš steps: - name: Check out code uses: actions/checkout@v4 - name: Setup QEMU(linux/arm64) uses: docker/setup-qemu-action@v3 with: platforms: linux/arm64 - name: Build Docker image run: docker buildx build --platform linux/arm64 -t ${{ inputs.docker_image_name }}:${{ inputs.docker_tag }} . -f ${{ inputs.dockerfile_path }} - name: Assume role AWS token uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ vars.AWS_ACCESS_IAM_ROLE }} aws-region: ${{ vars.AWS_REGION }} - name: Push Docker image to ECR run: | aws ecr get-login-password --region ${{ vars.AWS_REGION }} | docker login --username AWS --password-stdin ${{ vars.AWS_ECR_REGISTRY_URI }} docker tag ${{ inputs.docker_image_name }}:${{ inputs.docker_tag }} ${{ vars.AWS_ECR_REGISTRY_URI }}/${{ inputs.docker_image_name }}:${{ inputs.docker_tag }} docker push ${{ vars.AWS_ECR_REGISTRY_URI }}/${{ inputs.docker_image_name }}:${{ inputs.docker_tag }} ã¡ãªãã GitHub Actionsã®æ¯æã®ç¡æå©çšæ å
ã§å®è¡ã§ãããããã³ã¹ããæãããã ãã¡ãªãã QEMUã䜿çšããŠArm64ç°å¢ããšãã¥ã¬ãŒãããããããã€ãã£ãã®Arm64ç°å¢ã§ã®ãã«ããšæ¯ã¹ãŠåŠçãé
ããªã Arm64ã©ã³ããŒã䜿ãå Žå 2024/06/03ã«GitHub Actionsã«Arm64ã©ã³ããŒã远å ãããŸããã ãã®ãããQEMUãäžèŠã«ãªããçŽæ¥ãã«ããè¡ããããã«ãªããŸããã 以äžãQEMUã䜿ããªãã¯ãŒã¯ãããŒã«ãªããŸãã ãããªãã¯ãªããžããªã®å Žå㯠ubuntu-24.04-arm ãããã©ã€ããŒããªããžããªã®å Žåã¯Arm64ã®ã©ã³ããŒãäœæããŠæå®ããŸãã # reusable_build_push_docker_image.yml on: workflow_call: input docker_image_name: # ECRãªããžããªå required: true type: string docker_tag: # ã€ã¡ãŒãžã¿ã°ïŒéåžžã¯latestïŒ required: true type: string dockerfile_path: # Dockerfileã®ãã¹ required: true type: string aws_access_iam_role: # AWS IAMããŒã« required: true type: string jobs: build_push_docker_image: name: Build and push Docker image runs-on: ubuntu-24.04-arm timeout-minutes: 3 environment: ${{ inputs.environment }} permissions: id-token: write # OIDCèªèšŒçš contents: read # ãªããžããªèªã¿åãçš steps: - name: Check out code uses: actions/checkout@v4 - name: Build Docker image run: docker buildx build --platform linux/arm64 -t ${{ inputs.docker_image_name }}:${{ inputs.docker_tag }} . -f ${{ inputs.dockerfile_path }} - name: Assume role AWS token uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ vars.AWS_ACCESS_IAM_ROLE }} aws-region: ${{ vars.AWS_REGION }} - name: Push Docker image to ECR run: | aws ecr get-login-password --region ${{ vars.AWS_REGION }} | docker login --username AWS --password-stdin ${{ vars.AWS_ECR_REGISTRY_URI }} docker tag ${{ inputs.docker_image_name }}:${{ inputs.docker_tag }} ${{ vars.AWS_ECR_REGISTRY_URI }}/${{ inputs.docker_image_name }}:${{ inputs.docker_tag }} docker push ${{ vars.AWS_ECR_REGISTRY_URI }}/${{ inputs.docker_image_name }}:${{ inputs.docker_tag }} ã¡ãªãã QEMUã䜿ã£ãŠããªããããããé«éã«ãã«ããè¡ãã ãã¡ãªãã ãã©ã€ããŒããªããžããªã§ã¯Large Runneræ±ãã®ãããç¡æå©çšæ å€ã®æ±ãã«ãªã£ãŠããŸãïŒ2025/04/02çŸåšïŒ Lambdaãžã®ããã〠aws cliã䜿ã£ãŠLambdaãã¡ã³ã¯ã·ã§ã³ãæŽæ°ããŸãã # reusable_update_lambda_function_image.yml on: workflow_call: inputs: docker_image_name: # ECRãªããžããªå required: true type: string docker_tag: # ã€ã¡ãŒãžã¿ã°ïŒéåžžã¯latestïŒ required: true type: string lambda_function_name: # Lambdaãã¡ã³ã¯ã·ã§ã³å required: true type: string aws_access_iam_role: # AWS IAMããŒã« required: true type: string jobs: updete_lambda_function_image: name: Updete Lambda function image runs-on: ubuntu-latest timeout-minutes: 3 environment: ${{ inputs.environment }} permissions: id-token: write contents: read steps: - name: Assume role AWS token uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ vars.AWS_ACCESS_IAM_ROLE }} aws-region: ${{ vars.AWS_REGION }} - name: Updete Lambda function image run: aws lambda update-function-code --region ${{ vars.AWS_REGION }} --function-name ${{ inputs.lambda_function_name }} --architectures arm64 --image ${{ vars.AWS_ECR_REGISTRY_URI }}/${{ inputs.docker_image_name }}:${{ inputs.docker_tag }} ã¡ã€ã³åŠç å
ã»ã©äœæããåå©çšå¯èœãªã¯ãŒã¯ãããŒãåŒã³åºããŸãã Dockerã®ã€ã¡ãŒãžåãšãã¡ã€ã«ãã¹ãæå®ããåãããããšã«ãã®èšå®ãäœæããããšã§ãããã€ç°å¢ã宿ããŸãã # deploy_batch1.yml name: Deploy batch1 on: push: branches: - develop paths: - "cmd/batch1/**" - "models/**" - "usecase/**" - "repository/**" - "go.mod" - "go.sum" jobs: build_push_docker_image: name: Call reusable build and push Docker image workflow uses: ./.github/workflows/reusable_build_push_docker_image.yml with: docker_image_name: batch1-ecr docker_tag: latest dockerfile_path: cmd/batch1/Dockerfile aws_access_iam_role: ${{ vars.AWS_ACCESS_IAM_ROLE }} update_lambda_function_ime: name: Call reusable update Lambda function image needs: [build_push_docker_image] uses: ./.github/workflows/reusable_update_lambda_function_image.yml with: docker_tag: latest lambda_function_name: batch1 docker_image_name: batch1-ecr aws_access_iam_role: ${{ vars.AWS_ACCESS_IAM_ROLE }} å®è¡ ä»åã¯ç¹å®ãã©ã³ããžã®pushãããªã¬ãŒãšããŠã¯ãŒã¯ãããŒãå®è¡ãããããã«èšå®ããŸããã 以äžããå®éã«ãããã€ããéã®å®è¡çµæã§ãã QEMUã䜿ã£ãå Žå Arm64ã©ã³ããŒã䜿ã£ãå Žå æ€èšŒã«äœ¿ã£ããããã§ã¯ãArm64ã©ã³ããŒã䜿ãããšã§åŠçãå°ãéããªããŸããã ã³ãŒãã®å€§ããã«ãã£ãŠã¯ãã£ãšå€§ããªå·®ãåºãŠãããšæããŸããæ©ããã©ã€ããŒããªããžããªã§ãç¡æå©çšæ ãªãã§äœ¿ããããã«ãªããšããã§ããã æåŸã« ä»åã¯Goã§äœæããããããLambdaã«å¹çãããããã€ããæ¹æ³ã玹ä»ããŸããã GitHub Actionsã¯åå©çšå¯èœãªã¯ãŒã¯ãããŒãäœæããããšãã§ããã®ã§ãä»åã®ãããªãããã€å
ãéãã ãã§ãå
éšåŠçãäžç·ã®å Žåã¯éåžžã«åœ¹ç«ã¡ãŸãã ãŸããä»åã®ããã«è€æ°ã®ããããã³ã³ããããŒã¹ã§ç®¡çããããšã§ãç°å¢ã®çµ±äžæ§ãä¿ãããã¡ã³ããã³ã¹æ§ãåäžããŸãã æ¬¡åã¯ãIWS ããã§ãã ä»åãšåããGitHub Actionsã䜿ã£ããããã€æ¹æ³ã玹ä»ããŠããããããªã®ã§ã楜ãã¿ã§ãïŒ
æ°ããæè¡ã®å°å
¥ãå«ãããšã³ãžãã¢ã®ãã£ã¬ã³ãžãåŸæŒãããŠããã ãããããŠãã¿ãªãããæããããã£ãšããäŒç€Ÿã®ããããšããããæããŠãã ããã A.Mãã ãšã³ãžãã¢èŠç¹ã ãšãè²ã
ãªããšã«ææŠã§ããäŒç€Ÿã ãšæããŸããäŒç€Ÿã«ãã£ãŠã¯å®å
šãªåæ¥å¶ã§ããµãŒãã¹ã®ãªãã®äžéšåã®éçºããä»»ããããªãã±ãŒã¹ããããŸããããããã£ã®å Žåã¯åžæããã°ãµãŒãã¹å
šäœã«æºãããããšãçãããããŸãããçŸã«ãã〠ãããã£ãã§ããåœåããiOSçã®éçºã ãã§ããããä»ã§ã¯Androidçããã®è£åŽã®ä»çµã¿ãå«ããŠå
šãŠãä»»ããŠããããŠããŸãããã¡ãã倧å€ãã¯ãããŸããããã«ã¹ã¿ãã¯ã«ã¹ãã«ãç¿åŸã§ããã®ã¯ããšã³ãžãã¢ã«ãšã£ãŠå€§ããªã¡ãªããã§ã¯ãªãã§ããããã ãŸããåŽåç°å¢ã®é¢ã§ã¯æ®æ¥æéãå€ãã¯ãªãã§ãããåããããäŒç€Ÿã ãšæããŸãããã¡ããé
å±éšçœ²ãæ¥åå
容ããã®æã
ã®ä»äºã®ç¶æ³ã«ãã£ãŠãå€ãã£ãŠããŸãããæçµŠäŒæã2æ¥åã®ç³è«ã§åé¡ãªãåããããšãè²ã
ãšæè»ã«å¯Ÿå¿ããŠããããŸããã M.Kãã A.Mã®è©±ãšå°ã䌌ãŠããŸãããè²ããªæè¡ã詊ãããšããããããã£ã®è¯ãã ãšæããŸããæåããç¹å®ã®æè¡ãããã§ã¯ãªãããã®éœåºŠããµãŒãã¹ã«åã£ãæè¡ãæ€èšããªããéçºãé²ããæåãåœããåã«æ ¹ä»ããŠããããããŸã§ç€Ÿå
ã§æ¡çšãããããšã®ãªãæ°ããæè¡ã§ãããããéžãã åŠ¥åœæ§ã説æã§ããã°ãåé¡ãªãæ¡çšããŠããããŸããããããæå³ã§ãããšã³ãžãã¢ããã£ã¬ã³ãžããããç°å¢ãªã®ããªãšããŸãããã£ã¬ã³ãžãšããæå³ã§ã¯åãå©çšããå
¬åå¶åºŠãããã§ãããèªåãããæé·ããããã«ãåžæããããžã·ã§ã³ã«ç°åã§ããå¶åºŠãããã®ã¯æ¬åœã«é
åçã ãšæããŸãã K.Nãã ãã£ã¬ã³ãžã®ããããã¯ãç§ãæããŸããç§èªèº«ããæ°åæã¯ãã¶ã€ã³ããŒã ã®ã³ãŒããŒãšããŠé
å±ãããWEBãµã€ãã®ãã£ã¬ã¯ã·ã§ã³ãæ
åœããŠããŸãããããããããŸããŸãªçµéšãç©ããªãã§åŸã
ã«çŸåšã®ã¹ã¯ã©ã ãšãã³ãžã§ãªã¹ãã«ã·ããããŠãã£ãã®ã§ããããã®ããã«äžåžãäŒç€Ÿãžã®èª¬åŸã»äº€æžãªã©ãç¹ã«å¿
èŠãªããŠããç§ã¯ãã£ã¡ã®æ¹åã«é²ã¿ããããããããªè³æ ŒãåããŸãããšèª¬æããã°ãåºæ¬çã«ã¯èªããŠããããŸãããããããããªãã¿ãããªããšãèšãããçµéšãã»ãšãã©ãªãã§ãããããªãçŸå Žã«ä»»ãããŠãããšããã¯ãããŸããã ãŸããäŒç€Ÿã®å¶åºŠã§ã¯ãN1!å¶åºŠããšãã£ãŠãç¹å®ã®åéã§çªåºããç¥èãšã¹ãã«ãæã£ã瀟å¡ãä»»åœãã1幎é100äžåã®æŽ»åè³éãå²ãåœãŠãä»çµã¿ããããŸããæŽ»åå
å®¹ã¯æ
åœæ¥åã®æ¹åãã瀟å
ã«ãããå°éåéã»æè¡ã®æå±ãç€Ÿå€æŽ»åãžã®åå ãªã©ããŸããŸã§ãåèªã®å°éæ§ãããã«ç£šãããšãã§ãããã§ããç§èªèº«ããã®å¶åºŠã掻çšããŠã¹ã¯ã©ã ãšãã³ãžã§ãªã¹ãã«ãªããçŸåšã§ã¯ç€Ÿå
å€ã«ã¹ã¯ã©ã ã®è¯ããåºããæŽ»åãè¡ã£ãŠããŸãã K.Nãã以å€ã«ãã瀟å
ã«ã¯äž»äœçã«æ°ããã¹ãã«ãç¥èã身ã«ã€ããããšãã人ãå€ãã®ã§ããããïŒ K.Nãã ããæããŸããããšãã°å匷äŒãããããšåŒã³ããããšãæ¯å2ã3人ã¯å¿
ããåå ãããããšæãæããŠãããŸããå
šäœçã«ãã¿ããªã§äžç·ã«åŠãã§ããããšããå§¿å¢ãæããããäŒç€Ÿã ãšæããŸãã M.Kãã 確ãã«ãå匷äŒã¯æŽ»çºã«è¡ãããŠããŸããããæ°ããæè¡ãã瀟å
ã®ç¥ããããæè¡ã¿ãããªãã®ã«ã€ããŠã誰ããå匷äŒãããããšææ¡ãããšããã«ã¡ã³ããŒãéãŸãæèŠããããŸããæ¥åæéå
ã§å匷äŒãè¡ãããšãèš±ããŠããããªã©äŒç€Ÿã®åŸæŒããããã®ã§ãç¥èãç²åŸãããã¹ãã«ã磚ãäžã§ã¯ãšãŠãæµãŸããç°å¢ã ãšæããŸãã 瀟å
ã«ã¯ããŸããŸãªã¢ãã«ã±ãŒã¹ãã è¥æãšã³ãžãã¢ã®ãã£ãªã¢ãã¹ã¯ïŒ æåŸã«ãã¿ãªããã®ãã£ãªã¢ãã¹ã«ã€ããŠäŒºããŸããA.MãããM.Kããã¯æ°åå
¥ç€Ÿãã6幎ç®ã§ããæ¬¡ã®ãã£ãªã¢ãå°æ¥ã®ãã£ãªã¢ã«ã€ããŠãçå£ã«èããé åãããšæããŸãããå
·äœçã«æããŠããããžã§ã³ãªã©ã¯ãããŸããïŒ A.Mãã æ£çŽãããã¯ãŸã æ©ã¿äžã§ããããã®ãŸãŸéçºè
ãšããŠçªãé²ãã§ããã®ãããããžã¡ã³ãå¯ãã®æ¹åæ§ã«ã·ããããŠããã®ãã瀟å
ã«ã¯ã©ã¡ãã®ã¿ã€ãã®å
茩ãããã®ã§ãè²ããªè©±ãèããŠåèã«ããªãããèªåã«åã£ãéãéžãã§ããããã§ãããäžåžãšã®1on1ãªã©ããã£ãªã¢ã«ã€ããŠçžè«ããããæãäžããŠèããããå Žãããã®ã§ãããããããŸã掻çšããªããèªåã®æããæç¢ºã«ããŠãããããšèããŠããŸãã M.Kãã åãåãããæ©ãã§ããŸããå
¥ç€Ÿåœåã¯ãããããã³ãŒããæžããŸããããã¿ãããªæãã§ããããæè¿ã¯åŸã
ã«ãããžã¡ã³ãã®åœ¹å²ãæ±ããããå Žé¢ãå¢ããŠããŸãããA.Mãèšãããã«ããããžã¡ã³ããšçŸå Žã§ã®éçºãèªåã®ãªãã§ã©ããã©ã³ã¹ããŠãããããããã¯ã瀟å
ã«ã¯å¹
åºãç¥èãæŽ»ãããŠãè²ããªããŒã ãæž¡ãæ©ããŠãµããŒããããããªäººãããŠãæ¬åœã«è²ã
ãªéããããªãšãããã¯ãè²ããªäººã®åããåèã«ããªããèŠå®ããŠããããã§ããã åç·šãã芧ãã ããïŒ ä»åã¯ãããã£ã®ã〠ãããã£ããŒã ã®ã€ã³ã¿ãã¥ãŒã®æ§åããå±ãããŸãããããããŠåç·šãã芧ãã ããã ãã€ã³ã¿ãã¥ãŒãäŒç€Ÿã®é¡ã«çãããµãŒãã¹ãææããéå§ããã〠ãããã£ãã®éçºã§æãããšã³ãžãã¢ãšããŠã®æé·ãã〠ãããã£åç·šã ãããã£ã§ã¯ãããŸããŸãªãããã¯ããžææŠãããšã³ãžãã¢ãçµ¶è³åéäžã§ãïŒ ãèå³ã®ããæ¹ã¯ä»¥äžã®æ¡çšãµã€ããããæ°è»œã«ãé£çµ¡ãã ããïŒ ãã®ã€ã³ã¿ãã¥ãŒã«é¢ããæ±äººæ
å ± /ããã°èšäº ãããã£æ ªåŒäŒç€Ÿ æ±äººæ
å ±
å
¥ç€ŸããŠããçµéšããŠããããšã«ã€ã㊠ããã«ã¡ã¯ïŒ2023幎ã«ãããã£ãžäžéå
¥ç€ŸããŸããã奜ç°ïŒããã ïŒãšç³ããŸãã å
¥ç€ŸããŠãã2幎ç®ã«çªå
¥ããŠãããŸããçŸåšã¯ã€ã³ãã©ã°ã«ãŒããšããŠäž»ã«ã«ã¹ã¿ããŒãµããŒãã§äœ¿çšããŠããç°å¢ã®éçšãè¡ã£ãŠããŸãã åè·ãããã«ã¹ã¿ããŒãµããŒãã§å©çšããŠããç°å¢ã®éçšãè¡ã£ãŠãããããã€ã³ãã©æ¥åã«é
å±ãããŠããã ããŸããããŸãã¯åè·ã§è¡ã£ãŠããããšã«ã€ããŠæžããŠãããããšæããŸãã åè·ã§è¡ã£ãŠããããš åè·ã§ã¯ãªãã¬ãŒã¿ãŒæ¥åã»ãããã£ã®ã·ã¹ãã ã®ç£èŠã»éçšæ¥åãè¡ã£ãŠãããŸããã ãªãã¬ãŒã¿æä»£ã®æ¥åããã£ãããšèšèŒããŸããšã以äžã®éãã§ãã ã»ã·ã¹ãã ã®ç£èŠ ã»åªäœäº€æäœæ¥ ã»æ©åšã©ã³ãã®å®æç®èŠ æå±ããŠãããªãã¬ãŒã¿ãŒã®ä»äºã¯ãæ¡ä»¶å¥ã«æé æžã䜿çšããç¶æ³ã«å¿ããç¹å®ã®æé ã«åŸã£ãŠå¯Ÿå¿ãè¡ã£ãŠãããŸããæé äŸå€æã¯æ
åœè
ãžé£çµ¡ãè¡ã圢åŒã§ããç£èŠããã·ã¹ãã ã®çš®é¡ããã¢ã©ãŒãã®å
容ãã¡ãŒã«ãé»è©±ã§ã®åãåãã察å¿ãåªäœäº€æãªã©ãããããã®ç¶æ³ã«å¿ããæé ãèšèŒãããŠããããã®æ°ã¯æå€§ã§çŽ100çš®é¡ã®æ¡ä»¶ãå¯Ÿå¿æ¹æ³ãèšèŒãããŠããŸããã éçšã«æºããããã«ãªã£ãŠããã¯ããªãã¬ãŒã¿åãã®æé ã®äœæãªã©ã宿œããŸããããéçšã«é¢ããæ
åœè
ã«ãã£ãŠäœæããæé ã®æ§æãç°ãªã£ãŠããããšãåå ã§ãªãã¬ãŒã¿ã確èªãèŸããªã£ãŠããŸããšããäºããããŸãããããã§ãããŒãäœæããå Žåããæé ã®èšèŒãçµ±äžåããå¿
èŠæ§ãåŠã³ãŸããã ç£èŠããŒã«ãšããŠã¯ãHPOMãäžå¿ã§ãZabbixãAS400ãdatadogãWindowsã¡ãŒã«ãªã©ã䜿çšããŠããŸããããžã§ã管çããŒã«ã¯ãA-AUTOãJP1ãªã©ãã¡ã€ã³ã§ããã ãã®äžã®å¯Ÿå¿ã§ç°åžžã¢ã©ãŒããæ€ç¥ããå Žåã¯æé ã«åŸã£ã察å¿ãé»è©±é£çµ¡çã®å¯Ÿå¿ã宿œããŠããŸãããæ£åžžã¢ã©ãŒãã«ã€ããŠãç¹å®ã®æé垯ã«åé¡ãªãåºåãããŠãããã確èªããŠããŸãã ãªãã¬ãŒã·ã§ã³ãã¹ã®å¯Ÿç äœæ¥ã察å¿ãè¡ã£ãŠãããšå®æœæŒããã察å¿ãã¹çãçºçããããšããããŸãããã®å¯Ÿçã€ããŠè©±ãåãã®ãããªããªãåæãã§ãããå
ã
ã¯æäŒæ¥ã§è¡ã£ãŠãããšãããŠããŸãã ãã®ããªããªãåæãã«ã€ããŠç°¡æœã«èª¬æããŸããšãçºçããäºè±¡ããå®éã«è¡ã£ãè¡åã«ããããããªãïŒããšããåããããç¹°ãè¿ãããšã§ãåé¡ã®æ ¹æ¬çãªåå ã远æ±ããŠããã®ãç¹åŸŽã§ãç®çãšããŠã¯ãåé¡ã®æ ¹æ¬åå ãç¹å®ãã解決ãå質åäžãç®æããšãã£ããã®ã§ãã®ã§ã宿œããã®ã«ããã£ãŠã¯å¯ŸçãŸã§é²ããŠããã®ã«ã¯æéãèŠããŸãããåçºé²æ¢çãªã©ã®æ€èšã«ã¯åœ¹ç«ã€ãããããŸããã ãããã£ã«å
¥ç€Ÿã㊠å
¥ç€ŸããŠããã¯ãäž»ã«ãµããŒãVDIç°å¢ã«ãããDaasã®ç°å¢ãããªã³ãã¬ãã¹ãæ§ç¯ã»èšèšã»éçšãè¡ã£ãŠããŸãããçŸåšç§»è¡äžã®ç°å¢ããããŸãããéæå¯Ÿå¿ãè¡ã£ãŠãããŸãã æé·ãããšæãäº éçšæ¥åãã¡ã€ã³ã§ãã£ããããæ§ç¯ã«é¢ããæ©äŒããããŸããã§ãããããµããŒãVDIç°å¢ãªãã¬ã€ã¹ãæ
åœãããŠããã ããããšã§ãæ§ç¯ãè¡ã£ãäºããä»ãŸã§ã§ã¯çµéšããŠããªãã£ãäºãçµéšã§ããããšã¯ä»åŸã«ã掻ãããã®ã§ã¯ãªãããšæã£ãŠããŸãã å±äººåè§£æ¶ã«åã㊠å±äººåã¯ãã€ã®æã§ãåºãŠãã課é¡ã«ãªãããšã¯æããŸããæ°ã«ããããã§ãèšèšåã³ã詳现èšå®ã«ã€ã³ã¹ããŒã«ããã¢ããªã®èšå®è©³çްãããŒã¿ãæ®ããŠãããŠãããšããŠãããã¡ããšå
éšã§å
±æããŠãããªããšãä»åŸå¯Ÿå¿ã«æºãã£ã人ãå
ã®èšå®ã¯äœã ã£ãã®ãäžæã®ç¶æ³ãåºãŠããããšæããŸãããªããªãæ§ç¯ãè¡ãã€ã€ãææžåãã€ã€å
±æãè¡ã£ãŠããäºã¯å€§å€ããšæããŸãããã©ã®ãããªèšå®ãè¡ã£ãã®ããã€ã³ã¹ããŒã«å®è¡æã«ããããã©ã¡ãŒã¿ã®èšå®ã¯äœãèšå®ããã®ã詳现ã«èšããŠãããªãããã°ãæ§ç¯æã¯ããçšåºŠèšæ¶ããŠãããã®ã§ãããåœæã¯ã©ãã ã£ãã®ããæéãçµã€ã«ã€ãæ§ãã«ãªã£ãŠãããã®ããšæããŸãããã®ããã«ã¯ä»æ§ã ãã§ã¯ãªãã詳现ã«èšå®ããé
ç®ããã¡ããšæ®ããŠãããªããã°ãªããªããšèããŠããŸããåè·ã®çµéšã掻ãããããã¥ã¡ã³ããçµ±äžæ§ããã£ãŠäœæããããšã§ã誰ãèŠãŠãåãããããå¯Ÿå¿æé ã®äœæãå¿ãããè¡ããããŒã ã®ã¡ã³ããŒãšã¯å®æçã«å¯Ÿå¿ããå
容ããèšå®é
ç®ã®å
±æãè¡ããå±äººåè§£æ¶ã«åãããã¥ã¡ã³ãã®æŽåãç¶ããŠããŸãã æåŸã« åè·ã§ã¯éçšã®æ¥åãããªãã¬ãŒã·ã§ã³ãè¡ã£ãŠããŸãããããããã£ã«å
¥ç€ŸããŠããã¯ãããã¥ã¡ã³ã以å€ã«ãæ§ç¯ã®åéã§ãã£ããããªãã¬ã€ã¹å¯Ÿå¿ãæ°ããªæ¥åã«ãææŠããŠããã®ã§ããŸã ãŸã æªçãªãšããã¯å€ã
ãããŸããããã®äžã§æ°ããªåŠã³ãåŸãããšã§ä»åŸãæé·åºæ¥ãããšæããŸãã ãã¹å¯Ÿçã®ãªããªãåæã«ã€ããŠã¯çµæ§æåãªãã®ã§ãã®ã§ããèå³ã®ããæ¹ã¯æ
å ±ãæ²¢å±±ãããŸãã®ã§ã調ã¹ãŠããã ããšè¯ãããªãšæããŸãã
ã¯ããã« äŒå¡ã·ã¹ãã ã°ã«ãŒãã®kiqkiqã§ãã èªããŒã ã§ã¯awsã®ã€ã³ãã©ã¯Terraformã§ç®¡çããŠããŸããTerraformã¯ã€ã³ãã©ã¹ãã©ã¯ãã£ãã³ãŒããšããŠç®¡çãã䟿å©ãªããŒã«ã§ãããã®äŸ¿å©ãã®äžã«ã泚æãã¹ãå
容ããããŸããä»åã¯ãªãœãŒã¹äœææã«ééãããäºæãã¬ãªãœãŒã¹ã®äžæžãã«ã€ããŠå
±æããããšæããŸãã ééããåé¡ èªããŒã ã§ã¯åäžAWSã¢ã«ãŠã³ãå
ã§è€æ°ã®Terraformãããžã§ã¯ããå©çšããŠãããæ°ä»ããåãååã®EventBridge RuleãTerraformã§å®çŸ©ããŠããŸããŸããããã®ç¶æ³ã§åäžåç§°ã®EventBridge Ruleããããã€ãããšãããšã©ãŒãçºçããã®ã§ã¯ãªãå
ãããã£ããªãœãŒã¹ã®å
容ãäžæžããããšããæåã«ééããŸããã äŸãã°ã以äžã®ãããªaws_cloudwatch_log_groupã®ãªãœãŒã¹ãäœæããå Žåãåã /example/example_logs ãšãããã°ã°ã«ãŒãã®ãªãœãŒã¹ããããš terraform apply æã«ãšã©ãŒãšããŠåºåãããŸãã resource "aws_cloudwatch_log_group" "example_logs" { name = "/example/example_logs" # ... ãã®ä»ã®èšå® ... } ãããã以äžã®ãããªaws_cloudwatch_event_ruleã®ãªãœãŒã¹ãäœæããå Žåã example-rule ãšããEvent Ruleã®ãªãœãŒã¹ããã§ã«åã¢ã«ãŠã³ãå
ã«ååšããŠãäžæžããããŠããŸããŸãã resource "aws_cloudwatch_event_rule" "example_rule" { name = "example-rule" description = "æ°ããã«ãŒã«" # ... ãã®ä»ã®èšå® ... } åäžTerraformãããžã§ã¯ãå
ã§å®çŸ©ããŠããå Žåã¯ãplanå®è¡æã« Error: Duplicate resource "aws_cloudwatch_event_rule" configuration ãšãããšã©ãŒãçºçããŸããããããä»åã®ããã«å¥ãããžã§ã¯ãã§ç®¡çããŠããšterraform planæã®å·®åã§ã¯ç¢ºèªã§ããã terraform apply ã§ããšã©ãŒãçºçããã«ãããã€ã§ããŠããŸããŸãã äºé²çã®äŸãšããŠã¯ä»¥äžã®ãããªãã®ãæããããŸãã åäžã¢ã«ãŠã³ãå
ã§è€æ°ã®Terraformãããžã§ã¯ããå©çšããŠããå Žåã¯ãããžã§ã¯ãå
šäœã§ã®åœåèŠåãçµ±äžããã¬ãã£ãã¯ã¹ãªã©ã§åãã ååããããŠæç€ºçã«æå®ããèªåæ¡çªã«ä»»ãã ããããã¡ãªãããã¡ãªããããããä»ã«ãæ¹æ³ã¯ãããã§ããããšæãã®ã§ç¶æ³ã«å¿ããŠé©åãªãã®ãåãå
¥ããŠã¿ãŠãã ããã ãŸãšã ãã®ããã«ãªãœãŒã¹åã®éè€ãããå Žåã倧åã®ãªãœãŒã¹ã¯ terraform apply å®è¡æã«ãšã©ãŒãšããŠåºåããŠãããŸããäžéšã®ãªãœãŒã¹ã§ã¯ãšã©ãŒã«ãªããæ¢åãªãœãŒã¹ãæŽæ°ãããå ŽåããããŸããä»åã®å Žåã¯Terraformãããžã§ã¯ããåãããŠãããšããããšããããæ¢åãªãœãŒã¹ãäžæžããããŠããŸã£ãŠããããšã«æ°ä»ãã®ãé
ããŸãããç¹ã«Event Ruleã¯å®æå®è¡ããããŸã§æ°ã¥ããé害ã«ãªãå¯èœæ§ãããããæ°ãã€ããŠãã ããã åè é¢é£issue: https://github.com/hashicorp/terraform-provider-aws/issues/25598
ã¯ããã« åºå¹¹ã·ã¹ãã ã°ã«ãŒãã®å³¶ã§ãããã®èšäºã§ã¯ãã»ã©AIã«è©³ãããªãç§ãRoo Codeã䜿ã£ãŠå®éã«ã³ãŒãã£ã³ã°ããŠã¿ãäœéšãæžããŸãã Roo Codeã¯ç°¡åã«äœ¿ããã®ã§AIã®å©çšã«äžæ
£ããªäººã«ãªã¹ã¹ã¡ã ãšæããŸããããããã£ã人ã®åèã«ãªãã°ãšæããŸãã â» Roo Codeã«ã€ããŠã¯å
¬åŒã®ãªããžããªãåç
§ãã ãã 1 ãã®æ¹æ³ã¯GitHub Copilotãå©çšå¯èœãªç¶æ
ã«ãªã£ãŠããããšãåææ¡ä»¶ã§ã ã€ã³ã¹ããŒã« VSCodeã®æ¡åŒµæ©èœããŒã±ãããã¬ã€ã¹ãããRoo Codeããšæ€çŽ¢ãããšRoo CodeãåºãŠããã®ã§ã€ã³ã¹ããŒã«ããŸãã æ¡åŒµæ©èœããRoo Codeãã€ã³ã¹ããŒã« ã€ã³ã¹ããŒã«ãããšå·ŠããŒã«ãã±ããã®ã¢ã€ã³ã³ã衚瀺ãããã®ã§ãããããRoo Codeãå©çšã§ããŸãã ãã±ããã®ã¢ã€ã³ã³ãã¯ãªã㯠以äžã§ã€ã³ã¹ããŒã«ã¯å®äºã§ããæ¬¡ã«åæèšå®ãè¡ããŸãã åæèšå® å©çšããã¢ãã«ãèšå®ãã ã¯ããã«å©çšããAPIãããã€ããŒãšèšèªã¢ãã«ãèšå®ããŸãã API Providerã¯ã VS Code LM API ããéžæããŸããããã¯GitHub CopilotãæäŸããŠããAPIã§ãGitHub Copilotã䜿ããç¶æ
ã§ããã°è¿œå 課éãçºçããã现ããèšå®ãäžèŠã§æ°è»œã«äœ¿ããŸãã Language Modelã¯ã奜ã¿ã®ã¢ãã«ãéžãã§ãã ãããä»åã¯ã copilot -claude-3.5-sonnet ãã«ããŸããã APIãããã€ããŒãšèšèªã¢ãã«ã®èšå® æš©éãèšå®ãã æ¬¡ã«Roo Codeã®æš©éãèšå®ããŸããç»é¢äžéšã®ãAuto-approveããšæžãããŠããéšåãã¯ãªãã¯ãããšæš©éèšå®ã衚瀺ã§ããŸãã æš©éèšå®ã®éãæ¹ æš©éèšå®ã®éãæ¹ æš©éèšå®ã®éãæ¹ Auto-approveã«ãã§ãã¯ãã€ãããšæ¿èªãã¿ã³ãæŒããªããŠãèªåã§ã³ãŒããèªãã§å€æŽããŠãããŸãã ç§ã¯Roo Codeãã©ã®ã³ãŒããèªãã§ã©ããã倿Žãããããçè§£ããªããé²ãããã£ãã®ã§Auto-approveã¯ãªãã«ããŠãæ¿èªããªããé²ããããã«ããŸããã æš©éã¯ã³ãŒããèªãã§å€æŽããŠãããã ããªããRead files and directoriesããšãEdit flesãã«ãã§ãã¯ãä»ããŠããã°åé¡ãªãã§ãã æš©éèšå® æš©éèšå® æš©éèšå® 以äžã§Roo Codeãå©çšããæºåãã§ããŸãããããããã¯å®éã«Roo Codeã䜿ã£ãŠã³ãŒãã£ã³ã°ããŠãããŸãã å®éã«ã³ãŒãã£ã³ã°ããŠã¿ã äžéšã®å
¥åæ¬ã«ããã³ãããå
¥åããŸããä»åå
¥åããããã³ããã¯ä»¥äžã§ãã slack.rsã®352è¡ã§æçš¿æ°ãå€ããšSlack APIã®rate limitãšã©ãŒã«ãªã£ãŠããŸããäžåºŠãŠãŒã¶ãŒæ
å ±ãååŸãããŠãŒã¶ãŒã«ã€ããŠã¯SlackAPIãåŒã°ãã«ãŠãŒã¶ãŒåãèšå®ããããã«å€æŽããAPIã®åŒã³åºãåæ°ãæžãããã ããã³ãããå
¥å ããã³ãããå
¥å ããã³ãããå
¥å ãã£ãšãã£ããããããã³ããã§ãåããŸãã詳ããæžããæ¹ã粟床ã¯äžãããŸãã ããã³ãããéããšslack.rsãèªã¿ãããšè¿ã£ãŠããŸãããApproveãæŒããŠæ¿èªããŸãã ããã³ãããžã®ã¬ã¹ãã³ã¹ ããã³ãããžã®ã¬ã¹ãã³ã¹ ããã³ãããžã®ã¬ã¹ãã³ã¹ ã³ãŒãã®åé¡ç¹ãšå€æŽå
容ã®èª¬æãæç€ºãããŸããããããŠå€æŽããã³ãŒããæç€ºãããŸããSaveãæŒããšå€æŽããã³ãŒããä¿åãããŸããRejectãæŒãããã远å ã§å¥ã®æç€ºãéããšå¥ã®ä¿®æ£æ¡ãæç€ºããŠãããŸãã 倿ŽãããœãŒã¹ã³ãŒããšãã®èª¬æã衚瀺ããã 倿ŽãããœãŒã¹ã³ãŒããšãã®èª¬æã衚瀺ããã 倿ŽãããœãŒã¹ã³ãŒããšãã®èª¬æã衚瀺ããã Saveãããšæ¬¡ã®ä¿®æ£ç®æãæç€ºãããŸããããã確èªããŠåé¡ãªããã°SaveããŸãã æ¬¡ã®ä¿®æ£ã³ãŒããæç€ºããã æ¬¡ã®ä¿®æ£ã³ãŒããæç€ºããã æ¬¡ã®ä¿®æ£ã³ãŒããæç€ºããã ãããç¶ããŠãã£ãŠãã¹ãŠã®ä¿®æ£ãå®äºãããšTask CompletedãšãªãçµäºããŸãã ãã¹ãŠã®ä¿®æ£ãçµãããšTask Completedãšãªãçµäºãã ä¿®æ£ããããœãŒã¹ã§ããæ°è¡ã®ä¿®æ£ã§ããã°ã確èªããªããã§ã1~2åã§çµãããŸããè€æ°ãã¡ã€ã«ã®ä¿®æ£ããã¡ããããŠãããŸãã ææ 1åã®ããã³ããã§å€æŽç®æã®ç¹å®ããè€æ°ã®ã³ãŒãä¿®æ£ãŸã§ãã£ãŠãããã®ã§äœ¿ããããã£ãã§ãããŸãæ¥æ¬èªã«å¯Ÿå¿ããŠããã®ãå¬ãããã€ã³ãã§ãã èªåã¯ä»åŸä»¥äžã®ãããªäœ¿ãæ¹ãããããšèããŠããŸãã èªåã§å€æŽããã³ãŒãã®çãåãããããè¯ã倿޿¡ãææ¡ããŠããã æåã«Roo Codeã«ã³ãŒã倿ŽããŠãããããããããŒã¹ã«èªåã§åŸ®èª¿æŽãã æ¯åå®ç§ãªã³ãŒããæžããããã§ã¯ãªãã®ã§ã人ã®ç®ã«ãããã§ãã¯ã¯å¿
èŠã§ãã äœè«ã§ããæè¿ã¯GitHub CopilotãGitHubäžã§ãã«ãªã¯ãšã¹ãã®ã¬ãã¥ãŒãããŠãããã®ã§AIã«æžãããŠAIã«ã¬ãã¥ãŒããŠãããããšãã§ããŸãã GitHub Copilotã«ãããã«ãªã¯ãšã¹ãã®ã³ãŒãã¬ãã¥ãŒ ç°¡åã«äœ¿ããã®ã§ãã²äœ¿ã£ãŠã¿ãŠãã ããã èæ³š Roo-CodeïŒ https://github.com/RooVetGit/Roo-Code ïž
Cloudflare管çè
ãããŠããç³å·ã§ãã å
æ¥éå¬ãããCloudflare Meet-upã§ãCloudflare Streamã䜿ã£ãç°¡ååç»é
ä¿¡ããšããã¿ã€ãã«ã§LTããŠããŸããã Cloudflare Meet-up Tokyo Vol.7 – connpass å人çã«Cloudflareã¯2幎ã»ã©åãã䜿ã£ãŠãŸããããäŒç€ŸãšããŠã¯ä»åãåå°å
¥ãšãªããŸããåã
ããCloudflare䜿ããããªãšããã·ãŒã³ã¯ãã£ãã®ã§ãããä»åã¡ããã©ããå
容ãšã¿ã€ãã³ã°ã§ããã®ã§å°å
¥ãšçžæããŸããã å°å
¥åŸã«ãŸãèæ
®ããã®ã¯æ§æç®¡çã§ãããCloudflareã¯TerraformãµããŒãããŠããŸãã çŸç¶ã¢ã«ãŠã³ã管çã ãIaCåããŠéçšããŠããŸãïŒStreamã¯ã³ã³ãã³ã管çãããªãã®ã§æ§æã¯äžèŠïŒ åèïŒ Overview · Cloudflare Terraform docs WorkersãPagesã䜿ã£ãŠãããšãã«ãæããŠããŸããããè€éãªããšãããªããã°Cloudflareã¯ããªã䜿ãããããã©ãããã©ãŒã ã ãšæããŸããStreamã®ãã®äŸã«æŒããåç»é
ä¿¡ç°å¢ãç°¡åã«äœããŸãããè²»çšèŠç©ãããããããã£ãã®ãä»åãšãŠãå©ãããŸããã ä»ã®æ¹ã®LTã§æ°ã«ãªã£ãããš PagesãšWorkersçµ±åã®æ°é
åã
ããã¡ããã¡ãã確床ã®é«ãåã§ãã£ãWorkersãžã®çµ±åã åèïŒ æè¿ã®Cloudflare Workers – ããŒããã¹ãŒæ¥èš Pagesãªããªããšããããå°ããã§ããããäºãã®ãããšããã©ãã®åœ¢ã§çµ±åããŠã»ããã§ããã 4æã5æã«è¡ãããã§ãããDeveloper Weekã§çºè¡šãããå¯èœæ§ãããã®ã§èŠãã§ãã¯ã§ãã åèïŒ Developer Week | Cloudflare Cloudflareã®ãã£ãããšããæš©é Cloudflareã§ã¢ã«ãŠã³ã管çãåºããŠããç§ãç¥ã£ãã®ã§ãããçµæ§ãã£ãããšããRoleããçšæãããŠããŸããã åèïŒ Account roles · Cloudflare Fundamentals docs Pagesã§ãã«ããã°ã ãèŠãããã®ã«ãWorkersã®Adminæš©éãäžããªããšãããªããªã©ãéå°æš©éã§éçšã匷ããããã·ãŒã³ããããä»åŸã®çµç¹ã§ã®å©çšã§ã¡ãã£ãšé ãæ©ãŸããŠããç¹ã§ãã ãã®ããããä»åŸã¢ããããŒãããããšå¬ããã§ããã
ãããã£æ ªåŒäŒç€Ÿã®ä»²äžã§ãã以åNotionã§ã®äœå³ã«ã€ããŠèšäºãæžããŸããã ã2023幎12æçãNotionã®äœå³æ©èœç޹ä»(äŒç€Ÿç·š) ä»åã¯draw.ioïŒDiagrams.netïŒã«ç¹åããã話ãããŸããNotionã§draw.ioã䜿ã£ãäœå³ãããŠå°ã£ãŠããæ¹ã¯åèã«ããŠã¿ãŠãã ããã ã¯ããã« èšèšãšãèŠä»¶æŽçãšãããŠãããšãããdraw.ioã§å³ãæžãããšãå¢ããŸãã ãã ããããã£ãç»åãpngãjpegã§è²Œãä»ãããšãããšããç·šéã§ããªããŠå°ãããšããããŸã(ç·šéå
ã®ãã¡ã€ã«ã¯ãã€ãã©ã€ãã®éã®äžãžâŠâŠ)ã ãããªæ©ã¿ã®è§£æ±ºæ¹æ³ã«ã€ããŠè©±ããŠãããŸãã ãã®1 SVGã§ãšã¯ã¹ããŒãããã¹ã draw.ioã¯SVG圢åŒã§ãèªã¿èŸŒãããšãã§ããŸãã SVGã¯æ±çšçãªãã¡ã€ã«åœ¢åŒã§ã©ãã§ã䜿ãããšãã§ããã®ã§ãåºæ¬ãã®åœ¢åŒã§ä¿åããããšãããããããŸã(çã®draw.ioã¯ç¬èªåœ¢åŒã®XMLãã¡ã€ã«)ã ãã®2 Notionã«ããŒã¹ããã¹ã SVGã«ãšã¯ã¹ããŒãããŠããå
±æã§ããå Žæã«ã¯ã£ãŠãããªããã°æå³ããããŸããã Notionã«è²Œã£ãŠã誰ã§ãèŠããããã«ããŸãããã ãã®3 draw.ioã®æ¡åŒµæ©èœããããã¹ã ã¶ã£ã¡ãããããŸã§ã¯ãã®æ©èœã䜿ãããã®å座ã§ãããªãã§ãã draw.io for Notion – Chrome Web Store ãã®æ¡åŒµæ©èœãããããšNotionäžã§çŽæ¥SVGãã¡ã€ã«ãç·šéã§ããŸãã ãŸãšã å
šãã¡ã€ã«SVGã«ããŠãããïŒ
éå®³å ±åãèªåçæããbot ã¯ããã« ããã«ã¡ã¯ïŒSREããŒã ã®å³¶ã§ããæ®æ®µã¯ã·ã¹ãã é害ã«ããã客æ§åœ±é¿ãæžããããã«ããŒã ãæšªæããSRE掻åãããŠããŸãã ä»åã¯Slackã®äŒè©±å±¥æŽããéå®³å ±åãèªåçæããŠãããbotãäœã£ãã®ã§ã玹ä»ããŸããä»ç€Ÿã§ã䌌ããããªäºäŸã¯ããèŠãããŸãããäºäŸãå€ããšããããšã¯åããããªèª²é¡ãæ±ããŠãã人ãå€ããšããããšã ãšæãã®ã§ãåèã«ãªãã°ãšæããç§ã®äœéšãæžããŸãã ãããªäººã«èªãã§ã»ãã ãã®èšäºã¯ä»¥äžã®ãããªèª²é¡ãæ±ããŠãããšã³ãžãã¢ãSREã®æ¹ã«ç¹ã«èªãã§ã»ããã§ãã éå®³å ±åãæžãã®ã«æéãããããæ
å ±ãéããŠããã®ãå€§å€ é害察å¿äžã«éäžããå
¥ã£ãŠãã人ã«ç¶æ³ã説æããã®ãå€§å€ éå®³å ±åãæžãè² æ
ãæžãããã äœã£ãèæ¯ 課é¡ãææ¡ãã é害察å¿ã£ãŠå€§å€ã§ããããç§ã¯ã§ããã ãé害察å¿è
ã®è² æ
ãæžãããããšèããŠããŸãããããã§ãŸãã¯é害察å¿ã«ããã課é¡ãææ¡ããããã«ãšã³ãžãã¢å
šå¡ãžãµãŒãã€ã宿œããŸããã ãµãŒãã€ã®çµæ ãµãŒãã€ã®çµæ ãµãŒãã€ã®çµæ ãã®çµæãã éå®³å ±ãæžãã®ã倧å€ã»è² è·ã倧ããã ãšããæèŠã忰以äžã®äººããæãããŸãããä»ã«ãããŸããŸãªèª²é¡ãèŠæãæãã£ãã®ã§ãããããã®èª²é¡ã«ãªãèªåã§ãããã«ã¢ãããŒãã§ããã®ã§ã¯ããšæããä»åã®éçºã«è³ããŸããã ãããã£ã®é害察å¿ãã㌠ãããã£ã§ã¯é害ãçºçãããšãã®é害ã®å°çšãã£ã³ãã«ãäœãããã£ã³ãã«å
ã§ãããšããè¡ãã«ãŒã«ãšãªã£ãŠããŸãã ãããã£ã®é害察å¿ãããŒãç°¡åã«ãŸãšãããšä»¥äžã®ããã«ãªããŸãã ãããã£ã®é害察å¿ãããŒïŒæŠç¥ïŒ ãããã£ã®é害察å¿ãããŒïŒæŠç¥ïŒ ãããã£ã®é害察å¿ãããŒïŒæŠç¥ïŒ ãã®ãããŒãšãµãŒãã€çµæãèžãŸãããšä»¥äžã®ãããªèª²é¡ãèŠããŠããŸããã æ
åœè
ã¯é害察å¿ãããªããéå®³å ±ãæŽæ°ããªããã°ãªããªã éäžããé害察å¿ã«åå ãã人ãäžç®ã§ç¶æ³ãçè§£ãã¥ããïŒäººã«èããããã£ã³ãã«ãèªã¿è¿ãããæŽæ°äžã®éå®³å ±ãèªããããªãïŒ æ
åœè
ã¯åŸæ¥ãSlackã®äŒè©±ãèŠè¿ããªããéå®³å ±ã宿ãããªããšãããªã ãã®èª²é¡ã«ã¢ãããŒããããããé害æ
å ±ãèŠçŽããbotãäœæããéå®³å ±äœæã®è² æ
軜æžã詊ã¿ãŸããã é害èŠçŽbotã®æŽ»çšã€ã¡ãŒãž é害èŠçŽbotã®æŽ»çšã€ã¡ãŒãž é害èŠçŽbotã®æŽ»çšã€ã¡ãŒãž 以äžã®èæ¯ãèžãŸããŠãä»åäœæããbotã«ã€ããŠã玹ä»ããŸãã äœã£ããã® é害èŠçŽbot ä»åäœã£ãbotããé害èŠçŽbotããšåä»ããŸããã 圌ã¯Slackãã£ã³ãã«å
ã®äŒè©±å±¥æŽãèªã¿åã£ãŠé害æ
å ±ãèŠçŽããŠãããŸãã 圌ã¯ä»¥åãããããã£ã«ååšãããmyfriendGPTããšããæèœãªåéïŒç€Ÿå
ããŒã«ïŒã®ãœãŒã¹ãããŒã¹ã«äœããŸããã 1 ããŒã¹ãšãªã£ã瀟å
ããŒã«ãmyfriendGPTã ã€ãŸã圌ã¯myfriendGPTã®åŒåã§ãããããã£ãæå³ã蟌ããŠãããã£ãŒã«ã®é¡åçãmyfriendGPTãšåãWEBãµã€ãïŒThisPersonDoesNotExistïŒã§äœæããŸããã https://this-person-does-not-exist.com/en å®éã«äœ¿ã£ãŠã¿ã äœã£ãé害èŠçŽbotãå®éã«äœ¿ã£ãŠã¿ãŸããã äœ¿ãæ¹ã¯èŠçŽããããSlackãã£ã³ãã«ã§é害èŠçŽbotãžç©ºã¡ã³ã·ã§ã³ãéãã ãã§ãã é害èŠçŽbotã®äœ¿ãæ¹ã空ã¡ã³ã·ã§ã³ãéãã ãã§åŒã³åºãã äœ¿ãæ¹ã¯ãªãã¹ãã·ã³ãã«ã«ããŠèª°ã§ã䜿ããããã«ããŸãããéå®³å¯Ÿå¿æã«ãã䜿ããªãããè€éãªæäœãå¿
èŠã ãšäœ¿ãæ¹ãå¿ããŠããŸã£ãããé¢åã§äœ¿ããªããªã£ãŠããŸããšèããããã§ãã æ°ç§åŸ
ã€ãšé害æ
å ±ã®èŠçŽãè¿ããŠãããŸãã è¿ã£ãŠããé害æ
å ±ã®èŠçŽ äŒãåãå€ãèŠã¥ãããŠãã¿ãŸããã Slackã®äŒè©±å±¥æŽããèªã¿åããæ
å ±ãèŠçŽããŠãããŸããSlackããèªã¿åããªãæ
å ±ïŒãã®äŸã§ã¯åœ±é¿éé¡ãšåœ±é¿ãŠãŒã¶ãŒæ°ïŒã¯ãäžæããšè¿ãããŸããè¿ãé
ç®ã¯éå®³å ±ã®ãã©ãŒãããã«åãããŠããã®ã§ãããããã®ãŸãŸéå®³å ±ã«ã³ããŒããããšãã§ããŸãããã¡ããAIãªã®ã§æ
å ±ãæ£ããã粟æ»ã¯å¿
èŠã§ããã 察å¿ãã°ããšã¹ã«ã¬ãŒã·ã§ã³ãããŒãè¿ããŠãããŸããïŒäžã®ãã£ããã£ã®ç¶ãã§ãïŒ è¿ã£ãŠãã察å¿ãã°ããšã¹ã«ã¬ãŒã·ã§ã³ãã㌠人åã§å¯Ÿå¿ãã°ãæžããšãªããšSlackãé¡ã£ãŠäœæäœåã«äœãèµ·ãããã調ã¹ãªããšãããªãã®ã§å€§å€ã§ãããã察å¿ãã°ã®äœæã«ã¯ç¹ã«é害èŠçŽbotã®æŽ»èºãæåŸ
ããŠããŸãããšã¹ã«ã¬ãŒã·ã§ã³ãããŒãmermaid圢åŒã§è¿ããŠãããã®ã§ãäŸãã°ãšã³ãžãã¢ä»¥å€ã®æ¹ãªã©ããã°ã©ãã³ã°ã®ç¥èãããŸããªãæ¹ã§ããšã¹ã«ã¬ãŒã·ã§ã³ãããŒãæžãããããªãã®ãå¬ãããã€ã³ãã§ãã ãã®èŠçŽãèŠãããšã§éäžããåå ãã人ã§ãçŽ æ©ãç¶æ³ãçè§£ã§ããŸãããScribeïŒèšé²ä¿ïŒã®äººã¯èŠçŽãåèã«ããããšã§éå®³å ±ãæžãæéãåæžã§ãããšæåŸ
ããŠããŸãã myfriendGPTããã®å€æŽç¹ äžã®ç« ã§ãæ¢åããŒã«ã§ããmyfriendGPTãããŒã¹ã«é害èŠçŽbotãäœæãããšæžããŸãããããã§ã¯ããŒã¹ãšããããŒã«ãããã©ãããããªãã倿Žããã®ã説æããŸãã 1. ãã£ã³ãã«å
šäœã®äŒè©±ãèªã¿èŸŒãããã«ãã myfriendGPTã¯1察1ã®å¯Ÿè©±åŒã§äœ¿ãbotãªããšããããã¹ã¬ããå
ã®äŒè©±ã®ã¿èªã¿åã仿§ã«ãªã£ãŠããŸããä»åã®é害èŠçŽbotã¯è€æ°äººã®äŒè©±ãèŠçŽãããšãã圹ç®ããã£ãã®ã§ããã£ã³ãã«å
šäœãèªã¿èŸŒãããã«ããŸããã ãããèªã¿èŸŒãããŒã¿éãå¢ãããšãã®åAPIã®Rate Limitãšã©ãŒãªã©ã®ãšã©ãŒãèµ·ãã確çãäžãããšããåé¡ããããŸãããããã§ãšã©ãŒã®çºçãæžãããèŠçŽã®ç²ŸåºŠãäžããããã«ä»¥äžã®ãã€ã³ãã工倫ããŸããã 倧éã®æ·»ä»ãã¡ã€ã«ãèªã¿èŸŒããšãšã©ãŒãçºçããã®ã§ãã¡ãã»ãŒãžã«æ·»ä»ãããç»åããã¡ã€ã«ã¯èªã¿èŸŒãŸãªãããã«ãã èªã¿èŸŒãã¡ãã»ãŒãžæ°ãå€ããšãšã©ãŒã«ãªã£ãŠããŸãã®ã§ãéå»ã®éå®³å¯Ÿå¿æéãã¡ãã»ãŒãžæ°ãåèã«èªã¿èŸŒãã¡ãã»ãŒãžãçŽè¿7æ¥éãæå€§1000ä»¶ãŸã§ã«å¶éãã 人é以å€ã®çºèšãèªã¿åããšèŠçŽã«äœèšãªæ
å ±ãå
¥ã£ãŠããŸãããã人éã®çºèšã®ã¿èªã¿åãããã«ãããäžã®ãã£ããã£ããã®äŸã§ãã ã¢ããªããã®éç¥ã人éã®çºèšã§ã¯ãªãã¡ãã»ãŒãžãããããç¡èŠããããã«èšå® ããããç¡èŠããªããšäººé以å€ã®çºèšãèŠçŽã«å«ãŸããŠããŸãç²ŸåºŠãæ¬ ã 2. æçš¿æ¥æã æçš¿è
ãååŸããããã«ãã ã¡ãã»ãŒãžã®æçš¿æ¥æãšæçš¿è
åãAIã«æž¡ãããã«ããŸãããããããããšã§ãã€ã誰ããšããæ
å ±ãèªãã§ãããã®ã§ããã詳现ãªèŠçŽãäœæããŠãããŸãã When,Whoãæž¡ãããšã§ãã詳现ãªèŠçŽãäœæããŠããã ãªãAIéçºæªçµéšã§äœæã§ããã®ã 1ãããã®ãããªbotãäœãã®ã¯çµæ§å€§å€ã ãšæããŸããèªåãAIã®éçºçµéšããªãã£ãã®ã§äœããªãç¶æ
ããéçºããã®ã¯ããããç¡çã§ããã ã§ã¯ä»åãªãé害èŠçŽbotãäœãã®ããšãã§ããã®ãããã®èŠå ãã玹ä»ããŸãã ããŒã¹ãšãªããœãŒã¹ã³ãŒããã€ã³ããŒãœãŒã¹åãããŠãã ããŒã¹ã«ã§ãããœãŒã¹ã³ãŒãã瀟å
ã«ååšãããã®ã³ãŒãããå©çšã§ããç¶æ
ã«ãªã£ãŠãããããšãèŠå ãšããŠæããããŸããããŒã¹ã«ããmyfriendGPTã¯ã€ã³ããŒãœãŒã¹å 2 ãã€ãŸã瀟å
ã§äœ¿ãããªãŒãã³ãœãŒã¹ãšãªã£ãŠããŸããããã®ããã åèŠã§ãçè§£ããããããã«READMEãå
å®ããŠãã 2次å©çšããããšãæè¿ããã ãšããåŸæŒãããããã¹ã ãŒãºã«å©çšã§ããŸããã ãŸããã¡ããã©ã¿ã€ãã³ã°ãããã³ã³ããªãã¥ãŒãã詊ãäŒããšããã詊ãã§ã€ã³ããŒãœãŒã¹ã®ã³ã³ããªãã¥ãŒã 3 ãããŠã¿ãããšãã瀟å
å匷äŒããããããã«åå ããŠããããšã§ãã®ãœãŒã¹ã䜿ãããã ãšæãã€ããŸããããŸãã«ã€ã³ããŒãœãŒã¹ã®å©ç¹ã掻ããããšãã§ããŸããã æ¥ã
æ
å ±åéããŠãã ããã¯å¥œãã§ç¶ããŠããããšãªãã§ãããã¹ããæéã«ä»ç€Ÿã®å匷äŒã®è³æããã§ãã¯ããããSNSãèŠãŠæ°ã«ãªã£ãæè¡èšäºãæ¥ã
ãã§ãã¯ããŠããŸãããä»åãéå»ã«äŒŒããããªäºäŸãèŠãèšæ¶ããã£ãã®ã§ãç䌌ããŠã¿ãããšæãäœãããšãã§ããŸãããæ¥é ããæ
å ±åéãããŠè³ã«æ
å ±ãæºããŠããããšã¯å€§äºã ãšæããŸããã ä»åã®botã¯ä»¥äžã®ä»ç€Ÿæ§ã®èšäºãåèã«ãããŠããã ããŸããã Amazon Bedrock ãçšããé害察å¿å ±åæžãšãã¹ãã¢ãŒãã ææžèªåäœæ ãå
šå¡ã€ã³ã·ãã³ãã³ãã³ããŒãã®äœå¶æ§ç¯ãã 1幎çµã£ãçŸåšå° ãŸãšã ä»åã¯Slackã®äŒè©±å±¥æŽããéå®³å ±åãèªåçæããbotãäœæããŸããã ãŸã å
¬éããã°ããã§å©çšå®çžŸãå°ãªãå®çžŸãå ±åã§ããªãã®ãæ®å¿µã§ããããããã瀟å
ã§é害èŠçŽbotãæŽ»èºããŠãããããšãé¡ã£ãŠããŸããïŒSREãšããŠã¯æŽ»èºããæ©äŒãå°ãªãã®ãçæ³ã§ããïŒ éå®³å ±äœæã®è² æ
ã軜æžããããšã§æ
åœè
ãé害察å¿ã«éäžã§ãã察å¿ã«ãããæéãã³ã¹ããåæžã§ããããšãä»åŸæåŸ
ããŠããŸãã â» èæ³š myfriendGPTã«ã€ããŠã¯ãã¡ãã®èšäºãåç
§ãã ããããã¡ããäžèªããã ãããšããçè§£ãæ·±ããããŸãã ChatGPT APIãæŽ»çšããSlackbotãäœæããŠã30å以å
ã«äŒç€Ÿå
ã«æèœãªåéãäœã ïž ã€ã³ããŒãœãŒã¹ã«ã€ããŠã¯ãã¡ãã®èšäºã§è©³ãã玹ä»ããŠããŸãã ã€ã³ããŒãœãŒã¹ãå°å
¥ããŠã¿ã ãã®â ã詊ãå°å
¥ç·š ïž ã³ã³ããªãã¥ãŒãïŒèªåããªãŒããŒã§ãªããªããžããªã®ãœãŒã¹ãä¿®æ£ããŠãããããš ïž
ãšã³ãžãã¢ãªã³ã°ãããŒãžã£ãŒãããŠããŸããèŠå·ã§ãã 2025-02-26 ã« D-Plus Tokyo #11~åããŠããã£ãïŒèªåãåãããïŒãªã³ããŒãã£ã³ã° Part2 ã«ãŠã瀟å
ã§å®æœããŠããæ¥åãã¡ã€ã³ç¥èã®ãªã³ããŒãã£ã³ã°ã®è©±ãããŠããŸããã®ã§ãããã°ãæžããããšæããŸããïŒ çºè¡šã¹ã©ã€ãã¯ãã¡ãã§ãã ïŒ 20幎ãåãäŒç€Ÿã«ããã°ãããã§åããŠå®æããããšãããã€ããããŸããä»åããã®äžã®1ã€ã§ããããã¯ãã®å¯¿åœã®é·ããããããã¯ãã«é¢ãããšã³ãžãã¢ã®æéãªã©ã®èгç¹ãå«ããŠããªã³ããŒãã£ã³ã°ã®å€§äºãã«ã€ããŠè§ŠããããšæããŸãã çµè« ãã®å³ãæãäŒãããããšãªã®ã§ãå
ã«ç€ºããŠãããŸãã ãããã¯ããéçºããã客æ§ã«é·ããå©çšããã ãããã«ããã䟿å©ãªæ©èœãäœéšãæäŸããŠãããŸãã ãã䟿å©ãªæ©èœãäœéšãšãããã®ã¯ãã¡ãŒã«ãéã£ãããç©æµãéããŠã¢ããéã£ãããæ±ºæžææ®µãå¢ãããããšããããã¯ãã®åšèŸºã«ãã®ãå¢ããŠããŸããããã¯ãèŠããã«ãæ¥åãã¡ã€ã³ç¥èã§ãã äžæ¹ã§ãäžè¬çã«ãšã³ãžãã¢ã¯ãããã¯ãå
šäœã®å¯¿åœã«æ¯ã¹ããšæºããæéã¯çããã®ã§ãããªã®ã§ãããããããã®ãããã¯ããæé·ãããããã«ã¯ãéçºã«æ©ãæºãããããã«ããªããšãããŸããã ãããã¯ããæé·ãããããã®éçºã¯ãåãªãã³ãŒãã£ã³ã°ã»ãã¹ãã»ãããã€ãšããåçŽãªãã®ã§ã¯ãªããçŸåšã®ã客æ§ã®äœéšãçè§£ãããããæ¯ããŠããä»çµã¿ãç¥ããªããšãããŸãããã€ãŸããåšå²ã®ãã®ãå«ããŠæ¥åãã¡ã€ã³ç¥èã®åžåãå¿
èŠã§ãã ããã§ãæ¥åãã¡ã€ã³ç¥èã®ãªã³ããŒãã£ã³ã°ãå¿
èŠã«ãªããããŸããã®åŸªç°ãåãã°ããããããã¯ããæé·ããããµã€ã¯ã«ãæ©ãã§ãããšèããããšãã§ããŸãã ã§ãæ¥åãã¡ã€ã³ç¥èã®ã³ã³ãã³ãã®äœãæ¹ã«ã€ããŠã¯èšäºåŸåã«ãããŸãã®ã§ããããããããã°ããåèãã ããã ããŠããããã¯ãã¹ã©ã€ãããã®æç²ãšè£è¶³èª¬æãããŠãããããšæããŸãã ãããã£ã®æŽå²ã¯é·ãã10幎以äžç¶ããŠãããããã¯ãã倿°ãããŸã ISPäºæ¥ã¯ããã§ã«ç€ŸäŒã€ã³ãã©ãšãªã£ãŠããã®ãé¢ä¿ãããã§ãããé·ããã客æ§ã«ã䜿ãããã ããåŸåããããŸãã ãããŠãISPçãªä»çµã¿ã®æ¥åãã¡ã€ã³ç¥èãšã¯å¥ã«ããããã¯ããæé·ããŠãããšããã®åšèŸºã«ãããããªã·ã¹ãã ãå¢ããŠãããŸããäžã®å³ã¯ã€ã¡ãŒãžã§ãããä»ã«ãSMSãéã£ãããæ±ºæžææ®µãå¢ããããšãããããããŸãã ãããããªã³ããŒãã£ã³ã°ã§ç®æãããã¬ãã«ã¯ïŒ åŸã
ã«ãªã³ããŒãã£ã³ã°ã®è©±ã«ç§»ããŸããããŸãç®æãããã¬ãã«æãæç¢ºã«ããŠã¿ããšãåãªããéçºã§ããããã«ãªããã§ã¯ãªãããã客æ§ã®ããã«éçºã§ããããã«ãªãããã©ãããªãç®æããããšæããŸããã客æ§ã®ããã«ããšããããã«ã¯ãã客æ§ãçŸåšã©ããªäœéšãããŠããŠããããããããåšèŸºã®ã·ã¹ãã ã¯ã©ã®ããã«ãªã£ãŠãããããã£ãŠããç¶æ
ãæãŸããã§ãã ãããã¯ãã®å¯¿åœãš1人ã®ãšã³ãžãã¢ãæºããæéã«ã€ã㊠ã§ãæ¬¡ã¯æé軞ã§èããŠã¿ãããšæããŸãããã1ã€ã®ãããã¯ãã®å¯¿åœãšãããã®ãæé軞ãšããŠåãåããããã«äŒç€Ÿããšã³ãžãã¢ã®ããããã®æé軞ãã¿ã€ã ã©ã€ã³ãšããŠããããããŠã¿ãŸãã ããïŒã€ã®ãããã¯ãã®å¯¿åœã«æ¯ã¹ã1人ã®ãšã³ãžãã¢ãé¢ããæéã¯äžè¬çã«çããã€ã¡ãŒãžãšããŠã¯ãããªæãããšæããŸãããã£ãªã¢ãã§ã³ãžãå
¥é瀟ãªã©æ§ã
ãªçç±ã§ãçµæãšããŠãã®ããã«ãªããŸãã ãªã®ã§ãä»ãããšã³ãžãã¢ã¯å°æ¥å
¥ã£ãŠãããšã³ãžãã¢ã®ããšãæãããœãŒã¹ã³ãŒããããã¥ã¡ã³ããäœãããšã倧äºã§ãããèªã¿ãããã³ãŒããã·ã³ãã«ãªèšèšãæå³ããããããã¥ã¡ã³ããªã©ãããããæ®ããŠãããªããšãããªãããšã«ãªããŸããäœãã©ãæ®ããã¿ãããªè©±ã¯ãããã話ãããããšãããã®ã§ããã仿¥ã®äž»é¡ã¯ããã§ã¯ãªããæ°ãã«ãžã§ã€ã³ãã人ã®è©±ã«ãã©ãŒã«ã¹ãããšããããããã®ããã¡æ©ãåžåããŠããããã¯ããæé·ãããããã®ç¥èãåŸãªããšãããªãããã®æ©ãã倧äºã«ãªããšããããšãããããŸãã ç®æãããå¥œåŸªç° ã€ãŸãããããŸã§èª¬æããããšããããããšããããã埪ç°ãã§ãããšæããŸãã ãããã¯ããæé·ãããšãåšèŸºã«ãã®ãå¢ããŠããŸããããã¯æ¥åãã¡ã€ã³ç¥èãšå矩ã§ãããšã³ãžãã¢ã¯ãããã¯ãæé軞ã«å¯ŸããŠããªãæ©ãå
¥ãæ¿ãããçºçããããããããããã¯ããæé·ãããéçºãã§ããããã«ã¯ãæ©ãè²ãŠãå¿
èŠããããŸããã§ããªã³ããŒãã£ã³ã°ã§ç®æãããã®ã¯ããã åã«éçºãšãã¹ããšãããã€ãã§ããããã«ãªãããšã ãã§ã¯ãªãããããã¯ããã°ããŒã¹ãããããã«å¿
èŠãªåšèŸºç¥èãç¥ã£ãŠã»ãããšæããŸããã€ãŸããã©ããªã客æ§ã䜿ã£ãŠããã®ãïŒã客æ§äœéšãããããŠããåšèŸºã®ä»çµã¿ã¯ã©ã®ããã«ãªã£ãŠããã®ãããšããããšã§ããããããç¥ã£ãŠããããšã§ããããã¯ãã®æé·ãèŠæ®ããéçºããã£ãšã¢ã€ãã¢ãåºããäœããå¹çåãããããšããããšãã§ããŠããã®ããªããšèããŠããŸãã 以äžãããã¡ã€ã³ç¥èã®ãªã³ããŒãã£ã³ã°ãããããšã«ããããšã³ãžãã¢ã®æé·ãæ©ããç¶ç¶çã«ãããã¯ãã®æé·ãä¿ã奜埪ç°ããããããŠããããšãã説æã§ããã ã©ããã£ãŠãã¡ã€ã³ç¥èã®ãªã³ããŒãã£ã³ã°ã³ã³ãã³ããäœã£ããïŒ ããããã¯ãªã³ããŒãã£ã³ã°ã³ã³ãã³ãäœæã®è©±ã§ããäžã®ã¹ã©ã€ãã«ãããããªé çªã§äœæããŠãããŸããã瀟å
ã«ãããã¡ã€ã³ç¥èã®ãã¹ã¿ãŒãã¡ïŒäžçªç¥ã£ãŠãããªæ¹ïŒã«ã声ããããŠãããããããã®ãã¡ã€ã³ã§ã®æ
åœè
ãæ±ºããŠçŽ1æéãããã®è¬çŸ© / å°ãã¹ã 圢åŒã§ãã³ã³ãã³ããäœæããŠããã ããŸãããããã«ãã¹ãŠã®è¬çŸ©ã«ã€ããŠã¯é²ç»ããã¹ãŠåããä»åŸãžã§ã€ã³ããæ¹ã
ãããã«é²èЧã§ããããã«ããŸãããã³ã³ãã³ãã«ã€ããŠã¯ããããŠã瀟å
ã«æ¢åã®ããã¥ã¡ã³ããããããããããžã®ãªã³ã¯éã®ãããªåœ¢ã§è©±ã®æµãããŸãšããŠããã1ããŒãžã®ãããªæ³å®ã§ãã ãšãŠããããªãã§ããã现ãããšãããŸã§ç¥ãããšãããšéåžžã«æéããããããšã«ãªãé£ãããªããšæãã®ã§ãæµ
ãåºãç¥ã£ãŠãããããšãéèŠããèãæ¹ã§ããæ¿ãã®èª¿æŽã§ããããããã¡ã€ã³ç¥èã®è¬çŸ©æéã1æé確ä¿ããã®ã§ããã®äžã§äŒããããçšåºŠã«ããŠãã ããããšå
ã«æéå¶éãèšããŸããã ã³ã³ãã³ãã¯ã§ã次第ãè¬çŸ©ãéå¬ããŠãããæ¢åã¡ã³ããŒã«å¯ŸããŠæè²ããŠãããŸãã çµæçã«ãåãã¡ã€ã³ç¥èããšã«ãããã¥ã¡ã³ãã® URL ããããªéã®ããŒãžãäœæãããŸãïŒ ãã°ããããããã¯å®ã§ãã ããšã¯ãæ°ãããžã§ã€ã³ããŠããã ããæ¹ã«æŒããªããã®ã³ã³ãã³ããäŒãããããSlackã¯ãŒã¯ãããŒã䜿ã£ãŠèªåçã«ã¡ãã»ãŒãžãé£ã¶ããã«ä»æããŸããã æåŸã« é·æçãªãããã¯ãã®æé·ãæ¯ããããã«ã¯ãæè¡åãšæ¥åç¥èã®äž¡æ¹ãäžå¯æ¬ ã§ããç¹ã«ããããã¯ãã®å¯¿åœãé·ããè€éãªæ¥åç¥èãå¿
èŠãªå Žåããã®äž¡èŒªã®ãã©ã³ã¹ãéèŠã«ãªã£ãŠããŸãã ç§ã®çµéšããã广çãªãªã³ããŒãã£ã³ã°ãšã¯ãåãªãæè¡ã¹ãã«ã®åŠç¿ã§ã¯ãªãããããã¯ããåãå·»ãæ¥åå
šäœãžã®çè§£ãæ·±ããæ©äŒãªã®ã ãšæããŸãããããã¯ããæé·ããããšã³ãžãã¢ã¯ãã³ãŒããæžãã¹ãã«ãšåãããããããžãã¹ãæ¥åãžã®æ·±ãçè§£ãæ±ããããŠãããšæããŸãã ãšãããšããã§ã以äžããããã¯ãã®æé·ãç¶ç¶çã«ä¿ãã«ã¯ãæè¡ã¹ã¿ãã¯ã ããããªããæ¥åãã¡ã€ã³ç¥èã®ãªã³ããŒãã£ã³ã°ãåããããã®éãå¿
èŠãªè©±ãã§ããã
ãããã£ã«ã¯ããã©ã³ããè¥æãŸã§ãå€çš®å€æ§ãªãšã³ãžãã¢ãåããŠããŸãããã®èãæ¹ããã£ãªã¢ãã¹ã人ããããã§ãããåºæ¬çã«ã¯ç€Ÿå¡èªèº«ãäž»äœçã«ãã£ãªã¢ã«ã€ããŠèããèªãéãåãéããŠããèªç±ãªé¢šåããããŸããä»åã¯ãã〠ãããã£ãã®ãµãŒãã¹ãææããéçºã¡ã³ããŒ3åã«ã€ã³ã¿ãã¥ãŒããšã³ãžãã¢ããèŠããããã£ãšããäŒç€Ÿã®ç°å¢ã«ã€ããŠããã£ãªã¢ãã¹ã«ã€ããŠãªã©ãçŸå Žã§åãéçºè
ãªãã§ã¯ã®ãªã¢ã«ãªèŠç¹ã§è©±ãèããŸããã èªå·±çŽ¹ä» K.Nãã 2009幎å
¥ç€Ÿããã¶ã€ã³ããŒã ã«ã³ãŒããŒãšããŠé
å±ããããŠã§ããµã€ãã®ãã£ã¬ã¯ã·ã§ã³ãæ
åœã2015幎ããã瀟å
ã®ã¹ã¯ã©ã ãšãã³ãžã§ãªã¹ããšããŠæŽ»èºäžãCSMãA-CSMã®è³æ Œãæã¡ã10ããŒã 以äžã40å以äžã®ãšã³ãžãã¢ã«å¯ŸããŠã¹ã¯ã©ã å°å
¥ããµããŒãã宿œããŠãããã¹ã¯ã©ã ãã¹ã¿ãŒã®ã«ããäž»å¬ãã瀟å
ã®ã¢ãžã£ã€ã«æåã®éžæã«è²¢ç®ããã©ã€ããŒãã§ã¯ãã¢ãã¿ããŒã³ãã£ãŒãšããŒãã²ãŒã ãæããäžé¢ãã瀟å
ããŒãã²ãŒã éšã®éšé·ãšããŠãããããªã³ã®æ®åã«ãå°œåããŠããã M.Kãã 2019幎æ°åã§å
¥ç€Ÿã2022幎ããäŒå¡åãiOS/Androidã¢ããªãã〠ãããã£ãã®éçºã»éçšãæ
åœãããŒã ã«å
¥ã£ãåœåã¯iOS/Andoirdã¢ããªéçºã¯æªçµéšã ã£ãããçŸåšã¯ã¢ããªèªäœã¯ãã¡ããããã¯ãšã³ããã³ã³ãã³ã管ççšã®å
補ããŒã«ãŸã§å¹
åºãæ
åœããŠãããæè¿ã¯æããã©ãŒãã³ã¹ãã¥ãŒãã³ã°ã³ã³ãã¹ãã®æ¯ãè¿ããããªãããæ
åœã·ã¹ãã ã«æŽ»ãããããšããªããæš¡çŽ¢äžã A.Mãã 2019幎æ°åã§å
¥ç€Ÿããããã㣠ãã¥ãŒã¹ãããŒã ã«çŽ4幎åæå±ãããã®äžã§ã2021幎ã®ãã€ãããã£ã¢ããªã®ç«ã¡äžãæã«iOSã¢ããªãäž»å°ããŠéçºãäœå¶å€æŽã«äŒŽã£ãŠã2024幎3æã«ãã€ãããã£ããŒã ã«ç°åãJãªãŒã°ã暪æµFã»ããªãã¹ãã®ãµããŒã¿ãŒã§ãããããµãã«ãŒé§åã§å
šåœåå°ã«é åŸãããŠãããå®¶é»ãªã©ã«è©³ããã ãäºããé«ãåããåæãšã³ãžãã¢ã®ååš ã¿ãªããã¯ãã〠ãããã£ããææããããŒã ã®ã¡ã³ããŒãšããããšã§ããããäºãã«å¯Ÿããå°è±¡ãæããŠãã ããã K.Nãã ç§ã¯äºäººããã10幎å
茩ã§ããã〠ãããã£ãã®ã¹ã¯ã©ã ãã¹ã¿ãŒããã£ãŠããŸããA.Mãšã¯åéšçœ²ã§ããããã£ãã¥ãŒã¹ããšãããµãŒãã¹ã®ã¢ããªéçºãäžç·ã«ãã£ãŠãã仲éã§ããããæŠåã®ãããªååšã§ãããã¢ããªã®ãšã³ãžãã¢ãšããŠãéåžžã«é ŒãããæããŠããŸããã¡ãªã¿ã«ã圌ã¯ãµãã«ãŒããã€æŽ»ãå®¶é»è£œåã«è©³ãããŠãç§ãå®¶é»ãè²·ãæ¿ããæã¯å¿
ãçžè«ããŠãèŠãããããŸãŸè²·ã£ãŠããŸãã M.Kãšã¯ã圌ã2022幎ã«ãã〠ãããã£ãã«ãžã§ã€ã³ããæããã®ä»ãåãã§ãã圌ã®é·æã¯ææãããããšãçå£ã«åãæ¢ããçŽ çŽãããããŸã§ã¢ããªéçºã®çµéšã¯ãªãã£ãã®ã§ãããããã«äž»æŠåã«ãªã£ãŠãä»ã§ã¯ããŒã ãçœåŒããŠãããŠããŸããæŒ«ç»ã®è¶£å³ãåãã®ã§ããã奜ããªäœåã«ã€ããŠè©±ããŸããã ç§ããèŠãŠã圌ãã¯çæ³çãªé¢ä¿æ§ã ãšæããŸãããäºãã«ãã©ããŒãåãã€ã€é«ãåã£ãŠããããè¯ãã ãŒããçãŸããŠããããããããã¿ãã°ã§ããŒã ãçœåŒããŠã»ããã§ããã ã§ã¯ãK.Nããã¯ãäºäººã«ãšã£ãŠã©ããªå
茩ããªãŒããŒã§ããããïŒ A.Mãã åã1幎ç®ã®é ãããäžè©±ã«ãªã£ãŠããŸããããæž©å®€ãã§è²ãŠãŠããã£ãæèŠããããŸããããšããšå察é¢ã®äººãšã®ã³ãã¥ãã±ãŒã·ã§ã³ãèŠæã ã£ãã®ã§ãããããšãã°æ¥åã§ããŒã å€ã®äººãšèª¿æŽãè¡ãæãªã©ã¯ãK.Nããã«ããªããã©ããŒããŠããã ããŸããããŸããã©ã¡ãããšãããšãã¬ãã£ãã«èããŠããŸãæ§æ Œããããžãã£ããªK.Nããã«åœ±é¿ãããŠå°ããã€å€ãã£ãŠããŸããããä»ã¯èœã¡èŸŒãããšããã£ãŠãæã¡çŽãåãã ãã¶èº«ã«ã€ãããšæããŸãã M.Kãã åã¯æ°äººã®é ãã瀟å
ã€ã³ãã©ã®éçºãéçšã«æºãã£ãŠããããšãããããã〠ãããã£ãã®ããŒã ã«ç°åããåœåããŠãŒã¶ãŒããåãã®ãµãŒãã¹ã«é¢ããç¥èãã»ãšãã©ãããŸããã§ããããã ãK.NãããšäŒç»ããŒã ã®ãããšããèŠãŠããŠãŒã¶ãŒããã«äœ¿ã£ãŠãããããã«ã¯ã©ãããèŠç¹ãå¿
èŠããããã«ãµãŒãã¹ãéçšãã¹ãããšãã£ããšãããåŠã³ãŸããããå¿
èŠãªã¹ãã«ã身ã«ã€ããããã«ãµããŒãããŠããã ããŸããã ããã€ãããã£ãã¯äŒç€Ÿã®é¡ãäžæãªãã®ã¯åºããªã ã¿ãªãããææãããã〠ãããã£ããšã¯ãã©ã®ãããªãµãŒãã¹ãªã®ã§ããããïŒ K.Nãã @niftyã®äŒå¡æ§åãã¢ããªã§ã2021幎ã«iOSçã2022幎ã«AndroidçããªãªãŒã¹ããŸããã@niftyã®ãããããŒãžããµããŒãããŒãžãåãµãŒãã¹ãµã€ããªã©ãéçŽãããŠããŠãã¢ããªãéãã°ç¥ãããæ
å ±ã«ã¢ã¯ã»ã¹ã§ããŸãããŸããå©çšæéãNifMoã®éä¿¡æã確èªãããã@niftyã¡ãŒã«ããã§ãã¯ãããããç¥ãããªã©ãå«ããŠããŒã ã¿ãã§äžæ°èŠã§ããããã«ãªã£ãŠããŸããäžèšã§èšãã°ãã客æ§ãã€ã³ã¿ãŒãããããããã£ã®ãµãŒãã¹ãå¿«é©ã«ãå©çšããã ããããããµããŒãããããã®ã¢ããªã§ããã K.NãããšA.Mããã¯ãã〠ãããã£ãã®ç«ã¡äžãã¡ã³ããŒã§ãM.Kããã¯2022幎ã®Androidçã®éçºã¡ã³ããŒãšããŠã¢ãµã€ã³ããããšäŒºããŸãããM.Kããã¯ãããŸã§ã¢ããªéçºã®çµéšããªãã£ããšããããšã§ãããªãèŠåŽãããã®ã§ã¯ïŒ M.Kãã æ£çŽã倧å€ã§ããïŒç¬ïŒããã ããããããã〠ãããã£ãã«ã¯èªãã®åžæã§ç°åããŠããã®ã§ãæªçµéšãªããã¢ããªéçºãä»»ããŠããããã®ã¯ãããããã£ãã§ããããã¡ããããããŸã§ã®ç€Ÿå
ã·ã¹ãã ã®æ¥åã«ããããããæããŠããŸããããåŸã
ã«é¡§å®¢åãã®ãµãŒãã¹ã«ãæºãã£ãŠã¿ãããšèããŠããé ã«ã瀟å
ã§ãå
¬åå¶åºŠããšãããã®ãã¹ã¿ãŒããããã§ããæ°ãã人æãå¿
èŠãšããŠããããŒã ãå
šç€Ÿã«åããŠåéãããããããšãããã®ã§ããã〠ãããã£ãã§ãéçºã¡ã³ããŒãåã£ãŠããŸãããã¡ããã©Androidçã®éçºãå§ãŸã£ããšããã§ãåžå Žã§ãããŒãºã®é«ãã¢ããªéçºã«æºããããã£ã³ã¹ã ãšèãããã©ã€ããŠã¿ãããšã ãã ã倧å€ã ã£ããšã M.Kãã åœåã¯æ¬åœã«äœãåããããã©ãããå§ããã°ãããã ãããšããç¶æ³ã§ããã ãå
茩ãäžå¯§ã«ãµããŒãããŠãããŸããããèªåã§ãã¢ããªéçºè
ãéãŸãã«ã³ãã¡ã¬ã³ã¹ãªã©ã«åå ããŠãããã§èŽããã»ãã·ã§ã³ã®å
容ãå®åã§è©ŠããŠã¿ãããšãè²ããªè§åºŠããç¥èãæ·±ããŠãããŸããã ãŸããåãå
¥ã£ãã¿ã€ãã³ã°ã§ã¯ãã§ã«ãšã³ãžãã¢å士ã®è°è«ãå°œããããŠããŠãåºæ¬çãªèšèšãæ§é ãªã©ã¯ããããããŸãšããããŠããŸããããã®ãããèªåã¯ãã®æµãã«ä¹ãã€ã€ã¢ããªã®åŠç¿ãã¹ãã«ã®ç¿åŸã«æ³šåã§ãããšããããããŸããã A.Mããã¯ãããã§ãããïŒãç«ã¡äžãæã«èŠåŽããããšã課é¡ã«æããŠããããšã¯ãããŸããïŒ A.Mãã ãããŸã§ãããã㣠ãã¥ãŒã¹ãã®ã¢ããªã«æºãã£ãŠãããšã¯ãããéçšãæ°ããæ©èœã®éçºãã¡ã€ã³ã§ããããã«ã€ãããã¢ããªãç«ã¡äžããçµéšã¯ãããŸããã§ãããã©ãããæè¡ã䜿ãã°ããã®ããšãã£ããæ¬åœã«å
¥å£ã®éšåãã調ã¹ãŠãã£ãŠãã倧å€ãã¯ãããŸãããããŸããåçŽã«ã¿ã¹ã¯éãå€ããææ¥ãŸã§ã«çµããã®ããšããäžå®ãçŠãããããŸããã ãã ãæ°èŠãµãŒãã¹ã®ç«ã¡äžãã¯ãªããªãçµéšã§ããããšã§ã¯ãªãã§ãããéçºãéããŠæé·ã§ãã宿ããããŸããèªåããããŸã§è§ŠããŠããªãã£ã瀟å
ã®ãã¡ã€ã³ç¥èãå
šãп޻çšããªããéçºã«ããã£ãããšã§ãã¢ããªã®ããšã ãã§ãªããããã£å
éšã®æ
å ±ã®åãæ¹ã¿ãããªãšãããå«ããŠçè§£ãæ·±ãŸããŸãããã K.Nããã¯ããŒã ãªãŒããŒãšããŠããµãŒãã¹å
šäœã®ã¯ãªãªãã£ãªã©ãèŠãªããã°ãããªãç«å Žã ã£ããšæããŸããåœæãã©ããªæèã§éçºã«èšãã§ããŸãããïŒ K.Nãã ã客æ§ãããããšããã〠ãããã£ãã¯ãããã£ã®é¡ã ãšæããŸãããããªãµãŒãã¹ãäœåºŠãã¯ã©ãã·ã¥ããããããŸã䜿ããªãã£ãããããšããããã£ã«å¯Ÿããå°è±¡ãæªããªã£ãŠããŸãããããªæèã§éçºã«ããã£ãŠããŸããããŸããä»åŸããã£ãšéçšããŠãããµãŒãã¹ã«ãªããšèããŠããŸããã®ã§ãæåã«ã©ããŸã§ã€ããã®ããã©ããããå
ã®ããšãŸã§èæ
®ããŠã€ããã®ããããŒã ã§äœåºŠãè°è«ãéããŸãããã ãããã®èŠåŽãçµãŠiOSçããªãªãŒã¹ããçŽåŸã®ã客ããã®åå¿ã¯ãããã§ãããïŒ K.Nãã äŒç»ããŒã ãåšç¥ãé 匵ã£ãŠããããããã§ãæ©ã段éã§10äžDLã«å°éããŸããã䜿ã£ãŠããã ããã客æ§ããããæŠãé«ãè©äŸ¡ãããã ããŠããã ããªãªãŒã¹åœåããç®æšãšããŠæ²ããŠããã®ã¯ãåã«äŸ¿å©ãšããã ãã§ãªãã@niftyã®ãµãŒãã¹ãé·ã䜿ã£ãŠããã ãããã§ããªããŠã¯ãªããªãã¢ããªãã«ãŸã§æã£ãŠããããšã§ãããæ¥µç«¯ã«èšãã°ããã〠ãããã£ãããããã@niftyãå¥çŽããŸãããšèšã£ãŠãããããããã®æ©èœãšé
åãæã€ãµãŒãã¹ã«æé·ãããŠãããªããã°ãªããªããšèããŠããŸãã åŸç·šã«ç¶ããŸãïŒ ä»åã¯ãããã£ã®ã〠ãããã£ããŒã ã®ã€ã³ã¿ãã¥ãŒã®æ§åããå±ãããŸãããç¶ãã¯è¿æ¥å
¬éäºå®ã®åŸç·šã®èšäºãã芧ãã ããã ãã®ã€ã³ã¿ãã¥ãŒã«é¢ããæ±äººæ
å ± /ããã°èšäº ãããã£æ ªåŒäŒç€Ÿ æ±äººæ
å ±
ã¯ããã« ããã«ã¡ã¯ããããã£æ ªåŒäŒç€Ÿã®ä»²äžã§ãã CI/CDãæ§ç¯ããéãã¢ã¯ã»ã¹ããŒã®ç®¡çã倧å€ã§ãã ã¢ã¯ã»ã¹ããŒãã·ãŒã¯ã¬ããããŒãGitHub secretsãªã©ã«æ ŒçŽããæ¹æ³ããããŸããã管çã倧å€ã§ãæéåãã®å¯Ÿå¿ãªã©ãå¿
èŠã«ãªããŸãã ããã§ãæ¬èšäºã§ã¯OIDCãå©çšããèªèšŒã§AWSãžã®ã¢ã¯ã»ã¹æš©éã管çããæ¹æ³ãã玹ä»ããããšæããŸãã OIDCã«ã€ã㊠OIDCã¯OpenID Connectã®ç¥ã§ãã OIDCã¯SSO(ã·ã³ã°ã«ãµã€ã³ãªã³)ã®å®è£
ææ³ã®1ã€ã§ãå€ãã®ãµãŒãã¹ã«å©çšãããŠããèªèšŒãã©ãŒãããã§ãã ä»ã®èªèšŒãã©ãŒããããšããŠã¯ãSAMLãæåã§ãã OpenID Connect ã®èšèã®èª¬æã¯ä»¥äžã®èšäºãããããããã§ãã https://www.tohoho-web.com/ex/openid-connect.html ä»çµã¿ã®è§£èª¬ã«ã€ããŠã¯ã以äžã®èšäºãæåã§ãã https://qiita.com/TakahikoKawasaki/items/498ca08bbfcc341691fe AWSã§ã¯ãã®èªèšŒæ¹åŒãå©çšããæš©éç®¡çæ©èœãåãã£ãŠããŸãã https://docs.github.com/ja/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services ã¡ãªãã ã¡ãªãããšããŠã¯ä»¥äžã®ç¹ãæããããŸãã éµã®ç®¡çãäžèŠ ãŠãŒã¶ãŒã«äŸåããªãèªèšŒæ¹æ³ã«ãªã ããŒã¯ã³ã®æéã«é ãæ±ããªããŠæžã ãã¡ãªãã ãã¡ãªãããšããŠã¯ä»¥äžã®ç¹ãæããããŸãã ä»ã®ãªããžããªãããããã€ããããã«ãªã£ãå Žåãå床èªèšŒãå¿
èŠ èšå®ããã¹ãããš ãã¹ãŠã®GitHubäžã®ãªããžããªããã¢ã¯ã»ã¹ã§ããŠããŸã ç¹ã«ãAWSã®IAMããŒã«ãžã®ã¢ã¯ã»ã¹æš©é管çã«ã¯çްå¿ã®æ³šæãæãå¿
èŠããããŸãã ä»åã¯ãã®æ©èœã§ãªããžããªã®èªèšŒèšå®ãè¡ãããããã€ããŠããããšã«ããŸãã èšå®æé AWS ã® IAM ãž GitHub ã®IDãããã€ãã远å ãããã€å¯Ÿè±¡ã®IAMã§IDãããã€ããéžæããŸãã ãããã€ãã远å ããŸãã 以äžã®å
容ã§èšå®ããŸãã ãããã€ãã®ã¿ã€ã OpenID Connect ãããã€ãã® URL https://token.actions.githubusercontent.com 察象è
sts.amazonaws.com IAMããŒã«ã®äœæ IAMããŒã«ãããã«ã¹ã¿ã ä¿¡é Œããªã·ãŒãéžæããŸãã ã«ã¹ã¿ã ä¿¡é Œããªã·ãŒã®å
容ã¯ä»¥äžã®éãã§ãã { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::{èªåã®AWSã¢ã«ãŠã³ãID}:oidc-provider/token.actions.githubusercontent.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "token.actions.githubusercontent.com:aud": "sts.amazonaws.com", "token.actions.githubusercontent.com:sub": "repo:{ãããã€å¯Ÿè±¡ã®ãªããžããª}:ref:refs/heads/*" } } } ] } ãèš±å¯ãã§ã¯ãããã€ã«äœ¿çšããæš©éãéžæããŸããããã§ã¯ä»¥äžã®æš©éãä»äžããŸãã AWSCloudFormationFullAccess AmazonS3FullAccess AWSLambda_FullAccess CloudWatchLogsFullAccess IAMFullAccess AmazonDynamoDBFullAccess AmazonEC2FullAccess æš©éã¯ãããã€ãããã³ãã¬ãŒãã®å
容ã«ãã£ãŠå€æŽããŠãã ããã ããŒã«åãšèª¬æã远å ããŠããããŒã«ãäœæããéžæããŸãã ã¯ãŒã¯ãããŒãäœæãã ããã§ãããã GitHubã®ã¯ãŒã¯ãããŒãç»å ŽããŸãã èªèšŒã«ã¯ä»¥äžã®ã¢ã¯ã·ã§ã³ã䜿çšããŸãã https://github.com/aws-actions/configure-aws-credentials ãã¡ãã®ã¢ã¯ã·ã§ã³ã䜿çšããããšã§ãRole arnãæå®ããã ãã§AWSèªèšŒãè¡ã£ãŠãããããã«ãªããŸãã ã¯ãŒã¯ãããŒãå®çŸ©ããŸãã GitHub Acrtions ã®ç»é¢ãã倿°ãç»é²ããŸãã Repository variables ãéžæããŸãã AWS_OIDC_ROLE_ARNãèšå®ããŸããå
ã»ã©äœæããRoleã®ARNãæžããŸãã ã¯ãŒã¯ãããŒãåãããããããã©ã«ããã©ã³ããmain以å€ã«ããŠãããŸãã 以äžã®ã³ãŒããäœæããŠpushããŸãã name: éçºç°å¢ããã〠run-name: Deploy ${{ github.ref_name }} to development by @${{ github.actor }} on: workflow_dispatch: push: branches-ignore: - main # allow use id-token permissions: id-token: write contents: read jobs: deploy: runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v2 with: python-version: 3.12 - name: Setup SAM uses: aws-actions/setup-sam@v2 - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ vars.AWS_OIDC_ROLE_ARN }} aws-region: ap-northeast-1 - name: sam validate run: sam validate - name: sam build run: sam build - name: sam deploy run: sam deploy åäœç¢ºèª ããŸããããŸãããã¿ãªããããã²OIDCãå©çšããŠã¿ãŠãã ããã åè https://zenn.dev/kou_pg_0131/articles/gh-actions-oidc-aws
è¥æãšã³ãžãã¢ãã¡ãææ°ã®æ
å ±ãå
±æããã¹ãã«ãé«ãåãããšãç®çãšããã€ãã³ããNIFTY Tech Day 2025ãã2025幎2æ8æ¥ãæ°å®¿ãããã£æ¬ç€Ÿã«ãŠéå¬ãããŸããã åœæ¥ã¯ã¡ã€ã³äŒå Žã§ç¹°ãåºããããã»ãã·ã§ã³ã®ä»ãAIãChatBotããšã³ãžãã¢åãè±åºã²ãŒã ãã¹ã¯ã©ã ã©ãŠã³ãžçãåå è
ãå®éã«äœéšã§ããããŒã¹ã«å ããè±ªè¯æ¯åã®åœããããããããã«ãããããã®æ¹ã蚪ããŠããŸããã ä»åã®ã€ãã³ãã«éå¶ããŒã ãšããŠé¢ãã£ãé«ç°ããã«ãä»åã®ã€ãã³ãã®ç®çã«ã€ããŠèããŸããã éå¶ããŒã ã®é«ç°ãã é«ç°ããã³ã¡ã³ã ãå€ãã®çæ§ã«ãè¶ãããã ããèª ã«ããããšãããããŸããTech Dayã®ç®çã¯ããããã£ã®å
šãŠããèŠãããããšãã§ãããããã£ã®é°å²æ°ãããšã³ãžãã¢ãã¡ãã©ã®ããã«åŠã³ãæé·ããŠããããã芧ããã ããããšæããŸãããŸãããšã³ãžãã¢ã®çããã«ãšã£ãŠãæè¡ãå
±æããå Žãšãªãããšãé¡ã£ãŠããŸããã NIFTY Tech Day 2025ã®éå¹ã§ãïŒ NIFTY Tech Day 2025éå¹ NIFTY Tech Day 2025ã¯ãããã£ç€Ÿé·ã®åå³¶ããã«ãããªãŒããã³ã°ã»ãã·ã§ã³ã§å¹ãéããŸããã ãããã£ç€Ÿé·ã®åå³¶ãã åå³¶ãNIFTY Tech Dayã¯ãã¹ãŠç€Ÿå
ãšã³ãžãã¢ã®æã§äœãããã€ãã³ãã§ãããããã£è¥æç€Ÿå¡ãã¡ã®æ¥é ã®åªåã®ææããäœéšããŠãã£ãŠãã ããïŒã çœç±ã®ã»ãã·ã§ã³ãç¹°ãåºããããŸãã ã¡ã€ã³äŒå Žã§ã¯ãã²ã¹ãã¹ããŒã«ãŒãšè¥æãšã³ãžãã¢ãã¡ãç»å£ããããããç±ãã»ãã·ã§ã³ãç¹°ãåºããããŠããŸããã ã¡ã€ã³äŒå Žã§è¡ãããã²ã¹ãã¹ããŒã«ãŒãšãããã£ãšã³ãžãã¢ç€Ÿå¡ã«ããã»ãã·ã§ã³ã®æ§åã ã²ã¹ãã¹ããŒã«ãŒãšããŠç»å£ããGitHubæéšããã®è¬æŒå
容ã¯ãAIæä»£ã«ãšã³ãžãã¢ã«æ±ããããã¹ãã«ã«ã€ããŠã第äžç·ã§æŽ»èºãããšã³ãžãã¢ã®çã®è©±ãèããã®ã¯è²Žéã§ããã ãããã£ã®è¥æãšã³ãžãã¢ãã¡ã«ããã»ãã·ã§ã³ã ã»ãã·ã§ã³ãèããŠãããšããšã³ãžãã¢ãã¡ã®ãæé·ããŠããããšã楜ããããšããå§¿å¢ãäŒãã£ãŠããããã§ããã ã¯ãªãªãã£ã®é«ãé
ä¿¡ã«ããããªã³ã©ã€ã³åå ã®æ¹ãå¿«é©ã«èŠèŽã§ããŠããŸããã åå¥ã®ã»ãã·ã§ã³ã®å
容ã«ã€ããŠã¯ä»¥äžã®ãªã³ã¯ããã¢ãŒã«ã€ãåç»ãã芧ãã ãããïŒâ»ã¢ãŒã«ã€ãå
¬éããšã«éææŽæ°ïŒ AIãšååããæ¬¡äžä»£éçºã¹ã¿ã€ã« – æ±ããããæ°ããªã¹ãã«ãšåœ¹å²ã®å€å ã¢ãŒã«ã€ã ãšã³ãžãã¢ã®æ®»ãç ŽãïŒã€ã³ããŒãœãŒã¹ãšç€Ÿå€æŽ»åããããããæé· ã¢ãŒã«ã€ã ç»å£è³æ èªç€Ÿè£œCMSããã®è±åŽïŒ10ä»¶ã®Webãµã€ãåæ§ç¯ã«åŠã¶éçšéèŠã®æè¡éžå® ã¢ãŒã«ã€ã ç»å£è³æ ã¹ã¯ã©ã ãã¹ã¿ãŒå
¥éè
ã®ããã®åŠç¿ããã 广çãªåŠã³ãšå®è·µ ã¢ãŒã«ã€ã ç»å£è³æ åŠã³ãæåã«å€ããããããã£ã®å
補ç ä¿®ãšç¶ç¶çæé·ã®ä»çµã¿ã ã¢ãŒã«ã€ã ç»å£è³æ 瀟å
SEãšããŠã®é²åïŒAIããŒã«ã掻ãããããã¯ãŒã¯ãšã³ãžãã¢ã®æ°ããªææŠ ç»å£è³æ AWSã§ãOracleãããïŒDBç§»è¡æåïŒãããŒãžããµãŒãã¹æŽ»çšããŠå±äººåãè§£æ¶ ã¢ãŒã«ã€ã ç»å£è³æ ãããã£LT倧äŒå€§å
¬éã¹ãã·ã£ã« ã¢ãŒã«ã€ã ç»å£è³æâ ç»å£è³æâ¡ ç»å£è³æâ¢ ãã¹ãŠãæäœãã®ã€ãã³ãã§ã NIFTY Tech Day 2025ã«æ¥ãããæ¹ã¯ããããããã®èŠæš¡ã®ã€ãã³ãã«ã¯å°éã®éå¶äŒç€Ÿãå
¥ã£ãŠãããã ãããªãšæãããã®ã§ã¯ãªãã§ããããã åå³¶ããã話ããŠããéããå®ã¯ããããã¶ãããã£è¥æç€Ÿå¡ã®æã«ããå
補ãªãã§ããäŒå Žèšå¶ããé
åžç©ã®å¶äœãé
ä¿¡ã«ããããŸã§ããã¶ã§ãã é
ä¿¡ããŒã ããããã£ç€Ÿå¡ã§ãããè¶£å³ã§åŸãã¹ãã«ãçãããŠããã®ã ãšãã æ¥å Žè
ã«é
ãããNIFTY TECH BOOK ïŒ2ã¯ãç¡æé
åžãšã¯æããªãå
å®ã®å
容ã§ãããããã衚çŽãããã¹ãŠãããã£ç€Ÿå¡ã®æäœãã§ãã ãã®ã¬ããŒããæžããŠããå®è€ïŒå·ŠïŒãå®ã¯ãããã£OBã§ããå³ã¯ã»ãã·ã§ã³ç»å£åã®ãããã£ãšã³ãžãã¢ã®ç³å·ããïŒåŸãã§ç¬ã£ãŠããã®ããããã£OBã®æ£è¿ããã§ãïŒã æè¡ç³»ã®ã€ãã³ããšããã®ã¯é£ãã人ãã¡ãé£ãã話ãããå Žæããšããã€ã¡ãŒãžããã£ããã§ãããçŸå Žã§äœéšããŠã¿ããšãŸã£ãããããªããšã¯ãããŸããã§ããã ãšã³ãžãã¢ã®ã¿ãªãããèªåãã¡ã®èå³åéã«ã€ããŠèªãå Žã§ãããã»ãã·ã§ã³ã®åéã«ã¯ããªãŒã¹ããŒã¹ã§çºè¡šå
容ã«ã€ããŠã®äŒè©±ãèªç¶ã«çºçããŠããŸããã ããã¯ç§ããããã£ã«åšç±ããŠããæã«ãæããŠããããšãªãã§ããããããã£ã«ã¯ç€Ÿå¡ã®èªäž»æ§ãéãããç€Ÿé¢šãæ ¹åºã«ãããã ãšæããŸããNIFTY Tech Dayã¯ããŸãã«ãããã£ã瀟颚ãçµå®ããã€ãã³ãã§ããã ç»å£ãçµããè¥æãšã³ãžãã¢ã®ã¿ãªãããæ¥œãããã«ãäºããåŽã£ãŠãããšããããå°ãé¢ãããšãããã瀟é·ã®åå³¶ãããå¬ãããã«èŠãŠããã®ãå°è±¡çã§ããã ãããã£ãšã³ãžãã¢ã®åŒ·ã¿ã®ç¬¬äžäœãããããããæãããããšããã®ããããã£ããããªãšæããŸãã äœéšåããŒã¹ãäººæ° ã»ãã·ã§ã³ã®åéã«ã¯ãããããããã£ç€Ÿå¡ã«ããäœéšåããŒã¹ã«äººæ°ãéãŸã£ãŠããŸããã åè
ãšã³ãžãã¢ããè±åºã§ããªãã®ã§ã¯ããšæããããè±åºã²ãŒã ïŒå®éã¯äžå¯§ã«ãã³ãããããã®ã§è±åºã§ããŸãïŒïŒã ã»ãã·ã§ã³ã«ãç»å£ããŠããã¹ã¯ã©ã ããŒã ã«ãããã¹ã¯ã©ã ã©ãŠã³ãžãã§ã¯ãã¹ã¯ã©ã ãå°å
¥ããŠæ¹åãããããšãããããåŠãã§ããããããšãªã©ã«ã€ããŠã掻çºã«äŒè©±ã亀ããããŠããŸããã ããããããŒã¹ããã¯é³å£°ãã£ããããŒã«ã«ãããåžžã«ãããããã声ããšãªã£ãŠèãããŠããŠããŸããã ãããºããŒã ããã¯ãã©ãåãAI掻çšäºäŸã®ç޹ä»ããåã©ãããã®è³ªåã«ãã¹ã³ãããã£ã©ã¯ã¿ãŒãã²ãããããå³åº§ã«çããŠãããŸãã ãã¹ãŠã®ããŒã¹ããŸããã¹ã¿ã³ããéãããšãããåŒããããããããã®ã³ãŒããŒãè±åºã²ãŒã ãªã©ãããŒãã«ã®é«ãããªãã®ãã®ã豪è¯è³åãåœãããšãã£ãŠããããã®æ¥å Žè
ã®æ¹ã«ãããåŒããŠããã£ãŠããŸããã NIFTY Tech Day 2025ã§ã¯ãã»ãã·ã§ã³çµäºåŸã®æèŠªäŒã«è³ããŸã§ãåå è
ãšéå¶ã¹ã¿ãããã¿ããªå¿ãããæ¥œãããã«äŒå Žã®äžãæ©ãåã£ãŠããã®ãå°è±¡çã§ããã æèŠªäŒãçæ³ã§ãããã ãæ¥å Žã®ã¿ãªããããªã³ã©ã€ã³ã§ãèŠèŽããã ããã¿ãªãããæåŸãŸã§ããããšãããããŸããïŒ æ¬¡åããããŸãïŒ éäŒæšæ¶ã§ã¯æäžå·è¡åœ¹å¡ãããæ¬¡åã®Tech Dayéå¬ã宣èšãããŸãããéå¶ããŒã ããã§ã«æ¬¡åã«åããŠåãåºããŠããŸããæ¬¡åã®NIFTY Tech Dayã§ãŸããäŒãããŸãããïŒ ææ°æ
å ±ã¯åœããã°ãSNSå
¬åŒã¢ã«ãŠã³ãïŒ https://x.com/NIFTYDevelopers ïŒã§çºä¿¡ããŠãããŸãã®ã§ã楜ãã¿ã«ããŠããŠãã ããã NIFTY Tech Dayéå¬ãŸã§ã®éã¯ãNIFTY Tech Talkã§ãæè¡æ
å ±ãªã©ãçºä¿¡ããŸãã®ã§ããã²connpassïŒ https://nifty.connpass.com/ ïŒããç»é²ãã ããã ã¢ã³ã±ãŒããååã®ãããã äŒå Žã§ãåå ããã ããã¿ãªããããªã³ã©ã€ã³ã§èŠèŽããŠããã ããã¿ãªãããåŸæ¥ã¢ãŒã«ã€ããã芧ããã ããã¿ãªãããæ¬åœã«ããããšãããããŸãããã¿ãªããããã®ææ³ãã³ã¡ã³ãããã£ãŒãããã¯ã次ã®NIFTY Tech Dayã«ã€ãªãããŸãããã²ã¢ã³ã±ãŒãã«ãååãã ããã 2025幎3æ31æ¥ãŸã§ã«ã¢ã³ã±ãŒãã«ãåçããã ããã¿ãªããã®äžããæœéžã§æ¬ã€ãã³ãç»å£è
ã®æéšããã®æžç±ã10åããŸã«ãã¬ãŒã³ãããŸãã詳ããã¯ä»¥äžãªã³ã¯ããåç
§ãã ããã https://forms.gle/9n5uSFumWrSz7s5i6 èšïŒå®è€
ããã«ã¡ã¯ãäŒå¡ã·ã¹ãã ã°ã«ãŒãã§ãšã³ãžãã¢ãããŠããå±±ç°ã§ãã æšå¹Žæ«ãCloudFrontã®æšæºãã°ã«åŸ
æã®ã¢ããããŒããå
¥ããŸããã https://aws.amazon.com/jp/about-aws/whats-new/2024/11/amazon-cloudfront-log-formats-destinations-access/ ä»ãŸã§ã®æšæºãã°ã¯ã¬ã¬ã·ãŒãªä»æ§ãæ±ããŠãããç¹ã«ãã¹ãŠã®ãã°ãåããã¹ã«åºåãããŠããŸããšããç¹ãåé¡ã«ãªã£ãŠããŸãããAthenaã§ã®æ€çŽ¢ãªã©ã®ããã«ããã°ãæ¥ä»å¥ããŒãã£ã·ã§ã³ã«ç§»åãããLambdaãåãããŠããæ¹ãå€ãã£ãã®ã§ã¯ãªãã§ããããã ä»åã®ã¢ããããŒãã«ãã S3ã®åºåå
ãã¹ã«æ¥ä»ã»æéãå«ããããšãå¯èœã« JSONãªã©ã®ãã©ãŒãããããµããŒããã«ã©ã ã®åæšéžæãå¯èœã« S3ãã±ããããªã·ãŒã«å¯Ÿå¿ ãªã©ãä»ãŸã§å°ã£ãŠããéšåãè§£æ¶ãããããã«ãªããŸããããã«CloudWatch LogsãFirehoseãžã®åºåãã§ããããã«ãªããŸããã ãããŠæè¿ã«ãªã£ãŠãã®æšæºãã°v2ã¯Terraformã§ãèšå®ã§ããããã«ãªããŸããããŸã Terraformã§ã®èšå®æ¹æ³ã解説ããèšäºã¯å°ãªããã§ãã®ã§ã玹ä»ããããšæããŸãã åæç¥è ãŸã倧åæãšããŠãå®ã¯ãã®æšæºãã°v2ã CloudFrontã«èšå®ããæ©èœã§ã¯ãããŸãã ã ãã㯠å
¬åŒããã¥ã¡ã³ã ã®AWS CLIã§ã®èšå®æ¹æ³ãèŠããšãããã®ã§ãããCloudWatch Logs Delivery(v2)ãšããæ±çšçãªCloudWatchã®ãã°é
ä¿¡æ©èœã«ãªã£ãŠããŸããããã«CloudFrontã察å¿ãããšããã®ãå®éã®ããã§ãã ç»å ŽãããªãœãŒã¹ã¯ä»¥äžã®3ã€ã§ãã DeliverySource DeliveryDestination Delivery ãããã®é¢ä¿æ§ã¯ä»¥äžã®ããã«ãªã£ãŠããŸãã ãã°åºåå
(DeliverySource)ãšãã°åºåå
(DeliveryDestination)ãäœã£ãåŸãããããã€ãªãDeliveryãäœæãããšãã°ãéãããããã«ãªããŸããDeliverySourceã«CloudFrontãDeliveryDestinationã«S3ãèšå®ããããšã§åŸæ¥ã®æšæºãã°ã代æ¿ã§ããŸãã Terraformã§ããããã®ãªãœãŒã¹ãäœæããŠããããšã«ãªããŸãã Terraformã§ã®å®è£
äŸ åŸæ¥ãšåæ§ãS3ãžéãèšå®ã玹ä»ããŸãã Terraform AWS Provider㯠v5.89.0ä»¥äž ãå¿
èŠã§ããäœæã§ããããã«ãªã£ãã®ã¯v5.83.0ã§ãããapplyåŸã«ç¶æ
äžäžèŽ(tainted)ãšãªãè€æ°ã®ãã°ãä¿®æ£ãããŠããŸãã S3ã®èš±å¯èšå® S3ã®èš±å¯èšå®ã¯ãã±ããããªã·ãŒãèšå®ããŸããããACLã䜿ãå¿
èŠã¯ãããŸããã { "Version": "2012-10-17", "Statement": [ { "Sid": "AWSLogDeliveryWrite", "Effect": "Allow", "Principal": { "Service": "delivery.logs.amazonaws.com" }, "Action": "s3:PutObject", "Resource": "<S3ãã±ããARN>/<ãã°ãã¡ã€ã«ãŸã§ã®ãã¹>/*", "Condition": { "StringEquals": { "aws:SourceAccount": "<AWSã¢ã«ãŠã³ãID>", "s3:x-amz-acl": "bucket-owner-full-control" }, "ArnLike": { "aws:SourceArn": "arn:aws:logs:us-east-1:<AWSã¢ã«ãŠã³ãID>:delivery-source:*" } } } ] } delivery.logs.amazonaws.com ãprincipalãšããS3ãªããžã§ã¯ãã«å¯Ÿããèš±å¯èšå®ãè¡ããŸããäžèšèšå®ã§ã¯ã¢ã«ãŠã³ãå
ã®å
šãŠã®DeliverySourceããã®æäœãèš±å¯ããŠããŸãããå³å¯ã«ã¯DeliverySourceãäœæåŸããã®ARNãæå®ãããšããã§ãããã Log Deliveryã®äœæ æ¬¡ã«æ¬åœãšãªãLog Deliveryã§ããAWSã³ã³ãœãŒã«äžã§ä»¥äžã®ããã«èšå®ããå€ãã©ãã«å
¥ãã®ããèŠãŠãããŸãã ãªãLog Deliveryé¢é£ãªãœãŒã¹ã¯ãããã us-east-1ã§äœã å¿
èŠãããç¹ã«æ³šæããŠãã ãããéä¿¡å
S3ãã±ããã¯å¥ãªãŒãžã§ã³ã§ãåé¡ãããŸããã ãŸãã¯DeliverySourceãšDeliveryDestinationãäœæããCloudFrontãšS3ãæå®ããŸãã resource "aws_cloudwatch_log_delivery_source" "this" { name = "<é©åœãªsourceå>" log_type = "ACCESS_LOGS" resource_arn = "<CloudFrontã®ARN>" } resource "aws_cloudwatch_log_delivery_destination" "this" { name = "<é©åœãªdestinationå>" # AWSã³ã³ãœãŒã«ã®ãOutput Formatãã«çžåœ # åŸæ¥ã©ããã®å Žåã¯"w3c" output_format = "json" delivery_destination_configuration { # AWSã³ã³ãœãŒã«ã®ãéä¿¡å
S3ãã±ãããã«çžåœ destination_resource_arn = "<å®å
S3ã®ARN>/<ãã°ãŸã§ã®ãã¹>" } } DeliveryDestinationã§ã¯ãã©ãŒããããåºåå
ãã¹ãæå®ã§ããæ¥ä»å¥ãã¹ãªã©ã®èšå®ãã§ããŸããåŸè¿°ããŸããã destination_resource_arn ã«ãã¹éšåãæžããªãå ŽåãDeliveryã®èšå®ã«åœ±é¿ããã®ã§æ³šæããŠãã ããã æåŸã«Deliveryãäœãããšã§å®æã§ãã resource "aws_cloudwatch_log_delivery" "this" { delivery_source_name = aws_cloudwatch_log_delivery_source.this.name delivery_destination_arn = aws_cloudwatch_log_delivery_destination.this.arn # AWSã³ã³ãœãŒã«ã®ãField Delimiterãã«çžåœ # JSONã®å Žåã¯æå®ã§ããªã # field_delimiter = "," # AWSã³ã³ãœãŒã«ã®ããã£ãŒã«ãéžæãã«çžåœ # æªæå®ã®å Žåã¯ããã©ã«ãå€(legacyãšåç)ãèšå®ããã # record_fields = [ ... ] s3_delivery_configuration { # AWSã³ã³ãœãŒã«ã®ãããŒãã£ã·ã§ãã³ã°ãã«çžåœ # å¹Žææ¥æä»¥å€ã«{accountid}ã{DitributionId}ãæå®å¯èœ suffix_path = "/{yyyy}/{MM}/{dd}/{HH}" # AWSã³ã³ãœãŒã«ã®ããã€ãäºæã®ãã¡ã€ã«å圢åŒãã«çžåœ # trueã®å Žåããã¬ãŒã¹ãã«ãã®æ¿å
¥å€ã"year=2025"ã®ããã«ãªã enable_hive_compatible_path = false } } suffix_pathã¯DeliveryDestinationã§èšå®ãã destination_resource_arn ã®åŸã«ç¶ããã¹ã«ãªããŸããããã®æå®ãåä»ã§ã destination_resource_arn ã®å€ã«ãã£ãŠå®éã®èšå®å€ãå€ãããŸãã ãã¹ãæå®ããå Žå æå®ãã suffix_path ããã®ãŸãŸäœ¿ããã ãã¹ãæå®ããªãã£ãå Žå æå®ãã suffix_path ã®å
é ã« AWSLogs/{account-id}/CloudFront /ã远å ããã ãã®ãããã®ä»æ§ã¯ããããããããå
¬åŒããã¥ã¡ã³ãã«èŒã£ãŠãã ãã¹ã®èšå®äŸ ãåç
§ããããšãããããããŸãã æ³šæ æšæºãã°(legacy)ã«ã€ããŠ æšæºãã°v2ã¯åŸæ¥ã®æšæºãã°(legacy)ãšã¯ç¬ç«ããæ©èœã§ããv2çšã®èšå®ã远å ããã ãã ãšäºéåºåã«ãªã£ãŠããŸããããç¡å¹åãå¿ããªãããã«ããŸãããã AWSã³ã³ãœãŒã«äžããæäœããå Žå AWSã³ã³ãœãŒã«äžããæšæºãã°v2ãäœæããå Žåããã®è£ã§å
è¿°ã®3ãªãœãŒã¹ãäœæãããŸãããã®ãã¡DeliverySource㯠ãã°ãç¡å¹åããŠãæ¶ãããæ®ãç¶ããŸã ã1ã€ã®ãªãœãŒã¹ã«å¯ŸããŠDeliverySourceã¯1ã€ããäœæã§ããªããããæ®ã£ãŠãããšTerraformããã®äœæã倱æããŸãã AWSã³ã³ãœãŒã«äžããã¯åé€ããææ®µããªããããAWS CLIããåé€ããŠãã ããã # æ¢åã®DeliverySourceãæ€çŽ¢ % aws logs describe-delivery-sources --region us-east-1 { "deliverySources": [ { # èªåäœæãããDeliverySourceã¯CreatedByCloudFront-XXXã®åœåã«ãªã£ãŠããŸã "name": "CreatedByCloudFront-XXXXXXXXXX", "arn": "arn:aws:logs:us-east-1:{my-account}:delivery-source:CreatedByCloudFront-XXXXXXXXXX", "resourceArns": [ "arn:aws:cloudfront::{my-account}:distribution/XXXXXXXXXX" ], "service": "cloudfront", "logType": "ACCESS_LOGS" } ] } # DeliverySourceãåé€ % aws logs delete-delivery-source --name CreatedByCloudFront-XXXXXXXXXX --region us-east-1 ãŸãšã Terraformã§ã®CloudFront æšæºãã°v2ã®èšå®æ¹æ³ãã玹ä»ããŸããã æšæºãã°v2ã®ç»å Žã«ãããCloudFrontã®ãã°åšãã®èŸããäžæ°ã«è§£æ¶ãããããã«ãªããŸããS3ã«éä¿¡ããäžã§ã¯æéãå€ãããªããããç©æ¥µçã«ç§»è¡ããããããããæ©èœã§ãã ãŸãå®äœãšãªãCloudWatch Log Delivery(v2)ã¯CloudFrontã«éããªãæ±çšçãªä»çµã¿ã«ãªã£ãŠãããä»ãµãŒãã¹ãžå±éããŠããããšãæåŸ
ãããŸããALBã®ãã°ãªã©ã察å¿ããã°ããèªç±ãªèšå®ãå¯èœã«ãªããããä»åŸã®å±éã«æåŸ
ããããšããã§ãã æ¬èšäºãçæ§ã®è¯ãTerraformã©ã€ãã®äžå©ã«ãªãã°å¹žãã§ãã