Ubieã«ããããã©ãããã©ã¼ã ã¨ã³ã¸ãã¢ãªã³ã°ã®åãçµã¿2023
Ubie Engineering Advent Calendar 2023 ã®22æ¥ç®ã®è¨äºã§ã¯ãUbieã®ãã©ãããã©ã¼ã ã§çãã¦ãã課é¡ã¨ãããã解決ããããã«ãµã¼ãã¹ãã³ãã¬ã¼ãã£ã³ã°ãã¼ã«ãéçºã»å°å ¥ããåãçµã¿ã«ã¤ãã¦ç´¹ä»ãã¾ãã
- ã¯ããã«
- ãã©ãããã©ã¼ã ã¨ã³ã¸ãã¢ãªã³ã°ã¨ã¯
- å ·ä½çãªèª²é¡
- 解決æ³
- ãããã«
- ãã¾ã
ã¯ããã«
ã¢ãã«ã¬åæ¥ã®è¨äºã§ç´¹ä»ããã£ãããã«ãUbieã§ã¯ã¢ã¸ã¥ã©ã¢ããªã¹ã¨ãã¤ã¯ããµã¼ãã¹ã¢ã¼ããã¯ãã£ã®ä¸¡æ¹ãæ¡ç¨ãã¦ãããç¬ç«ãã¦åããµã¼ãã¹æ°ã¯ç¾å¨70è¿ãã«åãã§ãã¾ãããããã®ã¤ã³ãã©ã®å¤§é¨åã¯Google Cloudä¸ã®GKEãCloudRunã§åãã¦ããããã®ç®¡çã¨éç¨ãç§ã®æå±ããåºç¤ãã¼ã ã®è²¬åã«ãªãã¾ãã
æ°ããªãã¤ã¯ããµã¼ãã¹ãç«ã¡ä¸ããæã¯ãåºæ¬çã«ã³ã¼ããæ¸ãã¢ããªã±ã¼ã·ã§ã³ã¨ã³ã¸ãã¢ããµã¼ãã¹ã®ç«ã¡ä¸ãã«å¿ è¦ãªTerraformãk8sãããã§ã¹ããæ¸ããåºç¤ãã¼ã ã®ã¬ãã¥ã¼ãéãã¦å®ç°å¢ã«ãããã¤ãã¾ããã¤ã³ãã©ã«ã¢ããªã±ã¼ã·ã§ã³é½åã§å¤æ´ãå ããããªã£ãæãåæ§ã§ãããã®ãããªã³ã¼ããæ¸ãã人ãï¼åºç¤ãã¤ã³ãã©ãã¼ã ã®æ¯æ´ãåãã¤ã¤ï¼éç¨ã¾ã§è¡ãã¨ããã¢ã¤ãã¢ã¯DevOpsã®ååã¨ãããè¿å¹´ã®ã½ããã¦ã§ã¢ã¨ã³ã¸ãã¢ãªã³ã°ã§ã¯è¯ããã©ã¯ãã£ã¹ã¨ãã¦åºã浸éãã¦ãã¾ãã
䏿¹ã§ããã®ãããªãµã¼ãã¹ã®ã¤ã³ãã©ãæ±ãããã«ã¯ææ¡ããªãã¨ãããªããã¨ãå¤ããæéã¨æ°åãæ¶è²»ããã¨ãã£ã課é¡ãããã¾ãããå ·ä½çã«ã¯æ¬¡ã®ãããªãã®ã§ãã
- æ±ããããµã¼ãã¹ãåå¨ããGCPããã¸ã§ã¯ããGKEã¯ã©ã¹ã¿ãåãããªã
- k8sãã¯ããã¨ããã¯ã©ã¦ããã¤ãã£ãç³»ã®ãã¼ã«ããã©ãããã©ã¼ã ã®ä½¿ãæ¹ãææ¡ããã®ã大å¤
- ä½ãä¸å ·åããã£ãæã«è¦ãCIã®å±¥æ´ããã°ã®å ´æãçºè¦ããã®ã«æéãããã
Ubieã§ã¯GCPã®ããã¸ã§ã¯ããGKEã®ã¯ã©ã¹ã¿ã¯ã»ãã¥ãªãã£ä¸ã®çç±ãªã©ããããã¤ãã®åä½ã«åå²ããã¦ãã¾ãããã®ãããªç¶æ ã®ä¸ã§ãã¢ããªã±ã¼ã·ã§ã³ã¨ã³ã¸ãã¢ãé©åãªããã¸ã§ã¯ããã¯ã©ã¹ã¿ã鏿ãããã®ä¸ã«ãã¹ããã©ã¯ãã£ã¹ã«æ²¿ã£ãå½¢ã§ãµã¼ãã¹ãèµ·åããã®ã¯ãªããªãéª¨ã®æãã使¥ã§ããã¾ãèµ·åæã ãã§ãªãéç¨ä¸ã§ãã£ã¦ãããã¼ã«ã®ä½¿ãæ¹ããã°ã®è¦æ¹ãããããªãã¨ãã£ãåé¡ãçãã¦ãã¾ããã
ããã§ã¯ããããèªç¥è² è·(Cognitive Load)ã®å¢å¤§ãèµ·ãã£ã¦ããããããç´ æ©ããµã¼ãã¹ã®ç«ã¡ä¸ãã¨å¤æ´ã妨ãã¦ããã¨ããç¶æ ãèµ·ãã£ã¦ãããã®ã¨èãããã¾ããããã«ç¾å¨ãå種ãµã¼ãã¹ããã¡ã¤ã³ã«æ²¿ã£ã¦é©åãªã¯ã©ã¹ã¿ã¸é ç½®ãç´ãã¨ãã£ãç§»è¡ããã¸ã§ã¯ããèµ°ã£ã¦ãããä»å¾ã¾ãã¾ãã¤ã³ãã©ã®è¤é度ãå¢ãã¦ããè¦è¾¼ã¿ãããã¾ããã
what the CNCF sold me VS what I really get pic.twitter.com/X5pygpSE2W
— memenetes (@memenetes) March 20, 2023
ããã§ãè¿å¹´æ¥éã«æ³¨ç®ãæµ´ã³ã¦ãããã©ãããã©ã¼ã ã¨ã³ã¸ãã¢ãªã³ã°ã®ã¢ããã¼ããããããã®åé¡è§£æ±ºã«åãçµã¿ã¾ããã
ãã©ãããã©ã¼ã ã¨ã³ã¸ãã¢ãªã³ã°ã¨ã¯
ã¬ã¼ããã¼ã®ããã°ã§ã¯æ¬¡ã®ããã«å®ç¾©ããã¦ãã¾ãã
Platform engineering improves developer experience and productivity by providing self-service capabilities with automated infrastructure operations. It is trending because of its promise to optimize the developer experience and accelerate product teamsâ delivery of customer value.
ã¤ã¾ããã¤ã³ãã©ãªãã¬ã¼ã·ã§ã³ã®ã»ã«ããµã¼ãã¹æ©è½ãæä¾ãããã¨ã§ãéçºè ä½é¨ã¨çç£æ§ãåä¸ããã顧客ã«ç´ æ©ã価夿ä¾ã§ããããã«ãããã®ããã©ãããã©ã¼ã ã¨ã³ã¸ãã¢ãªã³ã°ã§ããç¹ã«ã»ã«ããµã¼ãã¹æ©è½ãæä¾ããã¨ããã®ããã¤ã³ãã§ããããã«ãããã¢ããªã±ã¼ã·ã§ã³ã¨ã³ã¸ãã¢ãã¤ã³ãã©é¨åãå ¨ã¦ã¤ã³ãã©æ å½è ã¸ä¾é ¼ãã¦ãã£ã¦ãããï¼DevOps以åã«éæ»ãï¼ã®ã§ã¯ãªããã¾ãè¤éããå¢ãã¯ã©ã¦ããã¤ãã£ãæä»£ã®ãã¼ã«ããã©ãããã©ã¼ã ã®æ±ãã«ç²å¼ããã®ã§ããªããåéçºçµç¹ã®è¦æ¨¡ãäºæ ã«åããã¦ä½ããããã¼ã«ããµã¼ãã¹ã使ããèªèº«ã§ã¤ã³ãã©ã®ç®¡çããããã¨ãã§ããããã«ãªãã¨ããã¦ãã¾ãã
æ¥æ¬èªã ã¨ä¸è¨ã®ã¹ã©ã¤ããåèã«ãªãã¾ãã
å ·ä½çãªèª²é¡
ãã¯ããã«ãã§è¿°ã¹ãã¨ãããUbieã§ã¯å¤§é¨åã®ãµã¼ãã¹ãGKEãCloudRunä¸ã§èµ·åãã¦ãã¾ãããããã®ãããã§ã¹ãã¯ã¢ãã¬ãã§ç®¡çãããå ¨ã¦ã®ãµã¼ãã¹ã®è¨å®ã1ã¤ã®ãªãã¸ããªã«å«ã¾ãã¦ãã¾ãã
æ°ãããµã¼ãã¹ãç«ã¡ä¸ããéãã»ã¨ãã©ã®ã¢ããªã±ã¼ã·ã§ã³ã¨ã³ã¸ãã¢ã¯æ¢åã®ãµã¼ãã¹ãåèã«ãã¦Terraformãk8sã®ãããã§ã¹ããªã©ã使ãã¦ãã¾ããã1ããyamlãæ¸ãã®ã¯å¤§å¤ãªã®ã§ããããã®ãæ®éã ã¨æãã¾ãããããã«ã¯æ¬¡ã®ãããªèª²é¡ãããã¾ããã
- k8sãããã§ã¹ãããã¹ããã©ã¯ãã£ã¹ã«æ²¿ã£ãå½¢ã§æ¸ãã®ãé£ãã
- ä»ãµã¼ãã¹ããã³ããã§ä½ãã¨å¤ããµã¼ãã¹ã®API versionãæ®ã£ãããä¸è¦ãªãªã½ã¼ã¹ãä½ãããããã
- ãããã§ã¹ãã®æ¸ãæã«ãã£ã¦ã¹ã¿ã¤ã«ã質ãã¾ã°ãã«ãªãã管çãé£ãããªã
PodDisruptionBudget
ããã£ãããªãã£ãã- ã¡ã¤ã³ã¨ãªãã³ã³ããã®ååã
app
ã ã£ãããµã¼ãã¹åã ã£ãã
- åºç¤ãã¼ã ãã¬ãã¥ã¼ããéã«ç¢ºèªãã¹ããã¡ã¤ã«ãç®æãå¤ããæããæ¼ããçãã
解決æ³
ãµã¼ãã¹ãã³ãã¬ã¼ãã£ã³ã°ãã¼ã«ãéçºããããã«ãããã§ã¹ããCI/CDã®è¨å®ãçæããããã¨ã§è§£æ±ºã試ã¿ã¾ããããµã¼ãã¹ãã³ãã¬ã¼ãã¨ããã®ã¯ããµã¼ãã¹ãèµ·åããã®ã«å¿ è¦ãªè¨å®ä¸å¼ãå«ãããã±ã¼ã¸ã®ãã¨ã§ããããã«ããæå°éã®ãã©ã¡ã¼ã¿ããä¸è²«æ§ã®ããè¨å®ãã¡ã¤ã«ãç´ æ©ãçæãããã¨ãå¯è½ã«ãªãã¾ãããµã¼ãã¹ãã³ãã¬ã¼ãã¯ã»ã«ããµã¼ãã¹æ©è½ãå®ç¾ãããã®ã¨ãã¦ããã©ãããã©ã¼ã ã¨ã³ã¸ãã¢ãªã³ã°ã®ä¸è¦ç´ ã¨ããã¦ãã¾ãã
ãã®ãã¼ã«ã¯ç¤¾å ã§ubieformã¨å¼ã°ãã¦ããã®ã§ããã®è¨äºã§ã以éãã®ããã«å¼ã³ã¾ãã
å ·ä½ä¾
ubieformã使ã£ã¦æ°ããªãµã¼ãã¹ãèµ·åããå ·ä½ä¾ã示ãã¾ãã
- 以ä¸ã®ãããªè¨å®ãæ¸ãã¾ãã
name: "sample" env: ["qa", "stg", "prd"] segment: "sample-segment" service_config: { github_actions: { pipelines: [ { envs: ["qa"] }, { envs: ["stg", "prd"] }, ] } manifest: { app: { main_container: { image_path: "asia-northeast1-docker.pkg.dev/example/{{.Env}}/sample" image_tag: {{ if or (eq .Env "stg") (eq .Env "prd") }}"v1.0.0"{{ else }}"aabbccddee"{{ end }} args: ["serve"] ports: [ { name: "http-web" container_port: 8080 }, ] readiness_probe: { path: "/health/readiness" port: "http-web" } config_names: ["sample-env"] } sidecars: [_alloydb_proxy] gcp_service_account: "jp-sample-app-{{.Env}}@example-{{.Env}}.iam.gserviceaccount.com{{- end}}" export_service: true } configs: [ { name: "sample-env", values: [ { key: "sample_DB_HOST" value: "127.0.0.1" }, { key: "sample_DB_NAME", value: "sample" }, ] } ] } backstage: [ { description: "awesome service" } ] cloud_deploy: { pipelines: [ { content: { envs: ["qa"] } }, { content: { envs: ["stg", "prd"] } } ] } } _alloydb_proxy: {}
2.æ¸ããã³ã³ãã£ã°ãubieformãªãã¸ããªå ã®æå®ã®ãã£ã¬ã¯ããªã«ã³ããããã¦ããã·ã¥ãããã«ãªã¯ã使ãã¾ãã
3.CIã«ãã£ã¦ä½æãããã³ã¡ã³ãããã使ããããããã§ã¹ãã確èªãã¾ãã
4.ã¬ãã¥ã¼ãæ¸ã¿ãã¼ã¸ãããã¨ããããã§ã¹ããCI/CDã®è¨å®ãã¾ã¨ã¾ã£ã¦ãã¢ãã¬ãã¸ä»¥ä¸ã®ãããªæ°è¦çæãã¡ã¤ã«ãå«ããã«ãªã¯ã使ããã¾ãã
sample âââ backstage/ENV.yaml # ENVã¯qa, stg, prdã«ç½®æããããããçæããã âââ clouddeploy/ENV.yaml âââ skaffold.yaml âââ app â âââ ENV â âââ deployment.yaml â âââ destinationrule.yaml â âââ service.yaml â âââ serviceaccount.yaml â âââ virtualservice.yaml âââ config âââ ENV âââ configmaps.yaml ââ .github/workflows/sample_ENV.yaml ââ run/flow/production/config.yaml (update only)
5.ã¢ãã¬ãã«ä½æããããã«ãªã¯ããã¼ã¸ããã¨ãGitHub Actionsã«ãã£ã¦Cloud Deployã®ãã¤ãã©ã¤ã³ãããã¯ããããµã¼ãã¹ãèµ·åãã¾ãã
ãã®ãããªæé ãåããã¨ã§ç°¡åã«ãµã¼ãã¹ãç«ã¡ä¸ãããã¨ãã§ãã¾ããä¸è¨ã®ä¾ã¯ããªãã·ã³ãã«ãªãµã¼ãã¹ã®ä¾ã§ãä»ã«ãDBã®ãã¤ã°ã¬ã¼ã·ã§ã³ã¸ã§ãããå ¬éãµã¼ãã¹ã«ä»éããadminç³»ã®ãµã¼ãã¹ãã·ã¼ã¯ã¬ãããHPAãIstioã®AuthorizationPolicyãªã©æ§ã ãªãªã½ã¼ã¹ãçæãããã¨ãã§ãã¾ãã
å®éã«ã¯GKE Workload Identityã®è¨å®ããããããªãã¸ã§ã¯ãã¹ãã¬ã¼ã¸ãDBã®ä½æãå¿ è¦ã«ãªããã¨ãå¤ããããTerraformãå¥éæ¸ãå¿ è¦ãããã¾ããTerraformã®ã³ã¼ãã¯ubieformããã«ãªã¯ãåºãã¢ãã¬ãã¨ã¯å¥ã®ã¢ãã¬ãã«ãªã£ã¦ãããããã¸ã®ã³ã¼ãçæã¯ã¾ã ãµãã¼ãã§ãã¦ãã¾ããã
ããã«ãã¤ã³ã¿ã¼ããããã使ãããµã¼ãã¹ã«ãã©ãã£ãã¯ãæµãã«ã¯Istioã®Gatewayã«ç´ã¥ãVirtualServiceãç·¨éããå¿ è¦ãããã¾ããå ¬éã®ã¿ã¤ãã³ã°ã¯ãµã¼ãã¹çæã®ã¿ã¤ãã³ã°ããå¾ã«ãªãã®ãæ®éãªã®ã§ãããã¯æä½æ¥ã§ç·¨éãã¦ãã¾ãã
å®è£
ubieformãä½ãã«ããã£ã¦èãããã¤ã³ãã¯æ¬¡ã®éãã§ãã
- è¨å®è¨è¿°ã®å´åããç´æ¥ãããã§ã¹ããæ¸ãå ´åã¨æ¯è¼ãã¦å¯è½ãªéãæ¸ãã
- æ°ããªèªç¥è² è·ãæå°éã«ã¨ã©ãã
- ãªãã¹ãå®éã«ãããã¤ããåã«ã¨ã©ã¼è¦å ãæé¤ãã
1ã¤ç®ã¯ubieformã®åå¨æç¾©ãªã®ã§æããã§ãã2ã¤ç®ã«é¢ãã¦ãæ°ããªãã¼ã«ãå°å ¥ãããããªã®ã§ãããã§ã¾ãå¥ã®èªç¥è² è·ãçããã®ã¯ä»æ¹ã®ãªããã¨ããããã¾ããããã ãèªç¥è² è·ãä¸ããããã®ãã¼ã«ãèªç¥è² è·ã大ããç£ãã§ãã¾ãã¨å ãåããªãã®ã§ã極åã·ã³ãã«ã§ç°¡åã«æ±ãããã¼ã«ã«ããªãã¦ã¯ãªãã¾ããã3ã¤ç®ã¯lintã®æ©è½ã§ãããk8sãããã§ã¹ãã¨ãã¦æ£ããããã¨ãã以å¤ã«ãUbieã®ãµã¼ãã¹ã¨ãã¦è¨±å®¹ãããã¨ããçµç¹ããªã·ã¼ã®è¦³ç¹ãå«ãã¦æ±ããå¿ è¦ãããã¾ããã
CUE
åé ã®ãããªè¦ä»¶ãæºãããããubieformã«ä¸ããã³ã³ãã£ã°ã®ãã©ã¼ãããã¨ãã¦é¸ãã ã®ããªã¼ãã³ã½ã¼ã¹ã®ãã¼ã¿æ¤è¨¼è¨èªã§ããCUEã§ããCUEã¯JSONã®ã¹ã¼ãã»ããã§ããããè¦ãç®ã¯JSONã¨ä¼¼ã¦ãã¾ãããåã·ã¹ãã ã¨å¶ç´ãå©ç¨ãã¦ãã¼ã¿æ§é ãå®ç¾©ãããã¨ãã§ãã¾ããCUEãé¸ãã çç±ã¯ä¸»ã«æ¬¡ã®éãã§ãã
- ã¹ãã¼ããå®ç¾©ã§ãã
- å¼·åãªåã·ã¹ãã ã¨ããªãã¼ã·ã§ã³ã®ä»çµã¿ãæã¤
- ï¼ã³ã³ãã£ã°ãæ¸ãã ããªãï¼ã·ã³ãã«ã§ããã«æ±ãã
CUEã§ã¯ã¹ãã¼ãã®å®ç¾©ã¨å¤ã«å¯¾ããããªãã¼ã·ã§ã³ãè¨è¿°ãããã¨ã§ãä¸ããããã³ã³ãã£ã°ãè©ä¾¡ãããã¨ãã§ãã¾ããããã«ãã¹ãã¼ãã®æ¸ãæ¹ã工夫ããã°ãubieformã¦ã¼ã¶ãä¸ããã³ã³ãã£ã°ã¯ã·ã³ãã«ã«ãªããCUEã®ç¥èãã»ã¨ãã©ãªãã¦ãã³ã³ãã£ã°ãæ¸ããããã«ãªãã¾ãã
ç°¡åã«ææ³ã®èª¬æããã¦ããã¾ãã以ä¸ã®schema.cueã¯æå¹ãªCUEã®è¨è¿°ã®ä¾ã§ãããã¹ãã¼ãã¨ãã¦ä½¿ããã¨ãã§ãã¾ãã
config: #Config #Config: { // Definition name: =~ "^[a-z][a-z0-9-]{0,61}[a-z0-9]$" // æ£è¦è¡¨ç¾ã§å¶ç´ãã¤ãã env: [#Env, ...#Env] // Definitionã使ã segment: *"shared" | string // *ã¯ããã©ã«ãå¤ã container?: { // ?ã®ãããã£ã¼ã«ãã¯çç¥å¯è½ name: "app" // 宿°æ±ºãæã¡ label: *[name] | [...string] // ä»ã®ãã£ã¼ã«ãåç § } #Env: "dev" | "qa" | "stg" | "prd" // Definitionã®å ¥ãå }
次ã®config.cueã¯å
ã»ã©ã®ã¹ãã¼ãã«å¯¾ããã³ã³ãã£ã°*1ã§ããã¹ãã¼ãã®è¨è¿°ã«ãã£ããããª?
ã*
ãªã©ã®è¨å·ã¯ç»å ´ãã¾ããã
config: { name: "ubieform" env: ["stg", "prd"] }
ããã2ã¤ã®CUEããçæãããå¤ã¯æ¬¡ã®ããã«ãªãã¾ãã
$ cue export schema.cue config.cue { "config": { "name": "ubieform", "env": [ "stg", "prd" ], "segment": "shared" } }
å ã»ã©ã®ã¹ãã¼ãã«å¯¾ãã¦æ¬¡ã®ãããªã³ã³ãã£ã°ã®æ¸ãæ¹ãããã¨å ¨ã¦ã¨ã©ã¼ã«ãªãã¾ãã
name
ãçç¥ããï¼?
ãããã©ã«ãå¤ãç¡ããã£ã¼ã«ãã¯å ¨ã¦å¿ é ï¼env: ["staging", "production"]
ã¨æ¸ãsegnent: "shared"
ã¨ãã£ã¼ã«ãåãtypoãã
ãã®ãããªCUEãæã¤å¼·åãªããªãã¼ã·ã§ã³ã®ä»çµã¿ã«ãã£ã¦ãæ£ç¢ºãªã³ã³ãã£ã°ã®è¨è¿°ãå¯è½ã«ãªãã¾ãã
ãã¦ãããããè¸ã¾ããä¸ã§ä»¥ä¸ã«ubieformã®ã¹ãã¼ãã®ä¸é¨ã示ãã¾ãã
config: #Config #Config: { name: =~ "^[a-z][a-z0-9-]{0,61}[a-z0-9]$" env: [#Env, ...#Env] segment: #Segment // the path to the directory where the manifests and configs are generated destination_dir: *"services/v3/\(name)" | string service_config: close({ platform: *"gke" | "run" // k8s manifest or cloudrun config settings manifest: close({ if platform == "gke" { // main application config app?: #DeploymentResource // ... // migration job config migration?: close({ main_container: #MainContainer sidecars?: [#Sidecar] // GSA email that associated with the KSA. gcp_service_account?: string & =~ "^[a-zA-Z0-9-]+@[a-zA-Z0-9-]+\\.iam\\.gserviceaccount\\.com$" }) configs?: [#Config, ...#Config] secrets?: [#GKESecret, ...#GKESecret] } if platform == "run" { // app is required for run app: close({ main_container: #MainContainer // ... cloudrun_cpu_throttoling: *false | bool cloudrun_startup_cpu_boost: *true | bool }) // ... } }) }) #Env: "dev" | "qa" | "stg" | "prd" #Segment: "shared" | ... | ... | "other" #DeploymentResource: { init_containers?: [...#BaseContainer] main_container: #MainContainer sidecars?: [...#Sidecar] pdb: close({ min_available: *"30%" | string }) ... } ... }
大é¨åãçç¥ãã¦ãã¾ãããé°å²æ°ã¯æ´ããã¨æãã¾ããä¾ãã°#DeploymentResource
ã¯k8sã®Deploymentã¨å¯¾å¿ãã¦ãããã³ã³ããããã¼ãã®è¨å®ãã§ãã¾ããã¾ãubieformã®ã¹ãã¼ãã¯k8sãããã§ã¹ãã«è¨è¿°ã§ããå
¨ã¦ã®ãã£ã¼ã«ããåãå
¥ããããã§ã¯ãªãããµã¼ãã¹ãã¨ã«åºæã®å¤ãåãããéè¦ãªãã£ã¼ã«ãã ããåãå
¥ãã¾ããããã«ãããã®è¨å®å¯è½ãªãã£ã¼ã«ãã®ä¸ã§ããä¸é¨ã®å¿
é ãã£ã¼ã«ããé¤ãã¦å¤§é¨åãããã©ã«ãå¤ãè¨å®ãã¦ãããçç¥å¯è½ã§ãããããå¤ãã®ãµã¼ãã¹ã§100~200è¡ã»ã©ã®CUEãã¡ã¤ã«ãæ¸ãã ãã§æ¸ã¿ã¾ãããããã1000~3000è¡ã»ã©ã®ãããã§ã¹ãã¨CI/CDã®è¨å®ãåãåºããããããããªãã®è¨è¿°éãå§ç¸®ãã¦ããã¨è¨ãã¾ãã
CI/CD
ubieformã¯k8sã®ãããã§ã¹ãã ãã§ã¯ãªãããã®CI/CDã®è¨å®ãçæãããã¨ãã§ãã¾ããubieã§ã¯pushåã®ãªãªã¼ã¹æ¹å¼ãæ¡ç¨ãã¦ãããããã¾ã§ã¯GitHub Actionsããç´æ¥ã¯ã©ã¹ã¿ã«applyãã¦ãã¾ããã
䏿¹ãubieformã§çæãããµã¼ãã¹ã§ã¯GitHub Actionsã«å ãã¦GCPã®ããã¼ã¸ããµã¼ãã¹ã§ããCloud Deployãå©ç¨ãã¾ããCloud Deployæ¡ç¨ã®çµç·¯ãã¡ãªãããªã©ã¯åããã¼ã ã®@sakajunqualityãããè¨äºãæ¸ãã¦ããã®ã§ãã¡ããåç §ãã ããã
Cloud Deployãå©ç¨ããã«ã¯ãDeliveryPipeline, Targetã®è¨å®ã«å ãã¦Skaffoldã®è¨å®ãä¸ããå¿ è¦ãããããæã§æ¸ãã¨å°ã 大å¤ã§ãããããubieformãããã°ãã®ãããªã³ã³ãã£ã°ã§ãã¤ãã©ã¤ã³ãç°¡åã«çæã§ãã¾ãã
name: "sample" env: ["qa", "stg", "prd"] segment: "sample-segment" service_config: { // ... cloud_deploy: { pipelines: [ { content: { envs: ["qa"] } }, { content: { envs: ["stg", "prd"] } } ] } }
ãã®è¨å®ã§ã¯qaã®ãã¤ãã©ã¤ã³ã¨ãstgã¨prdãç¹ãããã¤ãã©ã¤ã³ãçæããã¾ãããããã¤ã¿ã¼ã²ããã¨ãªãGCPããã¸ã§ã¯ããã¯ã©ã¹ã¿ã®è¨å®ãæ¸ããã¨ãã§ãã¾ãããã»ã¨ãã©ã®ã±ã¼ã¹ã§segment
ã¨env
ã«å¯¾å¿ãã¦èªåã§æ±ºã¾ãããã«ãªã£ã¦ãããããã¢ããªã±ã¼ã·ã§ã³ã¨ã³ã¸ãã¢ããããæ°ã«ããå¿
è¦ã¯ããã¾ããã
ç»åã®ãããªprdã®åã«stgã«ãããã¤ãæåãã¦ãããã¨ãä¿è¨¼ãããããªãã¤ãã©ã¤ã³ãç°¡åã«ä½ããã¨ãã§ãã¾ããããã«ãprdã®ãããã¤ã®åã«ã¯IAMã§ç®¡çãããApprovalãæã¾ãã¦ãããããç¹å®ã®äººä»¥å¤ãprdã«å¯¾ãã¦ãªãªã¼ã¹ã§ããªããããªä»çµã¿ã«ãªã£ã¦ãã¾ãã
ãããã§ã¹ãã®æ´æ°
k8sã¨ã³ã·ã¹ãã ã¯æ´»çºã«éçºãç¶ãããã¦ãããã¢ãããã¼ãã«ä¼´ã便å©ãªæ©è½ã使ããããã«ãªã£ããããªã½ã¼ã¹ã®apiVersion
ãä¸ãã£ããã¨ãã£ããã¨ãããããã¾ããããããæã¯è¤æ°ã®ãµã¼ãã¹ã®ãããã§ã¹ããæ¨ªæçã«æ´æ°ããããªããããæ¤ç´¢ç½®æãªã©ãé§ä½¿ãã¦ãªãã¨ãããå¿
è¦ãããã¾ãããããã§ããã£ã¼ã«ãã®è¿½å ãªã©ã¯ãã¾ããããªãå¯è½æ§ãããã¾ããããã§ubieformã¯ãã®ãããªä¸æ¬æ´æ°ã®ã¦ã¼ã¹ã±ã¼ã¹ããµãã¼ãããããã«ãã¾ããã
ubieformèªä½ã¯å é¨ã«ãããã§ã¹ãã®ãã³ãã¬ã¼ããæã£ã¦ããããããã¬ã³ããªã³ã°ãããã¨ã§ãã¡ã¤ã«ãçæãã¾ããä¾ãã°å ã»ã©ç´¹ä»ããCloud Deployã使ãéã«å¿ è¦ã¨ãªãSkaffoldã®ãã³ãã¬ã¼ãã¯æ¬¡ã®ããã«ãªã£ã¦ãã¾ãã
apiVersion: skaffold/v4beta6 kind: Config metadata: name: {{.Name}} {{- if .CustomActions}} customActions: {{- range $action := .CustomActions}} - name: {{$action.Name}} containers: - name: {{$action.Name}} image: {{$action.Image}} args: {{- range $arg := $action.Args}} - {{$arg}} {{- end}} {{- end }} {{- end }} profiles: {{- range $profile := .Profiles}} - name: {{$profile.Name}} deploy: statusCheckDeadlineSeconds: 600 tolerateFailuresUntilDeadline: true {{- if $.IsCloudRun }} cloudrun: {} {{- end}} manifests: rawYaml: {{- range $path := $profile.Paths}} - {{$path}} {{- end}} {{- end }}
ãã®ãããªãã³ãã¬ã¼ããããããã§ã¹ããªã©ãçæãããã¨ã§ããã£ã¼ã«ãã«è¿½å ãæ´æ°ããããéã¯ãã³ãã¬ã¼ãã«æãå ããã ãã§æ¸ã¿ã¾ããå ·ä½ä¾ã®é ã§è¦ããããã«ãå ¨ãµã¼ãã¹ã®ã³ã³ãã£ã°ã1ç®æï¼ubieformã®ãªãã¸ããªå ï¼ã§ç®¡çãã¦ããã®ãããã®ãããªä¸æ¬æ´æ°ã®æã«ã¾ã¨ãã¦å®è¡ããããããããã§ãã
ãµã¼ãã¹ã«ã¿ãã°
ubieformã¯ããªã¼ãã³ã½ã¼ã¹ã®Developer Portalã§ããBackStageã®ãµã¼ãã¹ã«ã¿ãã°è¨å®ãçæãããã¨ãã§ãã¾ããBackStageèªä½ã«ã¤ãã¦ã®è©³ç´°ãªèª¬æãå°å ¥ã®çµç·¯ã«ã¤ãã¦ã¯ä»ã®è¨äºã«è²ãã¾ãããããã¯ãµã¼ãã¹ã«é¢ããæ§ã ãªæ å ±ãã¾ã¨ãã¦ç¢ºèªã§ããéçºè ã®ããã®ç¤¾å ãã¼ã¿ã«ãµã¤ãã§ãããå¢ãç¶ããèªç¥è² è·ã軽æ¸ããããã«å°å ¥ãã¦ãã¾ãã
BackStageèªä½ã«ã¯ãã©ã°ã¤ã³æ©æ§ããããKubernetesãã©ã°ã¤ã³ãå°å ¥ãããã¨ã§Podã®ã¹ãã¼ã¿ã¹ã確èªã§ãããªã©ä¾¿å©ã«å©ç¨ã§ããããã«ãªãã¾ãããã®è¾ºãã®ãã¼ã¿ã«æ©è½ã®æ¡å ã¯ä»å¾é²ãã¦ããäºå®ã§ãã
ubieformã®ç¾å¨ã¨ä»å¾
ãã¯ããã«ãã§è¿°ã¹ãããã«ãç¾å¨å種ãµã¼ãã¹ããã¡ã¤ã³ã«æ²¿ã£ã¦é©åãªã¯ã©ã¹ã¿ã¸é ç½®ãç´ãã¨ãã£ãç§»è¡ããã¸ã§ã¯ããé²è¡ä¸ã§ãããã®ç§»è¡ä½æ¥ã®1ã¹ãããã¨ãã¦ãubieformã使ããã¨ã§æ¢åã®ãµã¼ãã¹ãä½ãç´ãã¨ãããã¨ããã¦ãã¾ãããããã£ããã³ãã¬ã¼ããã¼ã«ã¯æ¢åã®ãµã¼ãã¹ã®è¼ãæ¿ããããã®ãã©ããã¨ããåé¡ãä»ãçºããã¡ã§ãããubieformã¯ãã®ç¨éãæåããæ±ºã¾ã£ã¦ããããããã®æ¸å¿µã¯ããã¾ããã§ãããå ¨ç¤¾ã«æä¾ããåã«åºç¤ãã¼ã ã§ããã°ãã¼ãã£ã³ã°ã§ããã¨ããç¹ã«ã大ããªã¡ãªãããæãã¦ãã¾ãã
ubieformããµã¼ãã¹ã«ã¿ãã°ãã¾ã 社å ã«ãã¼ã¿çã¨ãã¦ã²ã£ããã¨å ¬éããæ®µéã§ãã¾ã æ£å¼ãªå¨ç¥ããã¦ããªã段éã§ããæ°è¦ãµã¼ãã¹ãç«ã¡ä¸ãããã¨åãåããããã¦ããã¨ã³ã¸ãã¢ã«ä½¿ã£ã¦ããã£ã¦ãããããããããå®éã«ã©ã®ç¨åº¦éçºå¹çã«å¹æããã£ãã®ãã¨ããå®éã»å®æ§çãªè©ä¾¡ããã¦ãããã°ã¨æã£ã¦ãã¾ãã
ãããã«
æ¬è¨äºã§ã¯Ubieã«ããããã©ãããã©ã¼ã ã¨ã³ã¸ãã¢ãªã³ã°ã®åãçµã¿ã¨ãã¦ãµã¼ãã¹ãã³ãã¬ã¼ãã£ã³ã°ãã¼ã«ã§ããubieformã«ã¤ãã¦ç´¹ä»ãã¾ãããUbieã§ã¯ä»å¾ãå¼ãç¶ãDeveloper Experienceã«æè³ãç¶ãã¦ããã¾ãã
Ubieã§ã¯å種ã½ããã¦ã§ã¢ã¨ã³ã¸ãã¢ãåéãã¦ãã¾ãã
ãã¾ã
人å100%ã§æ¸ããã®ã§AIç¡æ·»å ã®ã¹ããã«ã¼ãè²¼ã£ã¦ããã¾ã*2
*1:便å®ä¸ãã®ãããªæ¸ãæ¹ããã¦ãã¾ãããCUEã§ã¯ãã®2ã¤ã¯æç¢ºã«åºå¥ããã¾ãããhttps://cuelang.org/docs/tutorials/tour/intro/cue/
*2:ChatGPTçµã¿è¾¼ã¿ã®DALL-Eã§çæ