[{"data":1,"prerenderedAt":1119},["ShallowReactive",2],{"/ja-jp/blog/categories/engineering/":3,"navigation-ja-jp":22,"banner-ja-jp":439,"footer-ja-jp":452,"engineering-category-page-ja-jp":661},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":11,"config":12,"_id":15,"_type":16,"title":17,"_source":18,"_file":19,"_stem":20,"_extension":21},"/ja-jp/blog/categories/engineering","categories",false,"",{"title":9,"description":10},"エンジニアリング","Browse articles related to エンジニアリング on the GitLab Blog",{"name":9},{"template":13,"slug":14,"hide":6},"BlogCategory","engineering","content:ja-jp:blog:categories:engineering.yml","yaml","Engineering","content","ja-jp/blog/categories/engineering.yml","ja-jp/blog/categories/engineering","yml",{"_path":23,"_dir":24,"_draft":6,"_partial":6,"_locale":7,"data":25,"_id":435,"_type":16,"title":436,"_source":18,"_file":437,"_stem":438,"_extension":21},"/shared/ja-jp/main-navigation","ja-jp",{"logo":26,"freeTrial":31,"sales":36,"login":41,"items":46,"search":379,"minimal":413,"duo":426},{"config":27},{"href":28,"dataGaName":29,"dataGaLocation":30},"/ja-jp/","gitlab logo","header",{"text":32,"config":33},"無料トライアルを開始",{"href":34,"dataGaName":35,"dataGaLocation":30},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":37,"config":38},"お問い合わせ",{"href":39,"dataGaName":40,"dataGaLocation":30},"/ja-jp/sales/","sales",{"text":42,"config":43},"サインイン",{"href":44,"dataGaName":45,"dataGaLocation":30},"https://gitlab.com/users/sign_in/","sign in",[47,91,190,195,301,361],{"text":48,"config":49,"cards":51,"footer":74},"プラットフォーム",{"dataNavLevelOne":50},"platform",[52,58,66],{"title":48,"description":53,"link":54},"最も包括的かつAIで強化されたDevSecOpsプラットフォーム",{"text":55,"config":56},"プラットフォームを詳しく見る",{"href":57,"dataGaName":50,"dataGaLocation":30},"/ja-jp/platform/",{"title":59,"description":60,"link":61},"GitLab Duo（AI）","開発のすべてのステージでAIを活用し、ソフトウェアをより迅速にビルド",{"text":62,"config":63},"GitLab Duoのご紹介",{"href":64,"dataGaName":65,"dataGaLocation":30},"/ja-jp/gitlab-duo/","gitlab duo ai",{"title":67,"description":68,"link":69},"GitLabが選ばれる理由","GitLabが大企業に選ばれる理由10選",{"text":70,"config":71},"詳細はこちら",{"href":72,"dataGaName":73,"dataGaLocation":30},"/ja-jp/why-gitlab/","why gitlab",{"title":75,"items":76},"利用を開始：",[77,82,87],{"text":78,"config":79},"プラットフォームエンジニアリング",{"href":80,"dataGaName":81,"dataGaLocation":30},"/ja-jp/solutions/platform-engineering/","platform engineering",{"text":83,"config":84},"開発者の経験",{"href":85,"dataGaName":86,"dataGaLocation":30},"/ja-jp/developer-experience/","Developer experience",{"text":88,"config":89},"MLOps",{"href":90,"dataGaName":88,"dataGaLocation":30},"/ja-jp/topics/devops/the-role-of-ai-in-devops/",{"text":92,"left":93,"config":94,"link":96,"lists":100,"footer":172},"製品",true,{"dataNavLevelOne":95},"solutions",{"text":97,"config":98},"すべてのソリューションを表示",{"href":99,"dataGaName":95,"dataGaLocation":30},"/ja-jp/solutions/",[101,127,150],{"title":102,"description":103,"link":104,"items":109},"自動化","CI/CDと自動化でデプロイを加速",{"config":105},{"icon":106,"href":107,"dataGaName":108,"dataGaLocation":30},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[110,114,118,123],{"text":111,"config":112},"CI/CD",{"href":113,"dataGaLocation":30,"dataGaName":111},"/ja-jp/solutions/continuous-integration/",{"text":115,"config":116},"AIアシストによる開発",{"href":64,"dataGaLocation":30,"dataGaName":117},"AI assisted development",{"text":119,"config":120},"ソースコード管理",{"href":121,"dataGaLocation":30,"dataGaName":122},"/ja-jp/solutions/source-code-management/","Source Code Management",{"text":124,"config":125},"自動化されたソフトウェアデリバリー",{"href":107,"dataGaLocation":30,"dataGaName":126},"Automated software delivery",{"title":128,"description":129,"link":130,"items":135},"セキュリティ","セキュリティを損なうことなくコードをより迅速に完成",{"config":131},{"href":132,"dataGaName":133,"dataGaLocation":30,"icon":134},"/ja-jp/solutions/security-compliance/","security and compliance","ShieldCheckLight",[136,141,146],{"text":137,"config":138},"Application Security Testing",{"href":139,"dataGaName":140,"dataGaLocation":30},"/solutions/application-security-testing/","Application security testing",{"text":142,"config":143},"ソフトウェアサプライチェーンの安全性",{"href":144,"dataGaLocation":30,"dataGaName":145},"/ja-jp/solutions/supply-chain/","Software supply chain security",{"text":147,"config":148},"Software Compliance",{"href":149,"dataGaName":147,"dataGaLocation":30},"/solutions/software-compliance/",{"title":151,"link":152,"items":157},"測定",{"config":153},{"icon":154,"href":155,"dataGaName":156,"dataGaLocation":30},"DigitalTransformation","/ja-jp/solutions/visibility-measurement/","visibility and measurement",[158,162,167],{"text":159,"config":160},"可視性と測定",{"href":155,"dataGaLocation":30,"dataGaName":161},"Visibility and Measurement",{"text":163,"config":164},"バリューストリーム管理",{"href":165,"dataGaLocation":30,"dataGaName":166},"/ja-jp/solutions/value-stream-management/","Value Stream Management",{"text":168,"config":169},"分析とインサイト",{"href":170,"dataGaLocation":30,"dataGaName":171},"/ja-jp/solutions/analytics-and-insights/","Analytics and insights",{"title":173,"items":174},"GitLabが活躍する場所",[175,180,185],{"text":176,"config":177},"Enterprise",{"href":178,"dataGaLocation":30,"dataGaName":179},"/ja-jp/enterprise/","enterprise",{"text":181,"config":182},"スモールビジネス",{"href":183,"dataGaLocation":30,"dataGaName":184},"/ja-jp/small-business/","small business",{"text":186,"config":187},"公共機関",{"href":188,"dataGaLocation":30,"dataGaName":189},"/ja-jp/solutions/public-sector/","public sector",{"text":191,"config":192},"価格",{"href":193,"dataGaName":194,"dataGaLocation":30,"dataNavLevelOne":194},"/ja-jp/pricing/","pricing",{"text":196,"config":197,"link":199,"lists":203,"feature":288},"関連リソース",{"dataNavLevelOne":198},"resources",{"text":200,"config":201},"すべてのリソースを表示",{"href":202,"dataGaName":198,"dataGaLocation":30},"/ja-jp/resources/",[204,237,260],{"title":205,"items":206},"はじめに",[207,212,217,222,227,232],{"text":208,"config":209},"インストール",{"href":210,"dataGaName":211,"dataGaLocation":30},"/ja-jp/install/","install",{"text":213,"config":214},"クイックスタートガイド",{"href":215,"dataGaName":216,"dataGaLocation":30},"/ja-jp/get-started/","quick setup checklists",{"text":218,"config":219},"学ぶ",{"href":220,"dataGaLocation":30,"dataGaName":221},"https://university.gitlab.com/","learn",{"text":223,"config":224},"製品ドキュメント",{"href":225,"dataGaName":226,"dataGaLocation":30},"https://docs.gitlab.com/","product documentation",{"text":228,"config":229},"ベストプラクティスビデオ",{"href":230,"dataGaName":231,"dataGaLocation":30},"/ja-jp/getting-started-videos/","best practice videos",{"text":233,"config":234},"インテグレーション",{"href":235,"dataGaName":236,"dataGaLocation":30},"/ja-jp/integrations/","integrations",{"title":238,"items":239},"検索する",[240,245,250,255],{"text":241,"config":242},"お客様成功事例",{"href":243,"dataGaName":244,"dataGaLocation":30},"/ja-jp/customers/","customer success stories",{"text":246,"config":247},"ブログ",{"href":248,"dataGaName":249,"dataGaLocation":30},"/ja-jp/blog/","blog",{"text":251,"config":252},"リモート",{"href":253,"dataGaName":254,"dataGaLocation":30},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":256,"config":257},"TeamOps",{"href":258,"dataGaName":259,"dataGaLocation":30},"/ja-jp/teamops/","teamops",{"title":261,"items":262},"つなげる",[263,268,273,278,283],{"text":264,"config":265},"GitLabサービス",{"href":266,"dataGaName":267,"dataGaLocation":30},"/ja-jp/services/","services",{"text":269,"config":270},"コミュニティ",{"href":271,"dataGaName":272,"dataGaLocation":30},"/community/","community",{"text":274,"config":275},"フォーラム",{"href":276,"dataGaName":277,"dataGaLocation":30},"https://forum.gitlab.com/","forum",{"text":279,"config":280},"イベント",{"href":281,"dataGaName":282,"dataGaLocation":30},"/events/","events",{"text":284,"config":285},"パートナー",{"href":286,"dataGaName":287,"dataGaLocation":30},"/partners/","partners",{"backgroundColor":289,"textColor":290,"text":291,"image":292,"link":296},"#2f2a6b","#fff","ソフトウェア開発の未来への洞察",{"altText":293,"config":294},"ソースプロモカード",{"src":295},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":297,"config":298},"最新情報を読む",{"href":299,"dataGaName":300,"dataGaLocation":30},"/ja-jp/the-source/","the source",{"text":302,"config":303,"lists":305},"Company",{"dataNavLevelOne":304},"company",[306],{"items":307},[308,313,319,321,326,331,336,341,346,351,356],{"text":309,"config":310},"GitLabについて",{"href":311,"dataGaName":312,"dataGaLocation":30},"/ja-jp/company/","about",{"text":314,"config":315,"footerGa":318},"採用情報",{"href":316,"dataGaName":317,"dataGaLocation":30},"/jobs/","jobs",{"dataGaName":317},{"text":279,"config":320},{"href":281,"dataGaName":282,"dataGaLocation":30},{"text":322,"config":323},"経営陣",{"href":324,"dataGaName":325,"dataGaLocation":30},"/company/team/e-group/","leadership",{"text":327,"config":328},"チーム",{"href":329,"dataGaName":330,"dataGaLocation":30},"/company/team/","team",{"text":332,"config":333},"ハンドブック",{"href":334,"dataGaName":335,"dataGaLocation":30},"https://handbook.gitlab.com/","handbook",{"text":337,"config":338},"投資家向け情報",{"href":339,"dataGaName":340,"dataGaLocation":30},"https://ir.gitlab.com/","investor relations",{"text":342,"config":343},"トラストセンター",{"href":344,"dataGaName":345,"dataGaLocation":30},"/ja-jp/security/","trust center",{"text":347,"config":348},"AI Transparency Center",{"href":349,"dataGaName":350,"dataGaLocation":30},"/ja-jp/ai-transparency-center/","ai transparency center",{"text":352,"config":353},"ニュースレター",{"href":354,"dataGaName":355,"dataGaLocation":30},"/company/contact/","newsletter",{"text":357,"config":358},"プレス",{"href":359,"dataGaName":360,"dataGaLocation":30},"/press/","press",{"text":37,"config":362,"lists":363},{"dataNavLevelOne":304},[364],{"items":365},[366,369,374],{"text":37,"config":367},{"href":39,"dataGaName":368,"dataGaLocation":30},"talk to sales",{"text":370,"config":371},"サポートを受ける",{"href":372,"dataGaName":373,"dataGaLocation":30},"/support/","get help",{"text":375,"config":376},"カスタマーポータル",{"href":377,"dataGaName":378,"dataGaLocation":30},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":380,"login":381,"suggestions":388},"閉じる",{"text":382,"link":383},"リポジトリとプロジェクトを検索するには、次にログインします",{"text":384,"config":385},"GitLab.com",{"href":44,"dataGaName":386,"dataGaLocation":387},"search login","search",{"text":389,"default":390},"提案",[391,394,399,401,405,409],{"text":59,"config":392},{"href":64,"dataGaName":393,"dataGaLocation":387},"GitLab Duo (AI)",{"text":395,"config":396},"コード提案（AI）",{"href":397,"dataGaName":398,"dataGaLocation":387},"/ja-jp/solutions/code-suggestions/","Code Suggestions (AI)",{"text":111,"config":400},{"href":113,"dataGaName":111,"dataGaLocation":387},{"text":402,"config":403},"GitLab on AWS",{"href":404,"dataGaName":402,"dataGaLocation":387},"/ja-jp/partners/technology-partners/aws/",{"text":406,"config":407},"GitLab on Google Cloud",{"href":408,"dataGaName":406,"dataGaLocation":387},"/ja-jp/partners/technology-partners/google-cloud-platform/",{"text":410,"config":411},"GitLabを選ぶ理由",{"href":72,"dataGaName":412,"dataGaLocation":387},"Why GitLab?",{"freeTrial":414,"mobileIcon":418,"desktopIcon":423},{"text":32,"config":415},{"href":416,"dataGaName":35,"dataGaLocation":417},"https://gitlab.com/-/trials/new/","nav",{"altText":419,"config":420},"GitLabアイコン",{"src":421,"dataGaName":422,"dataGaLocation":417},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":419,"config":424},{"src":425,"dataGaName":422,"dataGaLocation":417},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"freeTrial":427,"mobileIcon":431,"desktopIcon":433},{"text":428,"config":429},"GitLab Duoの詳細について",{"href":64,"dataGaName":430,"dataGaLocation":417},"gitlab duo",{"altText":419,"config":432},{"src":421,"dataGaName":422,"dataGaLocation":417},{"altText":419,"config":434},{"src":425,"dataGaName":422,"dataGaLocation":417},"content:shared:ja-jp:main-navigation.yml","Main Navigation","shared/ja-jp/main-navigation.yml","shared/ja-jp/main-navigation",{"_path":440,"_dir":24,"_draft":6,"_partial":6,"_locale":7,"title":441,"button":442,"config":447,"_id":449,"_type":16,"_source":18,"_file":450,"_stem":451,"_extension":21},"/shared/ja-jp/banner","GitLab Duo Agent Platformがパブリックベータ版で利用可能になりました！",{"text":443,"config":444},"ベータ版を試す",{"href":445,"dataGaName":446,"dataGaLocation":30},"/ja-jp/gitlab-duo/agent-platform/","duo banner",{"layout":448},"release","content:shared:ja-jp:banner.yml","shared/ja-jp/banner.yml","shared/ja-jp/banner",{"_path":453,"_dir":24,"_draft":6,"_partial":6,"_locale":7,"data":454,"_id":657,"_type":16,"title":658,"_source":18,"_file":659,"_stem":660,"_extension":21},"/shared/ja-jp/main-footer",{"text":455,"source":456,"edit":462,"contribute":467,"config":472,"items":477,"minimal":649},"GitはSoftware Freedom Conservancyの商標です。当社は「GitLab」をライセンスに基づいて使用しています",{"text":457,"config":458},"ページのソースを表示",{"href":459,"dataGaName":460,"dataGaLocation":461},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":463,"config":464},"このページを編集",{"href":465,"dataGaName":466,"dataGaLocation":461},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":468,"config":469},"ご協力をお願いします",{"href":470,"dataGaName":471,"dataGaLocation":461},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":473,"facebook":474,"youtube":475,"linkedin":476},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[478,501,555,587,621],{"title":48,"links":479,"subMenu":484},[480],{"text":481,"config":482},"DevSecOpsプラットフォーム",{"href":57,"dataGaName":483,"dataGaLocation":461},"devsecops platform",[485],{"title":191,"links":486},[487,491,496],{"text":488,"config":489},"プランの表示",{"href":193,"dataGaName":490,"dataGaLocation":461},"view plans",{"text":492,"config":493},"Premiumを選ぶ理由",{"href":494,"dataGaName":495,"dataGaLocation":461},"/ja-jp/pricing/premium/","why premium",{"text":497,"config":498},"Ultimateを選ぶ理由",{"href":499,"dataGaName":500,"dataGaLocation":461},"/ja-jp/pricing/ultimate/","why ultimate",{"title":502,"links":503},"ソリューション",[504,509,512,514,519,524,528,531,534,539,541,543,545,550],{"text":505,"config":506},"デジタルトランスフォーメーション",{"href":507,"dataGaName":508,"dataGaLocation":461},"/ja-jp/topics/digital-transformation/","digital transformation",{"text":510,"config":511},"セキュリティとコンプライアンス",{"href":139,"dataGaName":140,"dataGaLocation":461},{"text":124,"config":513},{"href":107,"dataGaName":108,"dataGaLocation":461},{"text":515,"config":516},"アジャイル開発",{"href":517,"dataGaName":518,"dataGaLocation":461},"/ja-jp/solutions/agile-delivery/","agile delivery",{"text":520,"config":521},"クラウドトランスフォーメーション",{"href":522,"dataGaName":523,"dataGaLocation":461},"/ja-jp/topics/cloud-native/","cloud transformation",{"text":525,"config":526},"SCM",{"href":121,"dataGaName":527,"dataGaLocation":461},"source code management",{"text":111,"config":529},{"href":113,"dataGaName":530,"dataGaLocation":461},"continuous integration & delivery",{"text":163,"config":532},{"href":165,"dataGaName":533,"dataGaLocation":461},"value stream management",{"text":535,"config":536},"GitOps",{"href":537,"dataGaName":538,"dataGaLocation":461},"/ja-jp/solutions/gitops/","gitops",{"text":176,"config":540},{"href":178,"dataGaName":179,"dataGaLocation":461},{"text":181,"config":542},{"href":183,"dataGaName":184,"dataGaLocation":461},{"text":186,"config":544},{"href":188,"dataGaName":189,"dataGaLocation":461},{"text":546,"config":547},"教育",{"href":548,"dataGaName":549,"dataGaLocation":461},"/ja-jp/solutions/education/","education",{"text":551,"config":552},"金融サービス",{"href":553,"dataGaName":554,"dataGaLocation":461},"/ja-jp/solutions/finance/","financial services",{"title":196,"links":556},[557,559,561,563,566,568,571,573,575,577,579,581,583,585],{"text":208,"config":558},{"href":210,"dataGaName":211,"dataGaLocation":461},{"text":213,"config":560},{"href":215,"dataGaName":216,"dataGaLocation":461},{"text":218,"config":562},{"href":220,"dataGaName":221,"dataGaLocation":461},{"text":223,"config":564},{"href":225,"dataGaName":565,"dataGaLocation":461},"docs",{"text":246,"config":567},{"href":248,"dataGaName":249},{"text":569,"config":570},"お客様の成功事例",{"href":243,"dataGaLocation":461},{"text":241,"config":572},{"href":243,"dataGaName":244,"dataGaLocation":461},{"text":251,"config":574},{"href":253,"dataGaName":254,"dataGaLocation":461},{"text":264,"config":576},{"href":266,"dataGaName":267,"dataGaLocation":461},{"text":256,"config":578},{"href":258,"dataGaName":259,"dataGaLocation":461},{"text":269,"config":580},{"href":271,"dataGaName":272,"dataGaLocation":461},{"text":274,"config":582},{"href":276,"dataGaName":277,"dataGaLocation":461},{"text":279,"config":584},{"href":281,"dataGaName":282,"dataGaLocation":461},{"text":284,"config":586},{"href":286,"dataGaName":287,"dataGaLocation":461},{"title":302,"links":588},[589,591,593,595,597,599,601,605,610,612,614,616],{"text":309,"config":590},{"href":311,"dataGaName":304,"dataGaLocation":461},{"text":314,"config":592},{"href":316,"dataGaName":317,"dataGaLocation":461},{"text":322,"config":594},{"href":324,"dataGaName":325,"dataGaLocation":461},{"text":327,"config":596},{"href":329,"dataGaName":330,"dataGaLocation":461},{"text":332,"config":598},{"href":334,"dataGaName":335,"dataGaLocation":461},{"text":337,"config":600},{"href":339,"dataGaName":340,"dataGaLocation":461},{"text":602,"config":603},"Sustainability",{"href":604,"dataGaName":602,"dataGaLocation":461},"/sustainability/",{"text":606,"config":607},"ダイバーシティ、インクルージョン、ビロンギング（DIB）",{"href":608,"dataGaName":609,"dataGaLocation":461},"/ja-jp/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":342,"config":611},{"href":344,"dataGaName":345,"dataGaLocation":461},{"text":352,"config":613},{"href":354,"dataGaName":355,"dataGaLocation":461},{"text":357,"config":615},{"href":359,"dataGaName":360,"dataGaLocation":461},{"text":617,"config":618},"現代奴隷制の透明性に関する声明",{"href":619,"dataGaName":620,"dataGaLocation":461},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":37,"links":622},[623,625,627,629,634,639,644],{"text":37,"config":624},{"href":39,"dataGaName":40,"dataGaLocation":461},{"text":370,"config":626},{"href":372,"dataGaName":373,"dataGaLocation":461},{"text":375,"config":628},{"href":377,"dataGaName":378,"dataGaLocation":461},{"text":630,"config":631},"ステータス",{"href":632,"dataGaName":633,"dataGaLocation":461},"https://status.gitlab.com/","status",{"text":635,"config":636},"利用規約",{"href":637,"dataGaName":638,"dataGaLocation":461},"/terms/","terms of use",{"text":640,"config":641},"プライバシーに関する声明",{"href":642,"dataGaName":643,"dataGaLocation":461},"/ja-jp/privacy/","privacy statement",{"text":645,"config":646},"Cookieの設定",{"dataGaName":647,"dataGaLocation":461,"id":648,"isOneTrustButton":93},"cookie preferences","ot-sdk-btn",{"items":650},[651,653,655],{"text":635,"config":652},{"href":637,"dataGaName":638,"dataGaLocation":461},{"text":640,"config":654},{"href":642,"dataGaName":643,"dataGaLocation":461},{"text":645,"config":656},{"dataGaName":647,"dataGaLocation":461,"id":648,"isOneTrustButton":93},"content:shared:ja-jp:main-footer.yml","Main Footer","shared/ja-jp/main-footer.yml","shared/ja-jp/main-footer",{"featuredPost":662,"allPosts":690,"totalPages":1117,"initialPosts":1118},{"_path":663,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":664,"content":669,"config":683,"_id":686,"_type":16,"title":687,"_source":18,"_file":688,"_stem":689,"_extension":21},"/ja-jp/blog/what-is-platform-engineering",{"config":665,"ogImage":666,"title":667,"description":668},{"noIndex":6},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758508254/duu6d4vclamtnnxjdaat.jpg","プラットフォームエンジニアリングとは？意味や導入メリットをわかりやすく解説","この記事では、プラットフォームエンジニアリングの意味や特徴、導入メリットなどを解説します。具体的な導入ステップや基盤構築に役立つおすすめのプラットフォームも。",{"category":14,"body":670,"date":671,"authors":672,"heroImage":666,"title":667,"description":674,"tags":675},"近年ソフトウェア開発の領域では「プラットフォームエンジニアリング」と呼ばれる開発者の生産性向上に寄与するアプローチが注目されています。\n\n実際にプラットフォームエンジニアリングに興味はあるものの、意味や定義などを詳しく理解していない人も多いのではないでしょうか。\n\nこの記事では、プラットフォームエンジニアリングの意味や特徴、導入メリットなどを解説します。具体的な導入ステップや基盤構築に役立つおすすめのプラットフォームも紹介するのでぜひ参考にして下さい。\n\n## 1. プラットフォームエンジニアリングとは？\n\n![プラットフォームエンジニアリングとは](https://res.cloudinary.com/about-gitlab-com/image/upload/v1758508139/eui82g7mlcb2fr5vavir.jpg)\n\nまずはプラットフォームエンジニアリングの意味や特徴について解説します。\n\n### 1-1. プラットフォームエンジニアリングの意味・特徴\n\nプラットフォームエンジニアリングとは、企業内の開発者に対して適切なプラットフォーム（IDP）を整備し、ソフトウェア開発の効率化や生産性向上を実現するアプローチのことです。\n\n近年はIT技術の発展や消費者ニーズの多様化などを背景として将来の予測が難しい時代（VUCA時代）だと言われています。プラットフォームエンジニアリングは、VUCA時代において複雑化するビジネスニーズに対応するための新しいエンジニアリング手法として、ガートナー社が積極的に提案しているアプローチでもあります。\n\n### 1-2. IDP（内部開発者向けプラットフォーム）とは\n\nInternal Developer Platform（内部開発者向けプラットフォーム、以下IDP）とは、企業内の開発者が開発プロセスにおいて必要な機能やリソースを自ら取得して利用できるプラットフォームを指し、プラットフォームエンジニアリングの導入における重要な技術基盤に当たります。\n\nIDPを通してチームで共通して利用できるツールやリソースを開発者に提供することで、迅速なソフトウェアの構築やデプロイを実現できます。\n\nIDPの構築においては、自社の課題や目的に応じてさまざまなツールや技術を組み合わせて行いますが、[GitLab](https://about.gitlab.com/ja-jp/)のように単一のプラットフォームで開発プロセスにおける多くの作業を効率化できるサービスもあります。\n\n## 2. プラットフォームエンジニアリングが注目されている背景\n\n![プラットフォームエンジニアリングが注目されている背景](https://res.cloudinary.com/about-gitlab-com/image/upload/v1758508140/hvzgimgumavwq5mmfqlx.jpg)\n\nソフトウェア開発の領域でなぜプラットフォームエンジニアリングが注目されているのでしょうか。具体的な背景としては以下が挙げられます。\n\n* 開発環境の複雑化  \n* ビジネス環境の激化  \n* IT人材の不足\n\n### 2-1. 開発環境の複雑化\n\nプラットフォームエンジニアリングの必要性が高まっている背景の一つとしてまず挙げられるのが、開発環境の複雑化による開発者の認知負荷の増大にあります。\n\nソフトウェア開発における開発手法や技術は年々進化・発展し続けており、クラウドや生成AI、マイクロサービス、APIなどさまざまな技術が広く使われるようになっています。これらの技術活用によって柔軟なソフトウェア開発を実現できますが、その一方で管理すべきツールの種類が増え、かつ多様な技術を身につけなければならないという課題が発生します。\n\nそれにより、開発者は重要な開発作業や取り組み以外に自身のリソースを割く必要があり、それが結果としてチーム全体の生産性低下も招くことになります。\n\nつまり、ソフトウェア開発において効果的に最新技術を取り入れていくためには、開発者が本質的な業務に集中できる環境を構築しなければなりません。\n\n### 2-2. ビジネス環境の激化\n\n先ほども少し触れていますが、近年は[VUCA時代](https://www.nri.com/jp/knowledge/glossary/vuca.html)と呼ばれる将来の予測が難しい不確実な要素が多い時代です。\n\n市場が常に変化する中で社会や消費者にとって必要とされる価値あるソフトウェアを開発して競合と差別化を図るためには、多様な技術を活用したスケーラブルな開発が求められます。\n\nまた、自社の競争力を高めていくためには、アジャイル開発のようなスピード感のある開発手法を積極的に採用していく考えも大切です。\n\n開発者がセルフサービスで利用できるプラットフォームの提供は、柔軟かつ迅速なソフトウェア開発を実現する手段として有効なアプローチだと言えます。\n\n[アジャイル開発とは？意味や進め方、DevSecOpsとの関係性を解説](https://about.gitlab.com/ja-jp/blog/what-is-agile-development/)\n\n### 2-3. IT人材の不足\n\nソフトウェア開発の領域では、慢性的な人手不足が課題となっています。クラウドやAIなど高度な最新技術が次々と登場する一方で、それらを扱える専門知識を持った人材が業界全体で不足しているのです。\n\n実際に「[IT人材需給に関する調査](https://www.meti.go.jp/policy/it_policy/jinzai/houkokusyo.pdf)」を見てみると、2030年には最大で約79万人のIT人材が不足すると予測されています。\n\n![IT人材需給に関する調査](https://res.cloudinary.com/about-gitlab-com/image/upload/v1758508140/zv15e7qpd6cppogiogat.png)\n\n※引用元：[IT人材需給に関する調査](https://www.meti.go.jp/policy/it_policy/jinzai/houkokusyo.pdf)\n\nこのような背景の中で適切にソフトウェア開発を進めていくためには、プラットフォームエンジニアリングの導入を通じて開発者の負担削減や生産性向上を実現し、自社のリソースを上手に活用していく姿勢や工夫が求められると言えます。\n\n## 3. プラットフォームエンジニアリングとDevSecOps・SREとの関係性とは\n\n![プラットフォームエンジニアリングとDevSecOps・SREとの関係性とは](https://res.cloudinary.com/about-gitlab-com/image/upload/v1758508140/psg7uvfabu13r50vbwzc.jpg)\n\nプラットフォームエンジニアリングを理解する上では、DevSecOpsやSREとの違いについても把握しておくことが大切です。\n\n### 3-1. DevSecOpsとの違い\n\nDevSecOpsとは、開発（Dev）、セキュリティ（Sec）、運用（Ops）の3つの領域を連携させて開発を進めるアプローチを指します。開発と運用を連携してリリースサイクルを短縮させる従来の「DevOps」の考え方に対して、セキュリティ（Sec）のプロセスも加えることでソフトウェアの安全性を確保しつつ、迅速なリリースが可能になります。\n\n一方、プラットフォームエンジニアリングはDevSecOpのようなワークフローを実現する上で土台となるプラットフォームを社内で整備する取り組みです。\n\nつまり、プラットフォームエンジニアリングとDevSecOpsは親和性が高く、プラットフォームエンジニアリングはDevSecOpsをサポートする役割を担っていると言えます。\n\n### 3-2. SREとの違い\n\nSREとは、「Site Reliability Engineering」の略語で直訳すると、「サイト信頼性エンジニアリング」になります。Google社によって提唱された概念であり、運用プロセスにおいて手間のかかるタスクを自動化してシステムの安定稼働を実現しつつ、新機能の追加や更新などを通してユーザー体験（UX）の向上を目指す取り組みを指します。\n\nプラットフォームエンジニアリングとSREは、いずれも開発と運用における効率性・信頼性向上に関わるものですが、それぞれ目的や焦点が異なります。\n\nプラットフォームエンジニアリングは、社内の開発者の生産性向上や利便性向上を目的としたアプローチであり、SREは主にシステムの信頼性と可用性、スケーラビリティの向上に焦点を当てた考え方になります。\n\n## 4. プラットフォームエンジニアリングの導入目的とメリット\n\n![プラットフォームエンジニアリングの導入目的とメリット](https://res.cloudinary.com/about-gitlab-com/image/upload/v1758508134/m2jqfbt1sfjpjqh3dbih.jpg)\n\nプラットフォームエンジニアリングの導入目的やメリットは以下の通りです。\n\n* 開発プロセスの効率化  \n* 開発者の生産性向上  \n* プロダクトの品質向上  \n* セキュリティ・ガバナンスの維持と強化  \n* 人材不足の解消  \n* 新しいイノベーションの創出  \n* コスト削減\n\n### 4-1. 開発プロセスの効率化\n\nまずプラットフォームエンジニアリングの導入は、開発プロセスの効率化につなげられます。\n\nIDPにより開発者は開発に必要なリソースを必要な時に素早く取得して利用できるため、環境構築に手間と時間をかけることなく本質的な開発業務に集中することが可能です。\n\nアジャイル開発やDevSecOpsの手法を活用する際に、積極的にプラットフォームエンジニアリングの考え方も採用すれば、プロダクトや機能のリリース頻度・スピードが向上し、自社ビジネスの加速化に貢献できるでしょう。\n\n### 4-2. 開発者の生産性向上\n\nプラットフォームエンジニアリングでIDPを整備することで、チームで再利用可能なツールと機能を開発者に提供できるようになります。この仕組みにより、開発者それぞれで多数のツールを管理・運用する手間がなくなり、認知的負荷の軽減につなげられるでしょう。\n\nその結果、戦略立案や分析、新機能開発などより重要な業務にリソースを割けるようになり、生産性の最大化を図れるでしょう。\n\n### 4-3. プロダクトの品質向上\n\n顧客が満足するプロダクトを提供するためには、品質も担保しなければなりません。IDPに対してテストやレビュー、セキュリティスキャン、デプロイなどを自動化する仕組みを整備すれば、ヒューマンエラーの防止につなげられます。\n\nプラットフォームエンジニアリングの導入でテストやレビューなどを標準化することによって、開発者やプロジェクトごとの品質のバラつきを防止でき、自社で定義されたプラットフォームの基準に沿って開発と運用を進められます。\n\nつまり、プラットフォームエンジニアリングの導入は、開発効率や生産性の向上だけでなく、プロダクト品質や信頼性の向上にも寄与します。\n\n### 4-4. セキュリティ・ガバナンスの維持と強化\n\nプラットフォームエンジニアリングで自社に必要なセキュリティやガバナンスを定義し、それらを自社のプラットフォーム上に反映させて運用することも可能です。\n\n権限設定や監査ログ、セキュリティポリシー、脆弱性対応などをプラットフォーム上で集約して一元化することで管理や証跡の収集が容易になり、組織全体におけるセキュリティ・ガバナンスの維持と強化につなげられるでしょう。\n\nまた、標準化されたプラットフォームの整備によって、開発者の心理的な負担を軽減して安全に開発を進められます。\n\n### 4-5. 人材不足の解消\n\nプラットフォームエンジニアリングの導入は、開発プロセスの効率化や開発者の生産性向上に寄与するため、企業のリソースを最大限に活かしながらソフトウェア開発を進められます。\n\nまた、開発者のニーズにマッチしたプラットフォームを提供して働きやすい環境を構築することで、開発者体験（Developer Experience）の向上も実現できます。その結果、自社に対する開発者や求職者からのイメージも良くなり、優秀なエンジニアの獲得と定着を図れるでしょう。\n\n### 4-6. 新しいイノベーションの創出\n\n近年ソフトウェア開発の効率化や価値向上に役立つさまざまな最新技術が登場しています。しかし、複数の技術やツールを開発者個人で活用するには管理の負担が増えてしまい、実際の活用にはハードルが高いと言えます。\n\nプラットフォームエンジニアリングならさまざまな機能やツールが搭載されたプラットフォームをチームで利用できるため、開発者全員が最新技術に触れやすくなります。それをきっかけとして自社で新しいアイデアやイノベーションが生まれたり、より品質の高いプロダクトをリリースできたりする可能性が高まるでしょう。\n\n### 4-7. コスト削減\n\nプラットフォームエンジニアリングを取り入れることで、ツールや環境の共通化によるコスト削減にもつながります。例えば、ソフトウェア開発のプロセスにおいて複数のツールを活用している企業が、[GitLab](https://about.gitlab.com/ja-jp/)のようなさまざまなツールを単一のプラットフォームで利用できるサービスを導入すれば、ライセンス費用や管理コストの削減につなげられるでしょう。\n\nまた、CI/CDやセキュリティチェックなどをプラットフォーム上で自動化することで運用コストの削減も実現できます。\n\nワークフローの自動化や標準化により開発スピードが向上すれば、限られたリソースを効果的に活用できるため、長期的な人件費の最適化にもつながります。\n\n## 5. プラットフォームエンジニアリングの導入ステップ\n\n![プラットフォームエンジニアリングの導入ステップ](https://res.cloudinary.com/about-gitlab-com/image/upload/v1758508135/cep3gdqsqca4gb0ckt2w.jpg)\n\nここでは実際にプラットフォームエンジニアリングを導入する際の手順について見ていきましょう。\n\n1. 専門チームの組成  \n2. 開発課題の分析と目標設定  \n3. プラットフォームの構築・組織体制の変更  \n4. フィードバック・継続的なメンテナンス\n\n### 5-1. 専門チームの組成\n\nプラットフォームエンジニアリングを導入する際には、まず専門チームの組成から始めます。専門チームを社内に配置すれば、プラットフォームエンジニアリング導入の取り組みを推進できます。専門チームの主な役割としては以下が挙げられます。\n\n* 開発者のニーズ調査  \n* プラットフォームの設計・構築  \n* 社内でのプラットフォーム活用の浸透の実現  \n* プラットフォームの運用・定期的な改善 など\n\n実際のメンバー構成においては、開発者のさまざまなニーズを考慮したプラットフォームを導入するためにも、開発・運用・セキュリティなど多様なスキルセットを持つ人材や、それぞれの分野を専門とする人材を集めることがポイントです。\n\nまた、社内向けではあるものの、自社での活用を浸透させるためにはプラットフォームを一つのサービスとして捉え、ユーザーニーズを満たすという視点が重要になります。\n\n### 5-2. 開発課題の分析と目標設定\n\nプラットフォームエンジニアリングの専門チーム結成後は、現状の開発課題の把握と分析を実施します。課題の把握や分析においては、エンジニアとの個別面談やサーベイなどを通して行います。\n\nその中で、「複数のツールを管理するための負担がかかり過ぎている」「開発環境の構築から実際のリリースまで時間がかかっており、開発効率が悪い」などの課題が挙げられたなら、それらの課題を解決するためにどのようなプラットフォームを導入すれば良いのかを検討し、具体的な目標を設定します。\n\n例えば、開発者のツール管理の負担が主な課題としてあるなら、単一のプラットフォームで複数のツールや技術を活用できるIDPを整備するという方向性を定められるでしょう。\n\n### 5-3. プラットフォームの構築・組織体制の変更\n\nプラットフォームエンジニアリングの導入における目標や方向性が明確になった後は、実際に基盤となるプラットフォームの構築を行います。\n\n開発プロセスの課題解決につながるような機能やツールを搭載し、さまざまな手法で開発を進められるよう整備していきます。\n\nまた、プラットフォームを構築して実際に活用していく際には、これまでの開発プロセスに変化が生じるため、必要に応じて開発者間での認識の擦り合わせや組織体制の変更を行いましょう。\n\n### 5-4. フィードバック・継続的なメンテナンス\n\nプラットフォームエンジニアリングの基盤構築後は、実際にプラットフォームを運用し開発者に活用してもらいます。その中で開発者からフィードバックや要望があれば、機能追加や改善を柔軟に行っていきます。\n\nソフトウェア開発におけるツールや技術は進化し続けており、トレンドも常に移り変わるため、最新情報のキャッチアップや定期的なメンテナンスがプラットフォームエンジニアリングを成功させるための鍵となります。\n\n## 6. プラットフォームエンジニアリングの導入における注意点\n\n![プラットフォームエンジニアリングの導入における注意点](https://res.cloudinary.com/about-gitlab-com/image/upload/v1758508135/ew7szhpm1mnheubghlnk.jpg)\n\nプラットフォームエンジニアリングの導入においては以下のような注意点もあります。\n\n* プラットフォーム構築を目的としない  \n* 導入に効果が期待できるか見極める  \n* トップダウンでの導入は避ける  \n* 段階的に導入して小さく始める\n\n### 6-1. プラットフォーム構築を目的としない\n\nまずプラットフォームエンジニアリングの導入において、プラットフォーム構築そのものを目的として進めてしまうと失敗してしまう可能性が高まります。\n\n例えば、「最新技術だから」「高機能だから」というような考えだけで導入してしまうと、開発者ニーズにマッチしないプラットフォームを構築してしまうことになります。そうなると、社内での活用も浸透せず、誰にも使われないという結果を招いてしまうでしょう。\n\nそのため、開発者への調査を徹底して行い、どんな課題を解決したいのかを明確にした上でプラットフォームを構築する必要があります。\n\n### 6-2. 導入に効果が期待できるか見極める\n\nプラットフォームエンジニアリングの導入そのものが、実際に自社にとって効果が期待できるのかも見極めなければなりません。\n\n例えば、エンタープライズや中規模など大きめ組織で、かつ必要な人材が揃っているなら、専門チームの組成もスムーズに進み、実際のプラットフォーム構築によって開発の効率化やコスト削減などの効果が期待できる可能性が高いと言えます。\n\n一方、小規模な組織の場合で、かつ人手が足りない場合プラットフォーム構築や運用そのものに大きな負担がかかってしまい、逆効果になる可能性もあります。\n\nそのため、「プラットフォームエンジニアリングの導入や運用が自社で可能なのか」「実際にどのような効果が期待できるのか」をきちんと検討することが大切です。\n\n### 6-3. トップダウンでの導入は避ける\n\nプラットフォームエンジニアリングは開発者向けのアプローチであり、開発者がプラットフォームを問題なくセルフサービスで利用できるという要素が重要になります。\n\nそのため、トップダウンで現場の課題や開発者のニーズを無視して導入を進めてしまうと、新しいやり方に対して開発者から抵抗や反発を受ける可能性があります。\n\nスムーズな導入を実現するためには、経営層と開発者で双方向コミュニケーションをとり、開発者に選択の余地とアイデアを積極的に発信できる場を与える必要があります。\n\n### 6-4. 段階的に導入して小さく始める\n\n最初から全ての要件を満たした完璧なプラットフォームを構築して、運用しようとすると開発者が変化に対応しきれない可能性があります。また、時間をかけてプラットフォームを構築しているとトレンドに乗り遅れ、完成後には搭載した技術やツールが既に古いものになってしまっていたというケースも考えられます。\n\nそのため、まずは優先度の高い課題にフォーカスして、効果が期待できる機能から実装し段階的に運用するなど、アジャイル的な進め方がプラットフォームエンジニアリングの導入に求められると言えます。\n\n## 7. プラットフォームエンジニアリングの基盤構築に役立つツール・サービスの選び方\n\n![プラットフォームエンジニアリングの基盤構築に役立つツール・サービスの選び方](https://res.cloudinary.com/about-gitlab-com/image/upload/v1758508136/bdq3zpkcrz1ez00md2yr.jpg)\n\nプラットフォームエンジニアリングの導入においては、基盤構築に役立つサービスを積極的に活用すると効率的です。ここでは具体的な選び方を解説します。\n\n* 機能  \n* コスト  \n* サポート体制\n\n### 7-1. 機能\n\nプラットフォームエンジニアリングの導入を成功させるためには、開発者のニーズを満たし、かつ自社の課題を解決できる機能が搭載されたサービスを選ぶことが大切です。\n\n例えば、プラットフォームを構成する重要な要素として挙げられる機能は以下の通りです。\n\n* CI/CD（自動ビルド・テスト・デプロイ）  \n* ソースコード管理  \n* ドキュメント  \n* モニタリング  \n* API連携  \n* セキュリティ・ガバナンス など\n\nこのような機能が搭載されているサービスなら、開発者の生産性向上に貢献できるでしょう。\n\n### 7-2. コスト\n\nプラットフォームエンジニアリングの基盤構築となるサービスを選定する際には、コスト面も考慮することが大切です。\n\n組織の規模や導入形態などによってもコストが異なるため、ベンダーに問い合わせするなどして費用対効果が期待できるかしっかりチェックしておきましょう。\n\n無料トライアルを設けているサービスも多いため、まずは使用感を試してみてから導入を検討するのも良いでしょう。\n\n### 7-3. サポート体制\n\nプラットフォームエンジニアリングをスムーズに導入・運用していくためには、ツールやサービスを提供するベンダーのサポート体制をチェックしておく必要もあります。\n\n充実したサポート体制があれば、万が一トラブルや不明点が発生した場合でも、専任スタッフが迅速に対応してくれるでしょう。また、ベンダーがドキュメントやマニュアルなどを通して積極的にノウハウを公開していれば、トラブル時にも自社で解決しやすくなるでしょう。\n\n## 8. プラットフォームエンジニアリングの基盤構築なら「GitLab」\n\n![プラットフォームエンジニアリングの基盤構築なら「GitLab」](https://res.cloudinary.com/about-gitlab-com/image/upload/v1758508135/hy8mmygwnbm0ws0ejtik.png)\n\nプラットフォームエンジニアリングの基盤構築をスムーズに実現するなら「[GitLab](https://about.gitlab.com/ja-jp/)」の活用がおすすめです。ここでは、GitLabのサービス概要や強みについて紹介します。\n\n### 8-1. GitLabとは\n\nGitLabは、DevSecOpsワークフローを支援するAIを搭載したプラットフォームです。AIによるソースコード管理やセキュリティ対策、CI/CD、コンプライアンス管理など豊富な機能を単一のプラットフォームで活用でき、プラットフォームエンジニアリングの基盤構築に役立てられます。\n\n中小企業からエンタープライズまで多くの企業で導入されているプラットフォームで、高品質かつ迅速なソフトウェア開発を実現できます。\n\n### 8-2. GitLabが選ばれる理由\n\nGitLabの強みは、DevSecOpsツールチェーンの構築を単一のプラットフォームで実現できることです。これまで複数のツールを管理していた企業がGitLabを導入すれば、コスト削減や開発者の認知負荷の軽減につなげられ、プラットフォームエンジニアリングの運用をスムーズに行えるようになります。\n\nチーム全員で単一のプラットフォームを通して作業することで、メンバー間の連携や情報共有も容易に実施できます。また、サポート体制も充実しているため、導入と運用においても安心して進められるのも強みの一つです。\n\nGitLabを通してプラットフォームエンジニアリングを実現すれば、ソフトウェア開発のライフサイクル全体を効率化でき、競合との差別化につながる機能開発など本質的な作業に集中できるようになるでしょう。\n\n## 9. GitLabによるプラットフォームエンジニアリング実現のアプローチと活用例\n\n![GitLabによるプラットフォームエンジニアリング実現のアプローチと活用例](https://res.cloudinary.com/about-gitlab-com/image/upload/v1758508136/gn4zixnirbsgrk1anwi8.jpg)\n\n実際にGitLabによるプラットフォームエンジニアリング実現のアプローチと活用例を紹介します。\n\n* 再利用可能なCI/CDコンポーネント  \n* セキュリティとコンプライアンス  \n* データ活用と分析  \n* コミュニケーションの効率化\n\n### 9-1. 再利用可能なCI/CDコンポーネント\n\nCI/CDコンポーネントは、再利用可能な単一のパイプライン構成ユニットのことで、この機能を使用すればCI/CDパイプラインの設定が容易になります。\n\nまた、再利用可能なCI/CDコンポーネントをリスト化して、各コンポーネントの情報を確認できる「[CI/CDカタログ](https://gitlab.com/explore/catalog)」も提供しています。コンポーネントが一元管理されているため、必要なものを必要な時に見つけ出して再利用できる仕様となっています。\n\nこれにより、開発者の作業効率向上や、組織全体でのスムーズなナレッジ共有を実現できるでしょう。\n\nCI/CDコンポーネントの詳細については以下のページをご覧下さい。\n\n[GitLab入門：CI/CDについて理解する](https://about.gitlab.com/ja-jp/blog/getting-started-with-gitlab-understanding-ci-cd/)\n\n### 9-2. セキュリティとコンプライアンス\n\nGitLabでは、ソフトウェア開発ライフサイクルの全てのステージに対応したセキュリティやコンプライアンス機能を搭載しています。\n\n開発を進める中で、セキュリティリスクなどの問題を早期に発見して対応できるため、トラブル発生時の対応コストを抑えたり、事態の深刻化を未然に防止したりすることが可能です。\n\n### 9-3. データ活用と分析\n\nGitLabでは、データ活用と分析による開発の効率性向上も実現できます。プロジェクトの運用状況などソフトウェア開発ライフサイクルにおけるさまざまなデータが一元管理されている仕組みとなっているため、関係者全員がスムーズに必要な情報にアクセスできます。\n\nまた、 プラットフォームに蓄積された主要なメトリクスを追跡して問題点を詳細に分析することで、迅速な改善や顧客価値の向上につなげられます。GitLabでは、DevOpsのパフォーマンスや健全性を示す[DORAメトリクス](https://docs.gitlab.com/user/analytics/dora_metrics/)の可視化・分析機能などを提供しています。\n\n### 9-4. コミュニケーションの効率化\n\nGitLabは統合型プラットフォームであり、全員が同じツールにアクセスして利用できるようになるため、開発者間でのコミュニケーションが効率化されます。\n\n誰もがアクセスしやすい共同ドキュメントの作成も可能であるため、別のツールに切り替えて作業する必要がなく、情報の共有や整理が容易になります。\n\nなお、プラットフォームエンジニアリングにおけるGitLab活用の詳細については以下のページをご覧下さい。\n\n> [プラットフォームエンジニアリングにおけるGitLabの活用](https://about.gitlab.com/ja-jp/solutions/platform-engineering/)\n\n[](https://about.gitlab.com/ja-jp/solutions/platform-engineering/)\n\n## まとめ： プラットフォームエンジニアリングの実現により開発品質の向上と効率化を図ろう\n\nプラットフォームエンジニアリングの導入は、ビジネス環境が激化している時代において重要視されているアプローチです。実際の導入においては、適切な専門チームの組成やツール・サービスの選定が大切なポイントとなってきます。\n\nプラットフォームエンジニアリングの基盤構築なら、ぜひ[GitLab](https://about.gitlab.com/ja-jp/)をご活用下さい。GitLabなら単一のプラットフォームで豊富な機能を利用できるため、開発者の認知負荷を軽減し、迅速かつ品質の高いソフトウェア開発を実現できます。\n\nなお、GitLabでは世界39か国、5,000人を超えるDevSecOps専門家のインサイトが詰まった完全版レポートを無料で公開しているので、ぜひこちらもご覧下さい。\n\n> [2024グローバルDevSecOpsレポートはこちら](https://about.gitlab.com/ja-jp/developer-survey/?utm_medium=blog&utm_source=blog&utm_campaign=eg_apac_brand_x_x_ja_gitlabjapanblogseo_what-is-platform-engineering)\n\n*監修：川瀬 洋平 [@ykawase](https://gitlab.com/ykawase)*\n\n*（GitLab合同会社 カスタマーサクセス本部 シニアカスタマーサクセスマネージャー）*","2025-09-22",[673],"GitLab Team","この記事では、プラットフォームエンジニアリングの意味や特徴、導入メリットなどを解説します。",[111,676,677,678,679,680,681,682],"collaboration","DevOps","DevSecOps","features","performance","tutorial","workflow",{"featured":6,"template":684,"slug":685},"BlogPost","what-is-platform-engineering","content:ja-jp:blog:what-is-platform-engineering.yml","What Is Platform Engineering","ja-jp/blog/what-is-platform-engineering.yml","ja-jp/blog/what-is-platform-engineering",[691,710,730,749,769,795,819,839,859,878,902,922,945,965,987,1009,1033,1054,1074,1097],{"_path":692,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":693,"content":698,"config":704,"_id":706,"_type":16,"title":707,"_source":18,"_file":708,"_stem":709,"_extension":21},"/ja-jp/blog/what-is-gantt-chart",{"config":694,"ogImage":695,"title":696,"description":697},{"noIndex":6},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1757988342/gqogwxai28zzwwuj2z3i.jpg","ガントチャートとは？ソフト開発における役割やメリット、作り方","ガントチャートとは何か、作り方やメリットを詳しく解説。プロジェクト管理に役立つおすすめツールも紹介します。",{"heroImage":695,"date":699,"authors":700,"category":14,"body":701,"tags":702,"title":703,"description":697},"2025-09-16",[673],"ソフトウェア開発におけるプロジェクト管理を円滑に行うには「ガントチャート」の活用が役立ちます。実際に自社の開発プロジェクトにおいて複雑で多岐にわたるプロセス管理に課題を感じており、ガントチャートの活用を検討している人もいるのではないでしょうか。\nこの記事では、ガントチャートの役割や活用のメリット、具体的な作成方法などを解説します。ガントチャートの作成やプロジェクト管理におすすめのツールも紹介しているのでぜひ参考にして下さい。\n\n## 1. ガントチャートとは？意味やその役割\n\n![ガントチャートとは？意味やその役割](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757988290/sjxtqobutpz8gwszlfaw.jpg)\n\nまずはガントチャートの意味や役割など基礎知識について解説します。\n\n### 1-1. ガントチャートの定義・意味\n\nガントチャート（Gantt Chart）とは、プロジェクトのスケジュール管理やタスク管理のために活用されるツールです。縦軸に各タスクと作業の開始日・終了日を示し、横軸に進捗を示す時間軸を配置することでプロジェクトの進捗状況やタスク間の依存関係、担当者を一目で把握できます。\nガントチャートはIT業界だけでなく、建設業などさまざまな業種・業界のプロジェクト管理に活用されています。\n\n### 1-2. ソフトウェア開発におけるガントチャートの役割\n\nソフトウェア開発では、要件定義からプログラミング、テスト、リリース、保守運用まで多岐にわたる工程を踏む必要があり、複数の人材や関係者がプロジェクトに参加します。\nその中でメンバーや関係者間の認識のズレを防止しつつ、プロジェクトを円滑に進めるにはガントチャートによる徹底したスケジュール管理とタスク管理が重要です。\nガントチャートはソフトウェア開発において、メンバー間のコミュニケーションの向上や適切な進捗管理の実現、リカバリー策の設計などの役割を担います。\n\n## 2. ガントチャートの歴史・誕生背景\n\n![ガントチャートの歴史・誕生背景](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757988299/y4ewrmhuneplgjp1lbcg.jpg)\n\nガントチャートは、1896年にポーランドの経済学者であるKarol Adamiecki（カロル・アダミエツキ）氏によって最初に作成されたと言われています。\nその後、1910年代にHenry Gantt（ヘンリー・ガント）氏が独自のバージョンとしてガントチャートを考案しました。Henry Gantt氏は、工場で働く労働者が与えられたタスクを完了させるのにどのくらいの期間を要したかを現場の責任者が確認できるよう独自にガントチャートを考案したのです。\nさらに、Henry Gantt氏の死後、Wallace Clark（ウォーレス・クラーク）氏が、自身の著書でガントチャートの使い方やそのメリットを解説し、世界中に普及しました。\n\n## 3. ガントチャートの一般的な構成要素\n\nガントチャートを作成・活用する際には、構成要素について理解しておく必要があります。\n| 構成要素 | 詳細 |\n| :---- | :---- |\n| タスク | プロジェクトにおける各作業 |\n| タスクの期間 | 各作業の実施期間（開始日と終了日） |\n| タスクの担当者 | 各タスクの担当者の名前 |\n| タスクの依存関係 | タスク同士がどのような影響を与えるか |\n| タイムスケール | チャートの上部に示す時間軸（日・週など） |\n| マイルストーン | プロジェクトの重要な中間目標や節目 |\n| 進捗率 | タスクの完了率（%で表示） |\n一般的には上記のような要素で構成されますが、自社のプロジェクトの規模や内容によっても記載する要素は異なります。\n\n## 4. ガントチャートとWBS・バーチャート工程表との違い\n\n![ガントチャートとWBS・バーチャート工程表との違い](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757988296/ymdhirenqdz60ohwb1ys.jpg)\n\nガントチャートと混同されやすい用語として「WBS」と「バーチャート工程表」があります。それぞれの違いについて詳しく解説します。\n\n### 4-1. ガントチャートとWBSとの違い\n\nWBSとは、「Work Breakdown Structure」の略語でプロジェクト全体の作業を段階的に細分化したリストのことです。「プロジェクトを達成するためには何をすべきか？」という点にフォーカスし、必要なタスクを整理するのが目的です。\n一方、ガントチャートは時間軸を活用してWBSで整理されたタスクの進捗状況の把握や全体のスケジュール管理を行うための表を指します。つまり、ガントチャートを作成する際にはWBSによるタスクの細分化が不可欠であり、両者は密接な関係にあります。\n\n### 4-2. ガントチャートとバーチャート工程表との違い\n\nバーチャート工程表とは、縦軸に作業項目、横軸に時間を示して、横棒（バー）を使って作業の実施時間を可視化した図表を指し、主に建設現場や製造業で使われています。\nバーチャート工程表は、各タスクに要する実施期間を明確にすることを目的としていますが、ガントチャートのようにタスク間の依存関係を管理するのには向いていないツールです。\nソフトウェア開発においては各タスクの依存関係や進捗状況の把握が重要になってくるため、バーチャート工程表ではなくガントチャートの活用を検討することが大切です。\n\n## 5. ガントチャートを活用するメリット\n\n![ガントチャートを活用するメリット](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757988290/cjpufbck1bqaqizhiotv.jpg)\n\nガントチャートを活用することでどのようなメリットがあるのでしょうか。具体的には以下が挙げられます。\n\n* プロジェクトの全体像を把握できる  \n* 専門知識がなくても扱える  \n* 関係者間の認識のズレを防止できる  \n* マイルストーンを管理・最適化が可能になる  \n* タスクの依存関係を確認できる  \n* プロジェクトにおけるリカバリー策を取りやすい\n\n### 5-1. プロジェクトの全体像を把握できる\n\nガントチャートを活用すれば、関係者全員がプロジェクト全体の計画を直感的に把握できます。マネージャーや責任者だけでなく、メンバー1人ひとりがプロジェクト計画や進捗状況を確認できるため、個々が担当するタスクに対して責任を持って作業に取り組むことが可能です。例えば、「自分が担当しているタスクが完了しなければ、次のタスクに移れない」とタスク同士の依存関係を事前に把握していれば、計画を意識しながら作業を進められるでしょう。\nプロジェクトマネージャーも、ガントチャートを見ながらプロジェクトが計画的に進んでいるか常に状況をチェックできるため、メンバーへの指示も出しやすくなるでしょう。\n\n### 5-2. 専門知識がなくても扱える\n\nガントチャートは図表の構成そのものがシンプルであり、難解な用語も使用しないためメンバーや関係者に専門知識がなくても直感的に理解できます。プロジェクトマネージャーがガントチャートを作成する際にも専門知識は不要であり、専用ツールを活用すれば時間と手間をかけることなくスムーズな作成・修正が可能です。\n誰もが見やすくわかりやすいガントチャートを作成すれば、開発メンバーも戸惑うことなく作業に集中できるようになるでしょう。\n\n### 5-3. 関係者間の認識のズレを防止できる\n\nガントチャートで全体のプロジェクト計画をメンバーや関係者間で共有すれば、認識のズレなく全員が同じ方向を向いて開発を進められます。\n例えば、開発側と顧客側で認識のズレがあると、本来必要のない機能の開発のために工数を割いてしまうということにもなりかねません。ガントチャートなら、必要なタスクを細分化してスケジュールとして可視化できるようになっているため、関係者全員が事前に擦り合わせした上で計画を実行することが可能です。\nまた、開発途中でなんらかの課題や変更が発生した場合でも随時状況を共有し、スケジュールを修正すれば問題なくプロジェクトを進められるでしょう。\n\n### 5-4. マイルストーンの管理・最適化が可能になる\n\nマイルストーンとは、プロジェクトにおける重要な中間目標地点を指す言葉です。全体のスケジュールを可視化できるガントチャートなら、プロジェクト計画において重要な要素となるマイルストーンの管理も行うことができます。\n例えば、ガントチャート上にマイルストーンを設置すれば、「この期間までにはこのタスクを完了している必要がある」と視覚的に把握できるため、メンバー間での認識の強化やプロジェクトの遅延防止につなげられるでしょう。\n\n### 5-5. タスクの依存関係を確認できる\n\nソフトウェア開発を進めるに当たり、タスクによっては前のタスクが完了していないと着手できないといった依存関係が発生するケースも少なくありません。\nガントチャートを作成する際に各タスクにおける依存関係をマッピングすれば、容易にタスク同士の関係性を把握でき、ボトルネックの可能性を事前に認識することが可能です。例えば、タスクの依存関係が集中するフェーズでは、他の担当者がフォローできる体制を整えておくなどの対策を検討できるでしょう。\nなお、ガントチャートで各タスクの依存関係を示す際には必要な機能が搭載されたツールを活用すると効率的です。\n\n### 5-6. プロジェクトにおけるリカバリー策を取りやすい\n\nソフトウェア開発においては必ず計画通りプロジェクトが進むというわけではなく、途中トラブルなどが発生するケースも多いです。\nガントチャートで全体のスケジュールやタスクを可視化しておけば、急なトラブルや仕様変更などが発生した場合でも、どのフェーズまで戻り、どのような作業が必要になるのか検討しやすくなります。このように迅速なリカバリー策を講じることで、顧客の要望に沿った開発を実現できるでしょう。\nなお、計画に変更が生じた場合はガントチャートの修正も忘れずに行うことが大切です。\n\n## 6. ガントチャートの注意点\n\n![ガントチャートの注意点](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757988298/gzdswdhfx3mnedmvxv2v.jpg)\n\nガントチャートは、プロジェクト全体のスケジュールや各タスクの実施期間、進捗状況などを視覚的に確認できますが、作業工数における細かな情報については表示しないのが特徴です。例えば、「タスクAの実施期間は10日間」と表示されている場合でも、タスクAを完了させるために必要な細かな工数が見えないため、想定以上のコストがかかる場合があります。\nこのような事態を避けてプロジェクトを円滑に進めるためには、ガントチャートの活用と併せて工数管理表などのツールを導入し、別途で工数を管理する方法を検討することが大切です。\n\n## 7. ガントチャートの作り方\n\n![ガントチャートの作り方](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757988291/j4iylagxbsfajpa3s6uw.jpg)\n\nここではガントチャートの作り方について解説していきます。\n\n### 7-1. WBSを作成する\n\nガントチャートを作成する際には、まずWBSを作成してプロジェクトに必要なタスクを洗い出していきます。\nWBSでタスクを細分化することによって、作業内容が明確になり全体のスケジュール管理がしやすくなります。WBS作成の土台となるのはプロジェクトの目標設定です。開発における最終成果物や成功の定義が明確であるほど、ゴールまでのプロセスを丁寧に考えることができます。必要なタスクの洗い出しにおいては、まずは大きなフェーズから書き出し、そこからさらに細分化していくというステップを踏むのがポイントです。そうすることで次で紹介するタスクの依存関係の整理がスムーズになります。\n\n### 7-2.タスク間の依存関係を整理する\n\nプロジェクト達成に必要なタスクを洗い出した後は、各タスクの依存関係を整理します。「タスクAの作業が完了しなければ、タスクBに進めない」という依存関係がある場合は、視覚化して整理しておくことが大切です。\n例えば、開発において設計が完了しないと次のプログラミングに着手できないというケースは依存関係に該当するため、関係性をきちんと整理しておきます。\n\n### 7-3.各タスクのスケジュールを設定する\n\n次に各タスクに費やす作業期間を検討し、開始日と終了日を設定します。タスクの作業期間はプロジェクトの規模やタスクの内容に応じて、日数や週数の単位で検討します。その際、タイトなスケジュールを組んでしまうとメンバーの負担増加や、プロダクトの品質低下を招く原因にもなるため、余裕を持たせた上で各タスクの作業期間を設定することが大切です。\nまた、タスク間で依存関係が発生するフェーズにおいては遅延の可能性も考慮しなければなりません。\n併せてマイルストーンの設定も行っておきます。プロジェクトの中間目標を認識した上でスケジュールを検討することで、各タスクにおいて適切な作業期間を設定できるでしょう。\n\n### 7-4.各タスクの担当者を割り当てする\n\n各タスクのスケジュール設定が完了した後は、担当者を割り振っていきます。担当者の選定においては、個人のスキルや経験などを考慮しながら行います。各タスクの割り振りを誤ってしまうと、プロジェクトの遅延やトラブルを招くため、プロジェクトマネージャーはメンバーの能力をよく理解した上で検討しなければなりません。\n各タスクの担当者が決定したらガントチャート上に担当者の名前を記載しておきます。そうすることで誰がどのタスクを担当するのかをメンバー全員が把握できるため、個々が自身のタスクにおいて責任感を持てるようになります。\n\n### 7-5.関係者への共有と更新\n\nガントチャートの作成が完了すれば、メンバーや顧客など関係者全員に共有します。その中で関係者からタスクの洗い出しや作業期間において指摘やフィードバックがあった場合は、修正を実施します。関係者全員で共通の認識がなく、懸念点を抱えたままプロジェクトがスタートしてしまうとスムーズに作業が進まないため、時間をかけて細かな擦り合わせをしておきましょう。\nまた、プロジェクト開始後にも定期的なミーティングを実施し、進捗状況や認識のズレがないかを確認します。繰り返しにはなりますが、仕様変更やトラブルの発生などによって計画が変更された場合は、ガントチャートの修正も忘れずに行うことが大切です。\n\n## 8. ガントチャートを作成する際のポイント\n\n![ガントチャートを作成する際のポイント](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757988290/uz6tvvkkuepoghl2zo2k.jpg)\n\nガントチャートを作成する際には以下のポイントを意識することが大切です。\n\n* 視認性の高さを意識する  \n* 更新されることを前提に作成する\n\n### 8-1. 視認性の高さを意識する\n\nガントチャートはプロジェクトの関係者全員に共有するツールであるため、誰もが見やすい形で作成することが大切です。例えば、以下のような工夫が考えられます。\n\n* タスクの作業期間を示す横棒（バー）は、タスクのカテゴリ別に色分けする  \n* タスクの依存関係によりボトルネックが発生しそうなフェーズにはマークをつけておく  \n* マイルストーンにはわかりやすいアイコンを配置しておく など\n  視認性の高いガントチャートを作成するには、直感的なUIやレイアウト機能を備えた専用ツールを活用するのがおすすめです。\n\n### 8-2. 更新されることを前提に作成する\n\nガントチャートは事前に立てた計画通りに進行されるのが理想ですが、実際にはプロジェクトが開始されると仕様変更やトラブルが発生するケースも少なくありません。\nそのため、ガントチャートは「計画通りに進行させる」という前提ではなく、「更新されること」を前提として作成し柔軟性を持たせておく必要があります。例えば、バッファを含めて各タスクの作業期間を設定する、遅延が想定されるタスクにおいては別の担当者がフォローできるよう割り振りを工夫するなどの方法が挙げられます。\nプロジェクトの変更が発生した際に、同時に計画の変更もスムーズに行える体制を整えておくことで問題なく目標達成できるでしょう。\n\n## 9. ガントチャートと各開発手法との相性・使い方\n\n![ガントチャートと各開発手法との相性・使い方](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757988297/gyoodojgd9rfatopq20e.jpg)\n\nソフトウェア開発においては、近年開発手法も変化してきているためガントチャートと各開発手法との相性も把握しておくことも大切です。\nソフトウェア開発の手法においてはこれまで「ウォーターフォール開発」が主流でした。ウォーターフォール開発は開発前に全ての機能計画を立ててから計画通りに作業を進める手法であるため、プロジェクト全体のスケジュール管理やタスク管理ができるガントチャートとの相性は良いと言えるでしょう。\nなお、近年変化が激化しているビジネス環境において、迅速に顧客や市場ニーズに対応するために「アジャイル開発」にも注目が集まっています。アジャイル開発はウォーターフォール開発のように全体のスケジュールを立ててから開発を進めるのではなく、機能単位ごとに実装とテストを繰り返し開発を進めていきます。そのため、アジャイル開発においてはガントチャートによるスケジュール管理は不向きだと捉えてしまうかもしれません。\nしかし、ガントチャートが持つ計画性はアジャイル開発にも工夫次第で組み合わせることも可能です。例えば、スプリントプラニングにガントチャートを取り入れれば、視覚的に各タスクの作業期間や依存関係を表現できます。\n\n## 10. ガントチャートを作成できるツール・サービス\n\n![ガントチャートを作成できるツール・サービス](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757988291/fzynvxnilg3s0o3k9rf0.jpg)\n\nガントチャートを作成できるツール・サービスは以下の通りです。\n\n* エクセル・スプレッドシート  \n* プロジェクト管理ツール\n\n### 10-1. エクセル・スプレッドシート\n\nガントチャートは、エクセルやGoogleスプレッドシートを活用して自作で作成することが可能です。\nエクセルなら一般的にビジネスシーンで利用されることが多いツールであるため、操作に慣れている人であれば使いやすいでしょう。Googleスプレッドシートも、Googleアカウントを持っていれば手軽に利用できるツールです。\nただし、エクセルやGoogleスプレッドシートを活用してガントチャートを作成する場合は、さまざまな課題が発生するため後に詳しく解説します。\n\n### 10-2. プロジェクト管理ツール\n\nガントチャートを作成する方法としてプロジェクト管理ツールを活用する方法もあります。プロジェクト管理ツールは、複数のタスクやプロジェクトを管理でき、ガントチャートの作成も可能です。\nプロジェクト管理ツールなら、マイルストーン機能や依存関係の設定などさまざまな機能が搭載されており、ガントチャート作成における面倒な設定やレイアウト作成も不要です。ツール導入に当たりコストは発生しますが、プロジェクト管理における包括的なサポートを受けられるというメリットを考えると、高い費用対効果が期待できると言えるでしょう。\n\n## 11. エクセルなど自作でガントチャートを作成することの課題\n\n![エクセルなど自作でガントチャートを作成することの課題](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757988291/njhjqwrqpccvuk0cocq1.jpg)\n\nここでは、先ほど紹介したエクセルやGoogleスプレッドシートを活用して自作で作成することの課題について解説します。\n\n* 作成や更新に時間がかかる  \n* 視認性が低い  \n* スケジュール共有に時間がかかる\n\n### 11-1. 作成や更新に時間がかかる\n\nエクセルやGoogleスプレッドシートでガントチャートを自作する場合、作成や更新に時間がかかってしまいます。作成においてはテンプレートを利用する方法もありますが、自社のプロジェクトに沿ってカスタマイズしたい場合は操作に慣れている必要があり、ある程度関数や条件付き書式などの知識も求められます。\nまた、スケジュールの変更が発生する度に手作業で更新しなければならないため時間と手間がかかり、誤操作や更新漏れも発生しやすいと言えるでしょう。\n特に、プロジェクトの規模が大きいほど更新や修正における負担が増し、重要な業務に注力できなくなる恐れがあります。\n\n### 11-2. 視認性が低い\n\nエクセルやGoogleスプレッドシートでガントチャートのレイアウト作成や調整を行う場合、視認性が低くなってしまう恐れがあります。例えば、見た目を調整しようと必要のない項目を増やしたり、無駄な色使いなどを行うとガントチャートの情報量が多くなりかえって見づらくなってしまうでしょう。\nガントチャートは一目で全体の計画や進捗状況が把握できるかというポイントが重要になってくるため、慣れていないとエクセルやGoogleスプレッドシートで表現するのが難しい可能性があります。特に大規模なプロジェクトの場合は自作で視認性の高いガントチャートを作成するのに適していないと言えるでしょう。\n\n### 11-3. スケジュール共有に時間がかかる\n\nエクセルやGoogleスプレッドシートの場合、リアルタイムでの情報共有が難しくなります。特にエクセルの場合、更新の度にクラウドサービスなど別の媒体を使って共有する必要があり手間がかかります。また、その際誤操作によってファイルが破損してしまう可能性もあるでしょう。\nこのような形で情報共有がスピーディーかつ、正確に行われないと関係者間で認識のズレが生じてしまい、プロジェクトが円滑に進まなくなる恐れがあります。情報共有の正確性や迅速化を目指すなら専用のプロジェクト管理ツールの導入を検討するのが良いでしょう。\n\n## 12. ガントチャートの作成・プロジェクト管理なら「GitLab」\n\n![ガントチャートの作成・プロジェクト管理なら「GitLab」](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757988295/ldz4szcwrxwnpfl0bfnk.png)\n\nガントチャートの作成やプロジェクト管理を効率化するなら「[GitLab](https://about.gitlab.com/ja-jp/)」の導入がおすすめです。ここでは、GitLabの概要やプロジェクト管理機能の特徴について紹介します。\n\n### 12-1. GitLabとは\n\nGitLabは、AIを搭載したDevSecOpsプラットフォームです。AIによるソースコード管理やCI/CDによる開発プロセスの自動化、プロジェクト管理、セキュリティ強化など企業のソフトウェア開発を支援するさまざまな機能を提供しています。\nDevSecOpsとは、ソフトウェア開発における開発・セキュリティ・運用を掛け合わせたアプローチを指し、開発サイクル全体を効率化できるGitLabなら単一のプラットフォームでDevSecOpsを実現できます。GitLabは中小企業からエンタープライズまで世界中の多くの企業で導入されているプラットフォームです。\n\n### 12-2. GitLabのプロジェクト管理機能の特徴\n\n[GitLabのプロジェクト管理](https://about.gitlab.com/ja-jp/blog/getting-started-with-gitlab-mastering-project-management/)にはさまざまな機能が搭載されています。例えば、「ロードマップ」ならエピック（プロジェクトの大枠や目標）とマイルストーンをタイムライン形式（ガントチャート風）で視覚的に表示することが可能です。また、イシュー（タスク）の間に依存関係を設定することもできるため、事前に潜在的な障害を回避できます。\nその他にもアジャイル開発のプランニングに役立つ「イテレーション」や作業時間を測定できる「タイムトラッキング」などの機能があり、GitLabを導入することで自社のプロジェクト管理を円滑に進められます。\n\n## 13. ガントチャートを作成してプロジェクトを円滑に進めよう\n\nガントチャートを自社のソフトウェア開発に積極的に取り入れることで、全体のスケジュール管理やタスク管理がスムーズになり、プロジェクトの成功率を高められるでしょう。ガントチャートの作成はエクセルなどを利用して自作することも可能ですが、時間と手間がかかるためプロジェクト管理ツールを導入するのがおすすめです。\n[GitLab](https://about.gitlab.com/ja-jp/)なら、ソフトウェア開発におけるプロジェクト管理を効率化できる豊富な機能を揃えています。ガントチャートを作成して自社のプロジェクト管理を円滑に行いたいと考えている人は、ぜひ導入をご検討下さい。\nなお、[GitLab](https://about.gitlab.com/ja-jp/)では世界39か国、5,000人を超えるDevSecOps専門家のインサイトが詰まった完全版レポートを無料で公開しているので、ぜひこちらもご覧ください。\n\n\n[2024グローバルDevSecOpsレポートはこちら](https://about.gitlab.com/ja-jp/developer-survey/?utm_medium=blog&utm_source=blog&utm_campaign=eg_apac_brand_x_x_ja_gitlabjapanblogseo_what-is-gantt-chart)",[676,681,682,679],"ガントチャートとは？ソフトウェア開発における役割やメリット、作り方",{"featured":6,"template":684,"slug":705},"what-is-gantt-chart","content:ja-jp:blog:what-is-gantt-chart.yml","What Is Gantt Chart","ja-jp/blog/what-is-gantt-chart.yml","ja-jp/blog/what-is-gantt-chart",{"_path":711,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":712,"content":717,"config":724,"_id":726,"_type":16,"title":727,"_source":18,"_file":728,"_stem":729,"_extension":21},"/ja-jp/blog/what-is-local-llm",{"config":713,"title":714,"description":715,"ogImage":716},{"noIndex":6},"ローカルLLMとは？開発での活用メリットと注意点","ローカルLLMの意味やクラウドLLMとの違い、ソフトウェア開発における導入メリットなどを解説します。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1757577836/qjcz9aubvivrn4zy1kqr.jpg",{"title":714,"description":715,"authors":718,"heroImage":716,"date":719,"body":720,"category":14,"tags":721},[673],"2025-09-12","近年ソフトウェア開発の領域では、開発プロセスの効率化や生産性向上などを目的としてAIの活用が重要視されています。その中で企業のセキュリティ要件に対応しやすい「ローカルLLM」にも注目が集まっています。\n\n実際にソフトウェア開発におけるAI活用において、ローカルLLMの導入を検討している人も多いのではないでしょうか。\n\nこの記事では、ローカルLLMの意味やクラウドLLMとの違い、ソフトウェア開発における導入メリットなどを解説します。\n\n## 1 そもそもLLM（大規模言語モデル）とは？\n\n![そもそもLLM（大規模言語モデル）とは？](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757577783/xdlztojxzueezzp0nnhh.jpg)\n\nローカルLLMについて触れる前にまずはLLM（大規模言語モデル）について理解しておきましょう。LLMとは、膨大なデータを学習し、人間のような自然な言語を使って文章の生成や理解ができる自然言語処理に特化した生成AIの一種です。後にも詳しく解説しますが、ソフトウェア開発の領域ではコードのレビューやドキュメント作成などに役立てられます。\n\nなお、LLMのような自然言語処理ができる言語モデルには「SLM（小規模言語モデル）」もあり、さらにLLMについて触れるなら「RAG（検索拡張生成）」についても理解しておく必要があります。以下でそれぞれの特徴やLLMとの違いについて解説します。\n\n### 1-1 SLM（小規模言語モデル）との違い\n\nSLMは、LLMと同じく自然言語処理が可能なAIモデルですが、「小規模言語モデル」という名前が示すようにLLMよりも小規模で軽量な言語モデルを指します。金融や医療、保険など特定の分野で活用されることが多く、軽量な処理のためリソース要件に制約がある環境でも利用しやすいです。\n\nLLMとSLMの違いを表でまとめると以下の通りです。\n\n|           | LLM（大規模言語モデル） | SLM（小規模言語モデル） |\n| --------- | ------------- | ------------- |\n| 規模（パラメータ） | 数百億〜数兆        | 数億〜数十億        |\n| 学習データ     | 幅広いタスクに対応     | 特定のタスクに特化     |\n| 必要リソース    | 高性能GPUなどが必要   | 軽量            |\n| 開発コスト     | 高い            | 低い            |\n| 処理速度      | 遅い            | 高速            |\n\n### 1-2 RAG（検索拡張生成）との違い\n\nRAGとは、「Retrieval-Augmented Generation」の略語であり、LLMの能力や回答精度を向上させるための技術を指します。具体的には、LLMと外部のデータベースを連携し、データベースから検索した情報を付加させる形で精度の高い回答を実現する手法です。\n\nLLMの場合は、学習された既存のデータだけを利用して文章を生成するため、適切な回答を得られない可能性があります。また、学習データが古くなると最新の情報が反映されないため、情報の正確性や信頼性に劣るケースも見られます。\n\nそこでRAGも活用すれば外部データと連携して回答を行えるようになるため、最新情報や必要な情報を反映させた正確かつ信頼性の高いアウトプットを得られます。つまり、RAGはLLM活用を後押しするような技術として位置付けられるでしょう。\n\n## 2 ローカルLLMとは？クラウドLLMとの違い\n\n![2 ローカルLLMとは？クラウドLLMとの違い](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757577786/im83n2lheoasu6d1jix4.jpg)\n\nではここからはローカルLLMについて、クラウドLLMとの違いも踏まえながら解説していきます。\n\n### 2-1 ローカルLLMとは？\n\nローカルLLMとは、自社サーバーやユーザー個人のPC上などオンプレミス（ローカル）環境で動作する大規模言語モデルを指します。\n\nインターネット接続を必要としないのが大きな特徴で、機密情報を外部に送信することなくAIを活用できるため、企業のセキュリティ要件に対応しやすいです。また、オフライン環境で処理が完結することから、通信障害やネットワーク遅延などの影響を受けにくく、運用におけるリスクを軽減できます。\n\nさらに、ローカルLLMではモデルの再学習・微調整（ファインチューニング）も可能です。そのため、目的に応じて特定の業界やデータに特化させたモデルを構築できるなどカスタマイズ性が高いことも特徴の一つです。\n\n### 2-2 クラウドLLMとの違い\n\nクラウドLLMは、インターネットを介してベンダーのクラウドサーバー上で動作する大規模言語モデルを指します。ローカルLLMとは異なり、大前提として活用においてはインターネット接続が必須となります。\n\nクラウドであることから導入における初期費用を抑えられ、かつ高いスケーラビリティを持つものの、入力データは外部のサーバーに送信されるため、セキュリティが重視される業界やシーンにおいては懸念があると言えます。\n\nまた、ローカルLLMよりもカスタマイズ性は劣り、ベンダーのサービス範囲内となるため、自由度は高くはありません。\n\n## 3 ローカルLLMとクラウドLLMの比較表\n\n|           | ローカルLLM                             | クラウドLLM                                  |\n| --------- | ----------------------------------- | ---------------------------------------- |\n| 実行環境・接続要件 | ・自社サーバーやローカル端末で動作 ・インターネット接続不要      | ・ベンダーのクラウドサーバー上で動作 ・インターネット接続が必須         |\n| 処理速度・性能   | ・ハードウェアの性能に依存する ・ネットワーク遅延の影響を抑えられる  | ・高性能なサーバーの利用により処理速度が速い ・通信障害の影響を受ける場合がある |\n| コスト       | ・ハードウェアへの投資が必要 ・運用コストは維持費が中心で安定しやすい | ・従量課金が一般的 ・初期費用を抑えられる                    |\n| セキュリティ    | ・オンプレミス環境によりデータを外部に送信する必要がない        | ・データを外部に送信する必要があるため、懸念あり                 |\n| カスタマイズ性   | ・自社のニーズに合わせたモデルを構築しやすい              | ・ベンダーのサービス範囲内                            |\n| スケーラビリティ  | ・物理的なリソースを都度調整する必要がある ・クラウドより手間がかかる | ・柔軟にリソースを調整できる                           |\n\nローカルLLMとクラウドLLMの違いをまとめると上記の通りになります。ただし、OpenAIが提供している「gpt-oss」のように低スペックで動作するような効率性の良いLLMも登場してきています。そういった背景からコスト面などの違いにおいては2025年8月現在、少し状況が変わってきているとも言えるため、定期的な情報収集が必要です。\n\n## 4 ローカルLLMが注目されている背景\n\n![4 ローカルLLMが注目されている背景](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757577785/fuhck2u8wdffx6rmk5nc.jpg)\n\nなぜソフトウェア開発やビジネスにおいて、ローカルLLMが注目されているのでしょうか。具体的な背景としては以下が挙げられます。\n\n* 生成AI活用に対する企業ニーズの増加  \n* セキュリティ意識の向上  \n* 技術的な進化\n\n### 4-1 生成AI活用に対する企業ニーズの増加\n\nソフトウェア開発の領域においては、多様化するニーズやビジネス環境の変化に対応するためにAI活用のニーズが高まっています。\n\n実際に[GitLab](https://about.gitlab.com/ja-jp/)が開催したイベント「[DevOpsDive2025](https://about.gitlab.com/ja-jp/blog/event-report-devopsdive2025/)」によると、ソフトウェア開発ライフサイクルにおいてAIを使用中の国内企業の割合は48%で、米国の38%よりも高い数値となっています。ただし、国内のAI活用はコーディングの範囲に留まっている状況で、開発プロセス全体を通した活用には至っていません。\n\nソフトウェア開発ライフサイクル全体にAI活用を行き渡らせるためには十分なセキュリティ対策が必要になり、その手段として有効なのがローカルLLMの活用です。ローカルLLMならオンプレミス環境により企業の機密情報を安全に扱いながらAIを利用できます。つまり、ローカルLLMはAI活用における重要なソフトウェア開発基盤の一つだと言えるでしょう。\n\n### 4-2 セキュリティ意識の向上\n\n近年ビジネスにおけるIT活用が浸透する中で、セキュリティインシデントも多く発生しており、ソフトウェア開発の領域においてもセキュリティ対策への重要性が高まっています。\n\nLLMをクラウドベースで利用する場合、企業の重要な機密情報を外部のクラウドサーバーへ送信する必要があることから、情報漏えいのリスクが高まります。\n\nローカルLLMなら機密性の高いソースコードや仕様書などを、安心して投入して自由にAIを活用することが可能です。\n\n### 4-3 技術的な進化\n\nローカルLLMが注目されている背景として、技術的な進歩も挙げられます。例えば、日本語特化型LLMの登場により、日本企業がローカルLLMを導入する際にも扱いが容易になり、実用性が高まっています。\n\nまた、先ほど少し触れたようにモデルの軽量化により低スペックで動作できるようなLLMも登場してきているため、以前よりローカルLLMをスムーズに導入できる環境が整ってきていると言えるでしょう。\n\n## 5 ソフトウェア開発におけるローカルLLMのメリット\n\n![5 ソフトウェア開発におけるローカルLLMのメリット](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757577783/kj2jyvoa0bv2n67kwmxu.jpg)\n\nソフトウェア開発におけるローカルLLM導入のメリットは以下の通りです。\n\n* 開発の効率性と生産性の向上  \n* セキュリティ・コンプライアンスの強化  \n* コストの最適化\n\n### 5-1 開発の効率性と生産性の向上\n\nローカルLLMはソフトウェア開発ライフサイクルにおけるさまざまなプロセスで活用できます。例えば、コード補助や自動レビュー生成、バグ修正、脆弱性修正補助などに使えば、ヒューマンエラーのリスクを軽減しながら迅速かつ品質の高いソフトウェア開発を実現することが可能です。\n\nローカルLLMの活用によって効率よく開発を進めることで、開発者はより価値の高い活動や業務に集中できるようになり、結果としてチーム全体のパフォーマンスを向上させられるでしょう。\n\n### 5-2 セキュリティ・コンプライアンスの強化\n\n繰り返しにはなりますが、ローカルLLMなら自社サーバーを利用するため外部にデータを送信する必要がなく、セキュリティやコンプライアンスの強化を図りながら生成AIを活用できます。セキュリティ要件の厳しいプロジェクトや業界でも活用しやすく、開発者の心理的ハードルも下げられ安全に作業を進められるでしょう。\n\nまた、ローカルLLMを通して潜在的な脆弱性を検出し、修正案の提案を受けることでコードの安全性向上にもつなげられます。\n\n### 5-3 コストの最適化\n\nローカルLLMの導入によりコストの最適化を図れるメリットもあります。クラウド型のLLMは初期費用を抑えられるものの、従量課金制を採用していることから利用量（トークン数）が増えると、コストが大幅に増えてしまう可能性もあります。\n\n一方、ローカルLLMは初期にハードウェア導入費用が発生しますが、一度構築してしまえば運用に必要な費用は基本的に維持費だけになるため、長期的な視点で考えるとコストの最適化を図れるでしょう。\n\n## 6 ローカルLLM導入におけるデメリット・課題\n\n![6 ローカルLLM導入におけるデメリット・課題](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757577779/k5x3ndhan9varjcyvlqb.jpg)\n\nローカルLLMの導入においては以下のようなデメリットや課題もあるため、事前に把握しておく必要があります。\n\n* 専門知識の必要性  \n* 高額な初期導入コストの発生  \n* 不正確・不完全なデータを生成する可能性\n\n### 6-1 専門知識の必要性\n\nローカルLLMを導入するためには、オープンソースLLMを自社サーバーで実行できるよう環境の構築やモデルの最適化が必要になります。このプロセスにおいては、専門的な知識や技術が求められるため、社内で適切な人材を配置しなければなりません。基盤となるインフラ設計やファインチューニングなどさまざまな知識が必要になりますが、特にvLLMとHugging Faceなどでホストされているモデルに関する知識が重要です。\n\nまた、ローカルLLM導入後のメンテナンスやセキュリティ管理なども自社で対応しなければならないため、事前に社内で体制を整備しておきましょう。\n\n### 6-2 高額な初期導入コストの発生\n\nローカルLLMを導入する際には、高性能なハードウェアなどを確保する必要があるため、初期の導入コストが高額になりがちです。特に大規模なモデルを扱う場合は、計算能力の高い高価なGPUを用意しなければなりません。\n\nしかし先述したように一度導入してしまえばその後の運用コストは安定しやすいため、長期的な利用を前提とすればクラウドLLMよりも経済的な効果が期待できる可能性は高いと言えます。\n\nなお、NVIDIAと同等スペックのハードウェアを低価格で提供する動きが既にあるので、そのあたりも注視しておきたいところです。\n\n### 6-3 不正確・不完全なデータを生成する可能性\n\nローカルLLMを活用する際には、AIが必ずしも正しいデータを生成するとは限らないことを理解しておく必要があります。例えば、ソフトウェア開発において脆弱性の分析や修正をローカルLLMを通して自動化する場合、正しい結果がアウトプットされない可能性もあるため、AIからの修正案を検討するタイミングなどにおいては人間による二重チェックを積極的に行うことが大切です。\n\nなお、ローカルLLMのデータ品質を保つためには、定期的なモデルのアップデートが重要です。クラウドLLMのように自動で最新の状態にアップデートされるわけではないため、自社で再学習や調整作業を行わなければなりません。\n\n## 7 ソフトウェア開発におけるローカルLLMの活用例\n\n![7 ソフトウェア開発におけるローカルLLMの活用例](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757577784/ipjhxxa41aoymc7nvkbc.jpg)\n\nソフトウェア開発においては以下のようなプロセスにおいてローカルLLMを活用できます。\n\n* コード補完・レビュー  \n* ドキュメント作成・ナレッジ共有  \n* CI/CDパイプラインの作成\n\n### 7-1 コード補完・レビュー\n\nソフトウェア開発でローカルLLMを導入することで、オフラインでのコード補完・レビューが可能になります。コード補完ならコードを記述している際に、AIがコードの提案を行なってくれるため、開発者のコーディングスピードの向上が期待できます。\n\nまた、コードレビューの自動化により、開発者は効率的にコードの改善を実施でき、AIで一貫性のあるレビューを実現することでコード品質の向上につなげられるでしょう。\n\n### 7-2 ドキュメント作成・ナレッジ共有\n\nローカルLLMの活用は、ソフトウェア開発におけるドキュメント作成やナレッジ共有でも役立ちます。例えば、ドキュメント作成なら仕様書の初稿作成や内容のチェックをローカルLLMを通して行えば、作業の効率化につなげられます。\n\nまた、RAGと連携して社内ナレッジベースや文書を利用して社内Q&A検索などを構築すれば、開発チーム内でのナレッジ共有をスムーズに行えるでしょう。\n\n### 7-3 CI/CDパイプラインの作成\n\nソフトウェア開発でのローカルLLMの活用は、[CI/CD](https://about.gitlab.com/ja-jp/blog/what-is-ci-cd/)パイプラインの作成やパイプライン実行時のエラー調査にも貢献できます。また、テストコード生成によってテスト作業の軽減化も支援することが可能です。\n\n[CI/CD](https://about.gitlab.com/ja-jp/blog/what-is-ci-cd/)パイプラインの構築から実行におけるプロセスを効率化すれば、開発者はソフトウェアの開発作業に集中できるようになるため、リリース頻度やスピードの向上につなげられます。\n\n## 8 ローカルLLMの導入方法\n\n![8 ローカルLLMの導入方法](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757577783/xpoecwmgfqwwyxis4rxj.jpg)\n\nでは実際にローカルLLMを導入するにはどのような手順を踏めば良いのかを解説します。\n\n1. 目的と要件の整理  \n2. 環境整備  \n3. 継続的な検証と改善\n\n### 8-1 1.目的と要件の整理\n\nまずはソフトウェア開発の領域において「なぜローカルLLMの導入が必要なのか？」という目的を明確化することが大切です。\n\n例えば、「クラウドからの移行によるコスト最適化を図りたい」「自社のセキュリティ要件にマッチした開発環境を構築したい」など目的を検討します。明確な目的がないと導入そのものが目的となってしまい、十分な効果を得られないためきちんと設定し、社内で共通の認識を持っておく必要があります。\n\nまた、ローカルLLMを導入して具体的にどのような成果を得たいのか定量的なKPIもあわせて設定しておくことで、導入後の効果検証や改善がしやすくなります。例えば、開発コストの削減量やパイプライン実行時間などの目標値の設定が考えられます。\n\n### 8-2 2.環境整備\n\n次にローカルLLMの実行に必要なモデルの選定や環境構築を行います。モデルの選定においては導入目的をもとに、求められる性能やリソース要件などを考慮して検討します。\n\nハードウェア環境においては、使用するモデルのサイズや用途、利用ユーザー数などに応じた要件を満たすことがポイントとなり、特にGPUの性能が重要です。ハードウェア環境が整った後は、ソフトウェア環境の設定を行い実際にモデルを実装していきます。\n\n### 8-3 3.継続的な検証と改善\n\nモデル実装後は、継続的なパフォーマンステストと改善を行います。具体的には、処理速度や回答精度、リソースの利用状況などを検証し、必要に応じて改善や調整を実施します。なお、実際の運用においてはまずは小規模なプロジェクトから開始し、検証結果の内容や利用ユーザーのフィードバックを取り入れながら徐々に拡大していくと良いでしょう。\n\nまた、長期的に安定して運用するためには、メンテナンスやアップデートをスムーズに行える体制づくりも必要です。\n\n## 9 ローカルLLMのおすすめモデル\n\n![9 ローカルLLMのおすすめモデル](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757577779/z48qapdqnbbb67lotscz.jpg)\n\nローカルLLMの導入にあたっておすすめのモデルを紹介します。なお、ここで紹介するモデルは[GitLabのサポート対象](https://docs.gitlab.com/administration/gitlab_duo_self_hosted/supported_models_and_hardware_requirements/#supported-models)です。\n\n* Mistral-Small-3.2-24B-Instruct-2506  \n* Codestral 22B  \n* Llama 3\n\n### 9-1Mixtral-8x7B-Instruct-v0.1\n\nMixtral 8x7Bは、Mistral AIが2023年12月にリリースした大規模言語モデルです。混合エキスパートモデル（MoE）を採用しているのが特徴で、学習・推論スピードに強みがあります。Mixtral 8x7Bならコード生成タスクでも高精度なアウトプットが期待でき、Duo Chatでも活用可能です。\n\n### 9-2 Codestral 22B\n\nMistral AIが2024年5月から公開しているCodestral 22Bは、コーディングに特化した大規模言語モデルです。PythonやJava、C、SQLなど人気のプログラミング言語を含め、80以上の言語に対応しています。コード自動補完など開発効率の向上を目的として活用できます。Chatには使えませんが、ソースコード生成処理として良い選択になります。この時にGitLabは、用途用途にモデルを切り替えられるメリットがあります。\n\n### 9-3 Llama3\n\nLlama3は、Meta社が2024年4月に公開したオープンソース大規模言語モデルです。Llama3には、「8B」と「70B」の2つのモデルが存在します。\n\nLlama3 8Bは、80億のパラメータを持つモデルで比較的コンパクトであることから、計算リソースが限られるシーンでの利用が向いています。一方、Llama3 70Bは、700億のパラメータを持つモデルであり、多様なタスクへの対応やパフォーマンス向上などを目的として活用できます。また、ライセンスフリーで利用可能なモデルの中では最高峰レベルの性能を誇るため、ハードウェアに予算が割けられる場合は70Bをおすすめします。\n\n## 10 ローカルLLM導入における注意点\n\n![10 ローカルLLM導入における注意点](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757577779/twsdcll86zz9jgetvhq5.jpg)\n\nローカルLLMを導入する際には以下のような注意点があり、事前に必要な対策を検討しておくことが大切です。\n\n* 社内での周知・教育・活用定着を図る  \n* 社内でのセキュリティ設定・アクセス制御を徹底する  \n* モデルのライセンスを確認する\n\n### 10-1 社内での周知・教育・活用定着を図る\n\nローカルLLMを自社で導入した場合でも実際に開発者に使われないと意味がありません。導入目的の説明や操作マニュアル・ガイドラインの整備などを行い、利用の定着を図ることが大切です。社内におけるAI活用の利用状況を効率的にチェックするには、ツールの活用がおすすめです。\n\nGitLabのサービスの一つとして「[AI Impact Dashboard](https://docs.gitlab.com/user/analytics/ai_impact_analytics/)」があり、この機能を活用することで自社のAI導入における利用状況を可視化してROIのモニタリングが可能になります。\n\n### 10-2 社内でのセキュリティ設定・アクセス制御を徹底する\n\nローカルLLMは自社サーバーで運用しますが、社内でのセキュリティ対策は必須です。\n\n社内でのセキュリティ対策としてまず挙げられるのは、モデルに入力した機密データの管理の徹底です。LLMが出力するログにはソースコードなどの断片が出力されるケースもあるため、LLMを運用しているOSへのログインや物理アクセスの管理などを行わなければなりません。\n\nまた、実際にモデルを入手する際には改ざんされたモデルを利用しないようダウンロード元には十分注意しましょう。\n\n### 10-3 モデルのライセンスを確認する\n\nローカルLLMを導入する際に注意点したい要素として、モデルのライセンス条件があります。各モデルによって付与されているライセンスが異なり、商用利用や改変、再配布の可否などの条件が設定されています。\n\nライセンス違反にならないよう使用予定モデルのライセンス規約を丁寧に確認し、運用におけるリスクを取り除いておきましょう。\n\n## 11 GitLab Duo Self-HostedによるローカルLLM運用\n\n![11 GitLab Duo Self-HostedによるローカルLLM運用](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757577779/lqeesn9igwma1rdxohdd.png)\n\n[GitLab Duo Self-Hosted](https://about.gitlab.com/ja-jp/blog/gitlab-duo-self-hosted-enterprise-ai-built-for-data-privacy/)を活用することで、ローカルLLMをGitLabと連携して運用できます。[GitLab](https://about.gitlab.com/ja-jp/)は、ソフトウェア開発ライフサイクル全体を効率化できるDevSecOpsプラットフォームです。\n\nここでは、GitLab Duo Self Hostedの特徴やローカルLLMとの連携で実現できることを紹介します。\n\n### 11-1 GitLab Duo Self-Hostedとは？概要と主な特徴\n\n[GitLab Duo](https://about.gitlab.com/ja-jp/gitlab-duo/)は、GitLabが提供するソフトウェア開発におけるワークフローを支援するAIソリューションです。 [Self-Hosted版](https://docs.gitlab.com/administration/gitlab_duo_self_hosted/)ならGitLab Duoをオンプレミス環境で運用できるため、安全にAIを活用しながら開発を進められます。\n\nまた、Mistralなど主要なモデルをサポート対象としているため、自社のセキュリティやパフォーマンス要件に応じて柔軟にモデルを選定し、最適なソリューションを構築できます。\n\n### 11-2 ローカルLLMとGitLabの連携で実現できること\n\nローカルLLMとGitLabの連携により以下のようなことが可能になるため、ソフトウェア開発における生産性と品質向上を実現できます。\n\n* コード補完・レビュー支援（20以上の言語に対応）  \n* セキュリティ脆弱性検出・修正提案  \n* アクセス制御  \n* AI投資のROI測定  \n* CI/CDのyml生成・トラブルシュート、コードレビューの自動化 など\n\n## 12 ローカルLLMの将来性・今後の展望\n\n![12 ローカルLLMの将来性・今後の展望](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757577779/ycesbwldjawmyowsncrw.jpg)\n\n結論から述べるとローカルLLMの需要は拡大し、今後もさまざまなシーンで広く活用されていくと言えます。\n\n一般社団法人 電子情報技術産業協会（JEITA）が発表した「生成AI市場の世界需要額見通し」によると、生成AI市場の世界需要額は年平均53.3%で成長しており、2030年には2,110億ドルに達すると言われています。これは、2023年の106億ドルから約20倍の需要額となる見込みです。\n\nローカルLLMは、厳しいセキュリティ要件にも対応できるなどソフトウェア開発やビジネスにおいて多くのメリットがある技術です。今後も低スペックで動作する高性能モデルの登場や、クラウドとのハイブリッド活用などさらなる技術の発展やアプローチによって、開発者にとって必要不可欠なソフトウェア開発基盤として機能していくでしょう。\n\n※出典：[JEITA、生成 AI 市場の世界需要額見通しを発表](https://www.jeita.or.jp/japanese/topics/2023/1221-2.pdf)\n\n## 13 ローカルLLMに関するQ＆A\n\n![13 ローカルLLMに関するQ＆A](https://res.cloudinary.com/about-gitlab-com/image/upload/v1757577779/a4v40ozyl3jquhqhpsav.jpg)\n\n最後にローカルLLMに関するQ＆Aを紹介します。\n\n### 13-1 ローカルLLM導入はどのようなチームに向いている？\n\nローカルLLM導入は以下のような条件に該当するチームに向いています。\n\n* プロジェクトや業界のセキュリティ要件が厳しい  \n* 機密性が高いソフトウェア開発をしている  \n* CやC++など高い技術力が求められる言語で開発しているが、人員集めに苦労している  \n* クラウドのAPI課金に対してコスト面で負担を感じている  \n* LLMをDevSecOpsに組み込みたい など\n\n### 13-2 ローカルLLM運用のための最低限のハードウェア条件は？\n\nGitLab Duo Self-Hostedをオンプレミスで実行する場合は以下の通りです。ただ実際の要件はモデルのサイズと使用目的などによって異なるため、参考程度として捉えてください。\n\n・GPU：1 x NVIDIA A100（40GB）\\\n・VRAM: 35GB以上\\\n・ストレージ：モデルサイズ分以上\n\n※参考：[ハードウェア要件 | GitLab Duo](https://docs.gitlab.com/administration/gitlab_duo_self_hosted/supported_models_and_hardware_requirements/#hardware-requirements)\n\n### 13-3 ローカルLLMとクラウドLLMのハイブリッド活用例は？\n\nローカルLLMとクラウドLLMの使い分けやハイブリッド活用においては目的や要件によって判断する必要があります。\n\n例えば、機密性の高いソースコードに関する作業であり、かつ利用頻度も高い場合はローカルLLMで実行する必要があります。一方で機密性が低く、かつソースコードに関する作業頻度も低い場合は、クラウドLLMを利用すると良いでしょう。\n\n万が一クラウドLLMを運用中に障害が発生した時は、ローカルLLMを利用します。ただし、使用するモデルが異なるとアウトプットの質にも影響が出てくるため、可能な範囲でハイブリッド活用を検討します。\n\nなお、クラウドLLMは最新モデルを素早く利用できる利点と、モデルを動作するインフラの規模（GPUやVRAMなど）を気にする必要がないため、最新のクオリティでLLMを活用したいケースでの利用が向いているでしょう。\n\n## まとめ ローカルLLMを自社のソフトウェア開発に取り入れよう\n\nソフトウェア開発においてローカルLLMを採用することで、セキュリティ要件が厳しいケースにおいても安全に開発を進められます。実際の導入においては目的の明確化や自社ニーズ・リソースにマッチしたモデルの選定、適切な運用体制の構築が鍵となってきます。\n\nローカルLLMを自社の開発プロセスに導入するならぜひ「[GitLab Duo Self-Hosted](https://about.gitlab.com/ja-jp/blog/gitlab-duo-self-hosted-enterprise-ai-built-for-data-privacy/)」をご活用ください。GitLab Duo Self-Hostedならオンプレミス環境でさまざまなAI機能を活用して、高品質かつ迅速なソフトウェア開発を実現できます。\n\nなお、[GitLab](https://about.gitlab.com/ja-jp/)では世界39か国、5,000人を超えるDevSecOps専門家のインサイトが詰まった完全版レポートを無料で公開しているので、ぜひこちらもご覧下さい。\n\n*監修：小松原つかさ [@tkomatsubara](https://gitlab.com/tkomatsubara)*\n\n*（GitLab合同会社ソリューションアーキテクト本部シニアパートナーソリューションアーキテクト）*",[722,678,679,681,723],"AI/ML","security",{"featured":6,"template":684,"slug":725},"what-is-local-llm","content:ja-jp:blog:what-is-local-llm.yml","What Is Local Llm","ja-jp/blog/what-is-local-llm.yml","ja-jp/blog/what-is-local-llm",{"_path":731,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":732,"content":737,"config":743,"_id":745,"_type":16,"title":746,"_source":18,"_file":747,"_stem":748,"_extension":21},"/ja-jp/blog/what-is-vm",{"config":733,"title":734,"ogTitle":734,"description":735,"ogDescription":735,"ogImage":736},{"noIndex":6},"仮想マシン(VM)とは？意味や導入メリット","VM（仮想マシン）の基礎知識から開発・インフラでの導入メリット、具体的な活用方法まで詳しく解説","https://res.cloudinary.com/about-gitlab-com/image/upload/v1756347347/ocydmzmnj23eitgoiwzb.jpg",{"title":738,"description":739,"authors":740,"heroImage":736,"date":741,"body":742,"category":14},"仮想マシン（VM）とは？意味や導入メリット、GitLab活用例","この記事では、仮想マシンの基礎知識からソフトウェア開発・ITインフラの領域で導入するメリット、具体的な活用方法まで解説します。",[673],"2025-08-28","仮想マシン（VM）は、IT技術が進化する時代の中でソフトウェア開発やビジネスの領域において近年注目されている技術の一つです。実際に自社のソフトウェア開発の領域において、仮想マシンの導入を検討している人も多いのではないでしょうか。仮想マシンを自社の開発に取り入れて確かな効果を発揮するためには、仮想マシンの特徴などを事前に詳しく理解しておく必要があります。\n\nこの記事では、仮想マシンの基礎知識からソフトウェア開発・ITインフラの領域で導入するメリット、具体的な活用方法まで解説するのでぜひ参考にしてください。\n\n## 1. 仮想マシン（VM）の基礎知識\n\n![仮想マシン（VM）の基礎知識](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756347363/iwp4fwdv8jubfrclmvdk.jpg)\n\nまずは、仮想マシンを理解するために知っておきたい仮想化と呼ばれる技術の概要や、仮想マシンの特徴について解説します。\n\n### 1-1 そもそも仮想化とは\n\n仮想化とは、物理的な環境に囚われずにサーバー、ストレージ、ネットワーク、メモリなどのハードウェアリソースを効率よく利用するための技術のことです。\n\nよりわかりやすく簡潔に説明すると、仮想化とは本来1つであるハードウェアリソースを複数あるかのように利用する技術です。この仮想化技術は現代の企業のIT戦略を検討する上で重要な位置付けとなっています。\n\n### 1-2 仮想マシン（VM）とは\n\n![仮想マシン（VM）とは](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756347364/gao2azgosxdb60yoblno.jpg)\n\nでは、この記事の本題である仮想マシンについて説明します。仮想マシンとは、仮想化技術を活用して1つの物理マシン内（コンピューター）に仮想的に複数のコンピューターを再現する環境のことです。\n\n物理マシンは実体として存在するコンピューターであるのに対して、仮想マシンはソフトウェアを利用して物理マシン内に仮想的に再現したコンピューターであるという違いを理解しておくと良いでしょう。\n\nつまり、仮想マシンなら1台のコンピューター上で複数のOSをそれぞれ独立した状態で稼働できるようになります。後にも詳しく解説しますが、これによりサーバー台数の節約やニーズに応じたOSの稼働などができるようになり、開発やビジネスにおけるコスト削減や生産性向上にも寄与します。\n\n## 2 仮想マシン（VM）におけるホストOSとゲストOS\n\n![仮想マシン（VM）におけるホストOSとゲストOS](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756347365/rn4rccmpfjwm4wj2klkl.jpg)\n\n仮想マシンを語る上では、「ホストOS」と「ゲストOS」という言葉の意味についても理解しておく必要があります。\n\nまずホストOSとは、仮想マシンを構築する際の土台となるOSを指します。つまり、実体のある物理マシンにインストールされているOSです。一方、ゲストOSは仮想マシンにインストールするOSのことです。\n\n例えば、Windowsのコンピューターに対して仮想環境を作成して、Linuxをインストールすれば、ホストOSはWindows、ゲストOSはLinuxとなります。このようなホストOSとゲストOSの関係性は業務上でも使われるため、違いを把握しておくと良いでしょう。\n\n## 3 仮想マシン（VM）の歴史\n\n![仮想マシン（VM）の歴史](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756347363/g17rmmdu1jh0jm9ueglu.jpg)\n\n仮想マシンは近年注目されている技術の一つですが、歴史自体は古く、1960年代には既に使用されていました。当時のコンピューターリソースを複数のユーザーで使用するための「タイムシェアリング」という技術が仮想化の起源だと言われています。\n\nその後、時代の流れと共にIT技術が発展し、コンピューターの価格低下も実現できたことから物理的に台数を増やして運用するという考えが広まりました。しかしそれでは企業にとって運用負荷が増加してしまうという課題が残るため、仮想化技術が再び注目されるようになっているのです。\n\n※参考：[「仮想化」を理解するための誕生の歴史 | ITソリューション塾](https://blogs.itmedia.co.jp/itsolutionjuku/2014/06/post-9f0b.html)\n\n## 4 仮想マシンの主な利用シーン\n\n![仮想マシンの主な利用シーン](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756347368/vc1gzpcdyqmym44t92fl.jpg)\n\n仮想マシンは具体的にどのようなシーンで利用できるのでしょうか。具体例として以下が挙げられます。\n\n* ソフトウェア開発・テスト\n* 新しいOSのテスト\n* ソフトウェア・アプリケーションの実行\n* セキュアなWebブラウジング\n\n### 4-1 ソフトウェア開発・テスト\n\n仮想マシンはソフトウェア開発・テストの領域で役立てられます。仮想マシンを使って本番とは隔離された環境で開発を行えば、開発途中でなんらかのトラブルが発生した場合でも影響を最小限に抑えられるでしょう。また、複数の異なるOSを構築できるため、アプリケーションの互換性テストを容易に実行することが可能です。\n\n### 4-2 新しいOSのテスト\n\n企業が業務改善やビジネス上の戦略を理由に既存のOSから新しいOSへの移行を検討するケースもあるでしょう。しかし、使い慣れた環境から新しい環境へ切り替えを行う際には、既存のアプリケーションや周辺機器の互換性・操作性などを細かにチェックしなければなりません。\n\n事前に仮想マシンを使用して移行予定のOSを試せば、移行後の業務への影響度を事前に把握できるでしょう。\n\n### 4-3 ソフトウェア・アプリケーションの実行\n\n業務を進める上で状況によっては、現在利用しているOSでは動作しないソフトウェアやアプリケーションの実行が必要になるケースもあるでしょう。\n\nそういったケースでも仮想マシンを使えばソフトウェアやアプリケーションの実行に必要となるOSを柔軟にインストールできるため、業務に支障が出ることなく仕事を進められるでしょう。\n\n### 4-4 セキュアなWebブラウジング\n\nWebブラウジングを行う際にも仮想マシンを活用できます。Webブラウジングとは、Webブラウザを利用してWebサイトやホームページなどの情報を閲覧することです。\n\nウイルス感染のリスクが高いサイトも存在する中で、仮想マシンを使って隔離されたセキュアな環境でWebブラウジングを行えば、企業におけるセキュリティリスクを軽減できます。\n\n## 5 仮想マシン（VM）を実行するソフトウェアの種類\n\n![仮想マシン（VM）を実行するソフトウェアの種類](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756347364/vzsuhsyjxh38dmdmwios.jpg)\n\n仮想マシンを実行するためにはソフトウェアが必要になりますが、主に以下の種類に分けられます。\n\n* ホストOS型\n* ハイパーバイザーOS型\n\n### 5-1 ホストOS型\n\nホストOS型とは、先ほど解説したホストOS上に仮想化ソフトウェアをインストールして仮想マシンを構築する方法になります。\n\n以下からホストOS型を採用するメリットやデメリット、代表的な仮想化ソフトウェアを紹介します。\n\n#### ５−１−１ ホストOS型のメリット・デメリット\n\nホストOS型のメリットは、既に利用しているOS上にソフトウェアをインストールするだけで仮想マシンを実現できるため、扱いやすく容易に導入できることです。そのため、まずは仮想環境に触れてみたいといったテスト用途や、個人学習用途などで利用することが可能です。\n\nしかし、ホストOS型の場合は物理マシンと仮想マシンとの間にホストOSが介入することになり、本来の処理に加えて余分なリソースがかかる「オーバーヘッド」と呼ばれる現象が発生します。そのため、高速な処理には不向きな手段であることを把握しておかなければなりません。\n\n#### ５−１−２ 代表的な仮想化ソフトウェア\n\nホスト型の仮想化ソフトウェアの例としては以下が挙げられます。\n\n・Oracle VM VirtualBox\n\nVirtualBoxは、Oracle社が提供する人気の仮想化ソフトウェアです。多機能であることが特徴で、「スナップショット」「シームレスモード」「共有フォルダ」など仮想マシンを活用する上で便利な機能が搭載されています。\n\n・VMware Fusion Pro\n\nVMware Fusion Proは、Mac上で仮想マシンを構築し異なるOSを実行できる仮想化ソフトウェアです。ファイル共有などさまざまな機能が提供されています。\n\n### 5-2 ハイパーバイザー型\n\nハイパーバイザー型とは、ホストOSを使わず、ハイパーバイザーと呼ばれる専用の仮想化ソフトウェアをインストールして仮想環境を構築する方法です。以下からハイパーバイザーOS型のメリットやデメリット、代表的なソフトウェアを紹介します。\n\n#### ５−２−１ ハイパーバイザー型のメリット・デメリット\n\nハイパーバイザー型のメリットは、ホストOSを使わずに仮想マシンを構築するため、ホストOS型と比較してオーバーヘッドが少なく高速な処理が期待できます。\n\nただし、既存の物理マシンでハイパーバイザーを使用できない場合は、新たに互換性のある物理マシンを購入する必要があり、そのための費用を用意しなければなりません。また、ホスト型OSと比べて導入や管理においてある程度の専門知識が求められます。\n\nホストOS型とハイパーバイザー型の特徴の比較を以下の表でまとめました。\n\n![ハイパーバイザー型のメリット・デメリット](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756349540/bab2vb3tws84ftqtrj6x.jpg)\n\n#### ５−２−２ 代表的なハイパーバイザー\n\n代表的なハイパーバイザーには以下のようなものがあります。\n\n・KVM\n\nKVMは、Linuxをハイパーバイザーとして動作させることができる仮想化技術です。Linuxカーネル2.6.20以降から標準搭載されているため、Linuxを使用しているなら手軽に試せるでしょう。\n\n・VMware ESXi\n\nVMware ESXiは、 VMware が提供しているソフトウェアです。ESXiファイアウォールによりアクセス制限が可能でセキュリティにも強みを持っているのが特徴です。\n\n・Citrix Hypervisor\n\nCitrix Hypervisorは、 Citrix社が提供する仮想化プラットフォームです。Xen Projectをベースとしており、高性能なハイパーバイザーで信頼性が高いことが特徴です。\n\n## 6 仮想マシンとコンテナの違い\n\n![仮想マシンとコンテナの違い](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756347368/bq7nkfayq63ltttxhlmb.jpg)\n\n仮想化手法においては「コンテナ」と呼ばれる技術もあるため、仮想マシンとの違いを理解しておきましょう。\n\n### 6-1 コンテナとは？\n\n![コンテナとは？](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756347369/cdzvsfyrdh1qc8uctash.jpg)\n\nコンテナとは、アプリケーションを実行するための動作環境を仮想化して利用する技術のことです。\n\n仮想マシンは、物理マシン内に仮想化ソフトウェアを利用して複数の異なるOS（ゲストOS）を構築します。一方、コンテナは、「コンテナエンジン」と呼ばれるコンテナを管理するソフトウェアがOSとして機能するため、ゲストOSは不要になります。\n\n代表的なコンテナエンジンは、「Docker」になります。Dockerを活用すれば、複数のアプリケーションの実行環境を手軽に作成できます。\n\n### 6-2 コンテナの特徴\n\nコンテナは先ほども解説した通りゲストOSが不要であるため、必要最低限のリソースで運用することができコスト削減につながります。また、処理速度も速いことから効率的な運用を実現できるでしょう。\n\nしかし、コンテナの場合はOSが限定されるため、複数の異なるOSを利用できる仮想マシンのような自由度は期待できません。例えば、ソフトウェア開発において異なる種類の環境でテストを実行したい場合には適していない手段だと言えます。また、コンテナはコマンド操作や管理方法など初期で覚えることも多いため、スムーズな導入を実現するためには学習環境や運用体制を構築しておく必要があります。\n\n## 7 ソフトウェア開発・ITインフラの領域で仮想マシン（VM）を導入するメリット\n\n![ソフトウェア開発・ITインフラの領域で仮想マシン（VM）を導入するメリット](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756347365/kk7vgdomzo4quorhjs8v.jpg)\n\nここではソフトウェア開発とITインフラの領域に焦点を当てて、仮想マシン（VM）を導入するメリットについて解説します。\n\n* IT・開発コストの削減\n* 開発・テスト環境構築の迅速化\n* 複数OSの活用による効率性の向上\n* DevSecOpsのサポート\n* セキュリティリスクの軽減\n* 可用性の向上とBCP対策への貢献\n\n### 7-1 IT・開発コストの削減\n\n仮想マシンを導入することで、物理的なハードウェアリソースを論理的に分割する形で共有できるため、コスト削減につながります。複数OSの稼働が必要になった場合に、仮想環境を構築せずに物理的にリソースを準備するとなると、コンピューターの購入費や管理費などさまざまなコストが追加で発生してしまいます。\n\n仮想マシンなら、ハードウェアリソースを効率よく有効活用できるため、ソフトウェア開発・ITインフラの領域でも追加コストの発生を最小限に抑えられます。\n\n### 7-2 開発・テスト環境構築の迅速化\n\n仮想マシンは開発・テスト環境構築の迅速化にもつなげられます。開発者は簡単に仮想環境を作成できるようになるため、需要に応じて開発・テスト環境を瞬時にスピンアップできます。また、使用しない時にも素早くテイクダウンが可能です。\n\n本来であれば開発・テスト環境を構築する際には物理的な作業が発生し、時間を要します。柔軟性と拡張性を持つ仮想マシンなら、急なニーズが発生した場合でも物理的な作業を省略できるため、状況の変化に応じたスピーディーな対応が可能です。\n\n### 7-3 複数OSの活用による効率性の向上\n\n仮想マシンなら1つの物理マシン上で異なる複数のOSを運用できます。時間やコストをかけることなく、必要な時にゲストOSとして構築するだけでさまざまな環境でソフトウェアの開発やテストを実行することが可能です。例えば、WindowsとLinuxを同時に起動してアプリケーションの互換性をチェックするなどの対応が可能です。\n\n複数OSの活用によって開発やテストの効率性向上を実現できるでしょう。\n\n### 7-4 DevSecOpsのサポート\n\nDevSecOpsとは、開発（Dev）、セキュリティ（Sec）、運用（Ops）の3つの概念を組み合わせたアプローチのことを指します。開発サイクルにおいて開発からセキュリティ、運用までを連携して進めることでセキュリティ強化や開発スピードの向上につなげられます。\n\n仮想マシンの導入はこのDevSecOpsのサポートやツールチェーンの合理化にも貢献します。例えば、開発プロセスにおいて仮想マシンを作成し、仮想マシン上にCI/CDのような自動化されたワークフローを取り入れることで独立した環境で実行基盤を構築できます。\n\n### 7-5 セキュリティリスクの軽減\n\n仮想マシンはそれぞれ独立した環境で互いに分離された形で運用され、かつホストシステム（物理的なコンピューター）からも隔離されているため、セキュリティ対策にも役立ちます。\n\n例えば、1つの仮想マシンでセキュリティトラブルが発生した場合でも、他の仮想マシンやホストシステムへの影響を抑えやすいでしょう。ただし、環境分離によるセキュリティリスクの軽減は期待できるものの、トラブルが発生する可能性をゼロにできるわけではありません。仮想環境特有のセキュリティ対策も徹底し、より安全に運用できる体制を構築する必要があります。これについては後述します。\n\n### 7-6 可用性の向上とBCP対策への貢献\n\n仮想マシンは障害にも強く、システムの可用性を高めることも可能です。例えば、現在の仮想マシンの状態を保存・復元できる「スナップショット機能」を活用すれば、システム障害が発生した場合でも容易に以前の状態に戻すことが可能です。\n\nまた、稼働中の仮想マシンを継続したまま別のホストに移行できる「ライブマイグレーション機能」なら、安全性の高いホストへ移動させることで事前にシステムトラブルを回避できるでしょう。\n\n## 8 ソフトウェア開発・ITインフラの領域で仮想マシン（VM）を導入するデメリット\n\n![ソフトウェア開発・ITインフラの領域で仮想マシン（VM）を導入するデメリット](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756347369/d5zasrxf7krbjy2umv2s.jpg)\n\nソフトウェア開発・ITインフラの領域で仮想マシン（VM）を導入する際には以下のようなデメリットもあるため、事前に把握しておくことが大切です。\n\n* パフォーマンス低下の可能性\n* 仮想環境の導入・管理における専門性が高い\n* 仮想環境特有のセキュリティ対策が必要\n* 障害時の対応が増える場合がある\n\n### 8-1 パフォーマンス低下の可能性\n\n仮想マシンは物理的なコンピューターと比較すると性能面で劣る場合があるため、開発時に処理に時間がかかってしまったりなど不便さを感じてしまうかもしれません。例えば、オーバーヘッドが発生すると余分なリソースがかかり、処理速度に影響を与えてしまうでしょう。\n\n特に安定した作業環境が強く求められるシーンにおいては、適切なリソース配分を検討する、状況に応じて物理的なコンピューターを用意して利用するといった対策が必要になります。\n\n### 8-2 仮想環境の導入・管理における専門性が高い\n\n仮想マシンをスムーズに導入し、安定した運用を実現するためには専門的な知識や技術が求められます。次で詳しく触れますが仮想環境においても特有のセキュリティ対策が必要になり、専門知識を持った担当者がいないと十分な対策はできないでしょう。\n\n自社に専門知識を持った人材がいない場合は、新たに確保したり、対象者を教育しなければなりません。そのためには採用・教育コストが発生することも把握しておくことが大切です。\n\n### 8-3 仮想環境特有のセキュリティ対策が必要\n\n仮想マシンに対してもセキュリティリスクは存在するため、仮想環境特有のセキュリティ対策は必要になります。例えば、基盤となる物理マシンやホストOSだけでなく、仮想マシンにも専用のセキュリティソフトを導入することが大切です。また、複数の仮想環境を運用する場合は対策や管理に抜け漏れがないよう注意しなければなりません。\n\nその他、万が一セキュリティトラブルが発生した場合の対応フローを事前に整備しておくことも大切です。\n\n### 8-4 障害時の対応が増える場合がある\n\n仮想マシンは1つの物理マシン上で利用されるため、物理マシンに障害が発生した場合、稼働している全てのシステムに影響が出る可能性もあります。これは単一障害点（SPOF）と呼ばれるものですが、もし発生した場合は復旧対応に時間や手間、そして金銭的なコストがかかってしまうでしょう。\n\n単一障害点を回避するためには、事前に仮想環境基盤の冗長化を検討しておく必要があります。\n\n## 9 仮想マシン（VM）の一般的な設定手順　\n\n![仮想マシン（VM）の一般的な設定手順](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756347369/ivi8vlejqodcfecyl1b9.jpg)\n\n仮想マシンの一般的な設定手順は以下になります。\n\n1. 仮想化ソフトウェアの選定\n2. ゲストOSのインストール\n3. ネットワークの設定・データ共有\n\nまずは仮想マシンを導入する上で仮想化ソフトウェアの選定を行う必要があります。先ほど紹介したようにソフトウェアには「 VM VirtualBox」や「KMV」などがあるため、特徴を把握して自社の要件に合ったものを選びましょう。\n\n仮想化ソフトウェアを選定してインストールした後は、ゲストOSのインストールも行いましょう。最後にネットワーク設定や必要に応じてホストOSとのデータ共有などを行い運用します。\n\n## 10 仮想マシン（VM）でのGitLab活用例・使い方\n\n![仮想マシン（VM）でのGitLab活用例・使い方](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756347369/entroriird3lryl3zpr3.png)\n\n仮想マシンは[GitLab](https://about.gitlab.com/ja-jp/)のようなCI/CDツールと連携が可能で、DevSecOpsの推進にもつなげられます。GitLabでのCI/CDプロセスを実行する環境として仮想マシンを有効活用できます。\n\nここでは、GitLabのサービス紹介や、仮想マシン上でGitLabを使用するメリットなどを解説します。\n\n### 10-1 GitLabとは？\n\nGitLabは、ネイティブAIを搭載したソフトウェア開発のライフサイクル全体を網羅するDevSecOpsプラットフォームです。ソフトウェア構築における計画から開発、テスト、リリース、運用までを単一のプラットフォームで統合して実行することができ、ビジネスの加速化や運用負担・コストの削減につなげられます。\n\nCI/CDパイプラインの構築やセキュリティの自動化、ソースコード管理、プロジェクト管理などソフトウェア開発の効率化に役立つ充実した機能を提供しており、中小企業からエンタープライズまで世界中の多くの企業で導入されています。\n\n### 10-2 仮想マシン上でGitLabを使うメリット\n\n仮想マシン上でGitLabを利用することでどのようなメリットがあるのでしょうか。具体的には以下の通りです。\n\n* セキュアな環境で開発・テストを実行できる\n* 本番環境に近い環境でテストやビルドを行える\n* バックアップ機能やスナップショット機能でデータ復旧が容易になる\n\n#### 10-2-1 セキュアな環境で開発・テストを実行できる\n\n物理マシンとは独立した環境でGitLabを利用するため、セキュアな環境で開発やテストを実施することが可能です。仮想マシン上でトラブルが発生した場合もホストシステムへの影響を抑えられるため、セキュリティ要件が高いプロジェクトにも適しています。\n\nまた、仮想マシンなら常にクリーンな状態の環境を用意できるため、GitLabのCI/CDプロセスにおいて正確なテストやビルドが可能になります。\n\n#### 10-2−2 本番環境と同じ環境でテストやビルドを行える\n\n仮想マシンなら複数の異なるOSを用意できるため、例えばCI/CDプロセスにおいて本番環境を再現して動作確認やテストができるようになります。状況に合わせてさまざまな条件下で使用することで環境の違いによる不具合をリリース前に検出しやすくなるでしょう。\n\n#### 10-2-3 バックアップ機能やスナップショット機能でデータ復旧が容易になる\n\n仮想マシンのスナップショット機能を活用すればデータのバックアップを容易にとることができ、障害時の復旧にも役立てられます。また、GitLabにはバックアップ機能が搭載されているため、より安全なシステム運用を実現できるでしょう。\n\n## まとめ 仮想マシン（VM）の活用で開発効率の向上を図ろう\n\n仮想マシンは近年注目されている技術であり、ソフトウェア開発やITインフラの領域でも積極的に活用することで開発効率の向上やコスト削減、セキュリティ対策などにつながります。\n\nDevSecOpsプラットフォーム「[GitLab](https://about.gitlab.com/ja-jp/)」は、仮想マシン上で利用することができ、CI/CDプロセスを実行する環境として活用できます。その他、プロジェクト管理などチームでの開発を効率化できる豊富な機能が搭載されているため、ぜひ自社への導入をご検討ください。\n\n### より効率的な開発環境をお探しの方は\n\nVMの設定や管理に時間を取られることなく、すぐに開発を始めたい方には[GitLab Workspaces](https://docs.gitlab.com/user/workspace/?utm_medium=blog&utm_source=blog&utm_campaign=eg_apac_brand_x_x_ja_gitlabjapanblogseo_what-is-vm)という選択肢があります。k8sベースの開発環境で、複雑な仮想マシンの構築作業を省略できます。\n\n> ▶︎ GitLab Workspaces について詳しく：[https://docs.gitlab.com/user/workspace/](https://docs.gitlab.com/user/workspace/?utm_medium=blog&utm_source=blog&utm_campaign=eg_apac_brand_x_x_ja_gitlabjapanblogseo_what-is-vm)\n> 詳しくは、[当社GitLabの営業チームまでお気軽にお問い合わせ](https://about.gitlab.com/ja-jp/sales/?utm_medium=blog&utm_source=blog&utm_campaign=eg_apac_brand_x_x_ja_gitlabjapanblogseo_what-is-vm)ください。\n\nなお、GitLabでは世界39か国、5,000人を超えるDevSecOps専門家のインサイトが詰まった完全版レポートを無料で公開しているので、ぜひこちらもご覧ください。\n\n> [2024グローバルDevSecOpsレポートはこちら](https://about.gitlab.com/ja-jp/developer-survey/?utm_medium=blog&utm_source=blog&utm_campaign=eg_apac_brand_x_x_ja_gitlabjapanblogseo_what-is-vm)\n\n[](https://about.gitlab.com/ja-jp/developer-survey/)*監修：知念 梨果* *[@rikachinen](\u003C>)（GitLab合同会社 カスタマーサクセス本部 カスタマーサクセスエンジニア）*",{"featured":93,"template":684,"slug":744},"what-is-vm","content:ja-jp:blog:what-is-vm.yml","What Is Vm","ja-jp/blog/what-is-vm.yml","ja-jp/blog/what-is-vm",{"_path":750,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":751,"content":754,"config":763,"_id":765,"_type":16,"title":766,"_source":18,"_file":767,"_stem":768,"_extension":21},"/ja-jp/blog/what-is-docker",{"noIndex":6,"description":752,"title":753},"Dockerのコンテナ技術は広く普及しつつあります。Dockerとは何なのか。Dockerの使い方は？Dockerプラットフォームとその技術の基礎を学びましょう。","Dockerとは：GitLabとの統合とコンテナについての入門編 | GitLab",{"title":755,"description":756,"authors":757,"date":758,"body":759,"category":14,"heroImage":760,"tags":761},"Dockerとは：超入門編","Dockerのコンテナ技術は広く普及しつつあります。Dockerとは何なのか。Dockerの使い方は？Dockerプラットフォームとその技術の基礎を学びましょう。\n",[673],"2025-06-18","Dockerコンテナ技術は、2013年にオープンソースの「Dockerエンジン」として公開され、翌年2014年には本番環境向けの商用版が発表されました。その後約10年の間に、Dockerは使いやすさと高い利便性から、IT業界で瞬く間に広く普及してきました。これからもその人気は高まっていくでしょう。\n\nしかしその一方で、いまだに「Dockerとは何ですか」という声もよく耳にします。この記事では、Docker環境の導入を検討中で、Dockerにまだ不慣れなデベロッパーやプログラマーの皆様を対象に、Dockerの基本を解説します。Dockerに触れたことのない初心者向けの「Docker超入門編」です。\n\n## 目次\n\n1. Dockerとは：超入門編\n2. Dockerの目的\n\n   * Dockerとは\n   * Dockerでできること\n   * Dockerイメージとは\n   * Dockerコンテナとは\n   * Dockerfileとは\n   * Dockerはなぜ重要なのか\n3. Dockerの主な機能\n\n   * Dockerの特徴\n   * Docker Composeとは\n4. アプリケーションのデプロイにおけるDockerのメリット\n\n   * 開発環境と本番環境のシームレス化\n   * 起動の軽量化・処理速度の高速化\n   * バージョン管理のしやすさ\n   * 優れたスケーラビリティ\n5. Dockerのデメリット\n\n   * ひとつのOSを使わなければならない\n   * 大規模開発時のオーバーヘッド\n   * 技能習得に時間がかかる\n   * セキュリティに脆弱性が生じることもある\n   * コンテナ間での連携が難しい\n6. GitLabはDockerが抱える課題をどのように解決するのか\n7. GitLabのDevSecOpsにおけるDockerの役割\n8. まとめ\n9. FAQ（よくある質問）\n\n## Dockerの目的\n\nはじめに、Dockerとはどういったもので、何ができて、どうして便利なのか、なぜ重要なのか、Dockerの目的に着目しながらその概念をまとめていきます。\n\n### Dockerとは\n\nDockerは、Linuxのコンテナ技術を用いた軽量なソフトウェアコンテナプラットフォームです。アプリケーションの開発、出荷、実行を簡易化するために設計されました。Dockerを使えば、すべての依存関係と一緒にアプリケーションをパッケージ化できるため、依存関係を一つひとつ手動でインストールする必要がなくなり、一貫性のあるコード実行が可能になります。\n\nDockerを使えばアプリケーションの実行環境を標準化でき、環境の違いによる問題を減らすことで開発から本番環境へのデプロイ時間を大幅に短縮できます。\n\nLinuxには以前からコンテナ仮想化という技術がありました。この技術を使うと、プログラムを開発・実行環境から隔離することにより、複数のプログラムを素早く実行できます。ただし、この従来型の仮想化技術は、仮想環境を構築するためにホストとなるOS（オペレーティングシステム）に依存する必要がありました。Dockerはこのコンテナ仮想化技術をOSに関係なく簡単に扱えるようにしたソフトウェアといえます。\n\nDockerの基本概念はイメージとコンテナです。Dockerイメージは、読み取り専用のテンプレートであり、コンテナを作成するための指示が記述されています。たとえば、コンテナで実行するアプリケーションとその依存関係、環境変数、ファイルシステムなどがこれに含まれます。\n\n### Dockerでできること\n\nDockerを使うと、1台のマシン中に複数のコンテナ（仮想環境）をビルドできるため、いくつかの開発環境に対応することができます。つまり、1台のサーバー上で複数のアプリケーションを効率的に動かすことができるのです。アプリケーションの開発環境をDockerで構築すれば、たとえば開発環境（Windows）で動いていたアプリケーションがLinux上で起動しない、といった問題は発生しません。Dockerで構築した環境は、他のデベロッパーとクラウド上で簡単に共有できるため、開発作業がスムーズに進められます。\n\n### Dockerイメージとは\n\nDockerイメージは、アプリケーションを実行するのに必要なソースコードと必要な依存関係をパッケージ化したものです。Dockerコンテナを実行する際には、このDockerイメージが必要です。\n\nDockerイメージは、コンテナイメージを構成する複数のファイルに、`Dockerfile` を合わせてビルドします。つまり、Dockerイメージは、手作業で書くのではなく、コマンドを使って作成します。\n\nそのため、Dockerイメージは単一のファイルではなく、Dockerコンテナの実行に必要なパッケージ（ファイルやメタデータの集合体）であることを理解することが重要です。\n\n### Dockerコンテナとは\n\nLinuxのコンテナは、アプリケーションを内包し、必要なライブラリや依存関係、ファイルが含まれています。\n\n一方、Dockerコンテナは、Dockerイメージの実行可能なインスタンスです。これはDockerイメージから生成され、アプリケーションを実行するためのランタイム環境です。ただし、ハイパーバイザーを使用する従来の仮想化とは違い、DockerのコンテナはホストOS（オペレーティングシステム）のカーネルで実行されます。Dockerイメージ内には、個別のOSはありません。\n\nDockerイメージは環境のスナップショットであり、コンテナはソフトウェアを実行する環境といえます。\n\n### Dockerfileとは\n\n`Dockerfile`は文字情報を主体とするファイルで、ファイルの拡張子はありません。`Dockerfile`には、アプリケーションの構築から実行までのプロセスに必要なコマンドが記述されています。どのファイルをどこから取得して、どんな処理を行ない、Dockerイメージに含めるのかなどを記述します。\n\n`Dockerfile`は、Dockerイメージを作成するためのテキストファイルです。コンテナイメージをビルドする場合も、コンテナのビルド手順を`Dockerfile`で定義する必要があります。この`Dockerfile`には、命令のスクリプトが含まれており、Dockerはコンテナイメージをビルドする際にこのスクリプトを使用します。\n\n### Dockerはなぜ重要なのか\n\nDockerは、コンテナに関する既存のコンピューティングの概念、とりわけLinuxの「cgroups」や「namespaces」、「overlayfs」などの技術を活用しています。これは、アプリケーションの依存関係をサーバーやネットワークなどのインフラストラクチャから隔離したいという、デベロッパーやシステムオペレーターのニーズに応えるものでした。\n\nDockerを使うと、1台のサーバー上でさまざまなアプリケーションを簡単に仮想化・実行できるようになります。さらには、ローカルマシンに依存しない開発環境を実現でき（開発環境の統一）、本番環境に近い環境でのシミュレーションが可能になり、アプリケーションの依存関係も管理できます。加えて、ビルド、テスト、デプロイまでの各プロセスを一貫して行なうことができます。\n\n## Dockerの主な機能\n\nDockerは、Linuxのコンテナ技術を使用しています。Dockerコンテナはよく仮想マシンと比較されます。\n\n仮想マシンでは、ホストマシン上でハイパーバイザーを利用してゲストOSを動かし、さらにその上でミドルウェアやライブラリ、さらにその上にアプリなどを実行します。\n\nそれに対し、コンテナはホストマシンのカーネルを利用し、プロセスやユーザーなどを隔離します。そのため、非常に軽量で、まるで別のマシンが動いているかのように動作します。その結果、アプリなどを高速に起動、停止することが可能です。\n\nDockerは、次の4つの構成要素から成り立っています。\n\n* **Dockerイメージ：** アプリケーション実行に必要なソースコード、アプリと依存関係のパッケージ\n* **Dockerコンテナ：** アプリケーションを実行するランタイム環境\n* **Docker Hub：** クラウド上のレジストリサービス。アプリケーションやサービスコンテナのビルドと配信を行なう\n* **Dockerfile：** Dockerイメージを作成するために実行するコマンドライン命令を含むテキストファイル\n\n### Dockerの特徴\n\nDockerには、次のような特徴があります。\n\n* **軽量かつ高速：** 1つのOSで複数のコンテナを管理でき、仮想マシンより軽量で高速に立ち上げることが可能。\n* **環境の一貫性が保持でき再現性がアップ：** Dockerコンテナは異なるプラットフォームでも一貫して動作するため、ローカル、クラウド、ハイブリッド環境への移行が簡単にできる。\n  移植性が高い －クラウドシステムとの親和性が高く、主要なクラウドプロバイダーはDockerコンテナの実行をサポートしている。\n* **サンドボックスの提供：** セキュリティ対策やソフトウェア開発において、隔離された仮想環境でプログラムを実行・検証できる。このため、ホストマシンの環境を守ることができる。\n* **IaC（インフラストラクチャのコード化）を使用して、インフラをコード化：** Dockerfileによりミドルウェアのインストールや環境設定をコード化して管理できる。\n\n### Docker Composeとは\n\nDocker Composeは、複数のDockerコンテナを一元管理する、 Dockerアプリケーションのためのツールです。YAMLファイルを使用してアプリケーションのサービスを設定します。単一のコマンドで複数のサービスをまとめて生成したり、起動・停止したりすることができます。\n\nDocker Composeのコマンド例は次のとおりです。\n\n* **`docker-compose up`：** サービス用のコンテナを構築、作成、起動、アタッチします。リンクされているサービスがまだ起動していない場合は、それらも起動します。\n* **`docker-compose ps`：** Docker Composeで管理されている稼働中のサービスを一覧表示します。\n* **`docker-compose build`：** Docker Composeファイルで定義されているサービスをビルド（構築）します。\n\n## アプリケーションのデプロイにおけるDockerのメリット\n\nアプリケーションのデプロイにおけるDockerのメリットは次のとおりです。\n\n### 開発環境と本番環境のシームレス化\n\nコンテナ技術の利用を開発環境と本番環境で統一することで、環境の違いにより起こる問題を減らすことができます。その結果、デベロッパーと運用チームとの連携がスムーズに行われ、チーム間で発生していた問題も最小限に抑えられます。\n\n### 起動の軽量化・処理速度の高速化\n\nDockerのコンテナ技術は従来の仮想環境より軽く、アプリを瞬時に起動できます。これは、CPUやメモリなどのコンピュートリソースを必要最低限しか使用しないためです。起動速度が上がることで、開発にも集中できます。\n\n### バージョン管理のしやすさ\n\nDockerでは、GitLabなどのソースコードのバージョン管理ツールを使用できるため、バージョン管理の可視化が進むだけでなく、ロールバックやアップデートも簡単に行なえるようになります。\n\n### 優れたスケーラビリティ\n\nコンテナは軽量で拡張性に優れています。必要に応じて簡単に増減できます。これにより、アプリケーションの拡張やスケーリングを迅速に行なえるため、変わりゆく状況にも柔軟に対応できます。\n\n## Dockerのデメリット\n\nDockerにはさまざまなメリットがありますが、いくつかデメリットも存在します。以下にデメリットを挙げます。\n\n### 1つのOSを使わなければならない\n\nDockerは1つのOS上で複数のコンテナを作成します。これにより起動速度や処理速度の面でメリットがありますが、同時にデメリットになることもあります。たとえば、異なるOS環境で検証をしたい場合には、別のマシンや仮想マシンを準備する必要が生じます。\n\n### 大規模開発時のオーバーヘッド\n\nDocker自体は軽量ですが、大規模システムに拡張する場合には、Dockerの管理に伴う負荷が発生します。Dockerは1台のサーバーで多数のコンテナを実行できますが、その反面、管理やオーケストレーションが必要になり、その処理のためにオーバーヘッドが生じる場合があります。Dockerだけですべての管理を行なうのが困難になることもあります。\n\n### 技能習得に時間がかかる\n\nDockerは他の仮想マシンと異なる手法で仮想環境を構築します。つまり、デベロッパーは新しいコンセプトをすべてゼロから習得しなければならず、それには時間がかかります。Dockerの動作原理をきちんと理解せずに使用すると、あとでトラブルや問題が発生することもあります。Dockerについてしっかりと学習してから運用に取り組むようにしましょう。\n\n### セキュリティに脆弱性が生じることもある\n\nDockerはコンテナ型アーキテクチャです。1台のマシン上で複数のコンテナが動作するため、このことに起因する脆弱性には注意が必要です。たとえば、複数のコンテナがホストOSのリソースやカーネルを共有しているため、一つのコンテナに脆弱性があった場合、全体にその影響が及ぶ可能性があります。\n\n### コンテナ間での連携が難しい\n\n複数のコンテナ間での連携を検討している場合、各種設定が難しいために、運用時に問題が発生することがあります。たとえば、アプリとデータベースを別のコンテナで作成し、一緒に運用したい場合には、同一ホスト内で通信設定をしなければなりません。ポートやソケットを開放する場合にはセキュリティ面でリスクが生じます。それを避けるために設定を複雑にしてしまうと、今度は運用面で問題が起きる恐れがあります。コンテナを連携させる際は、設計段階から十分に検討することが重要です。\n\n## GitLabはDockerが抱える課題をどのように解決するのか\n\nDockerコンテナ内にGitLabをインストールすることができます。[GitLab](https://about.gitlab.com/ja-jp/platform/)は、Git「分散型バージョン管理システム」を主体としたDevSecOpsプラットフォームです。ソフトウェア開発ライフサイクル全体に対応する単一のプラットフォームで、GItLabを活用することで高品質なソフトウェアの迅速なデリバリーを実現できます。\n\nDockerコンテナ内にGitLabをインストールすると、GitLabインスタンスにアクセスできるようになります。Dockerコンテナへの[GitLab Dockerイメージのインストールは公式にサポート](https://about.gitlab.com/ja-jp/install/)されています。\n\nDockerが抱えるいくつかの問題のうち、特にセキュリティについては、GitLabのDevSecOps（開発、セキュリティ、運用）を活用して対処することができます。GitLabのDevSecOpsでは、[シフトレフト](https://about.gitlab.com/ja-jp/topics/ci-cd/shift-left-devops/)を重視しており、セキュリティ対策を開発サイクルの早い段階に組み込むことにより、コンテナイメージの持つセキュリティの問題の早期発見と対応を図っています。継続的インテグレーションによってこのシフトレフトのコンセプトを実践することで、セキュリティ対応にかかっていたコストを削減できます。\n\nDevSecOpsにおいて重要なCI/CDを実現するためには、自動化が欠かせません。GitLabではパイプラインがCI/CDの命令をまとめています。そして、その指示に従いプロセスの自動化を実現するときの基盤になっているのが[GitLab Runner](https://docs.gitlab.com/runner/)（英語）です。GitLab Runnerはセキュリティのシフトレフトを実現する上で重要な役割を果たしています。\n\nGitLab Runnerはセキュリティスキャンやテストを指定したタイミングで自動で実行してくれます。また、レポート作成ジョブを実行して、ダッシュボードに最新情報を表示することも可能です。\n\n## GitLabのDevSecOpsにおけるDockerの役割\n\nGitLabを活用したDevSecOpsインテグレーションにおいても、Dockerは非常に大切な役割を担っています。\n\n### CI/CDジョブのコンテナ化\n\nGitLab CI/CDでは、CI/CDパイプラインでDockerコンテナを使用することで、次のようなことが可能になります。\n\n* **一貫性：** CI/CDジョブはコンテナ内で実行されるため、依存関係や環境の違いによるエラーが防げます。\n* **スケーラビリティ：** コンテナは軽量かつ迅速に起動でき、大規模なパイプラインでも効率的に実行できます。\n* **環境の柔軟性：** ジョブごとに異なるDockerイメージを指定できるため、必要な環境を簡単に準備できます。\n\nGitLab RunnerのDockerイメージは、UbuntuまたはAlpine Linuxをベースにしています。Dockerイメージは標準の`gitlab-runner`コマンドを内包しており、ホストに直接GitLab Runnerをインストールしたかのように動作します。\n\n### セキュリティスキャンの自動化\n\nセキュリティはDevSecOpsでの重要な要素であり、Dockerはこれをサポートします。\n\n* **コンテナイメージのセキュリティスキャン：** GitLabには、CI/CDパイプラインでDockerイメージをスキャンする機能があります。このスキャンにより脆弱性がチェックされ、イメージ内の依存関係やコードの安全性を評価できます。\n* **コンテナ脆弱性スキャンの自動化：** GitLabにはTrivyやAquaなどのセキュリティツールを統合できます。DockerイメージのOSやアプリケーションが最新であるか、既知の脆弱性がないかをチェックします。\n\n### IaC（インフラストラクチャのコード化）と環境管理\n\n* **再現性：** DockerをGitLabのCI/CDジョブ内で使用することで、開発環境と本番環境の整合性を保つことできます。\n* **ステージングやテスト環境を即時に構築：** Docker ComposeやKubernetesと連携することで、特定のブランチやマージリクエストごとに分離された環境をGitLabで作成できます。これにより、テストやセキュリティスキャンを効率的に実行できます。\n\n### デプロイの効率化\n\nGitLabは、Dockerを使用する以下のデプロイパターンをサポートしています。\n\n* **Dockerイメージのビルドとプッシュ：** アプリをコンテナイメージとしてビルドして、GitLabのContainer Registryや他のDockerレジストリにプッシュします。\n* **継続的デリバリー：** Dockerイメージを使ってコンテナオーケストレーションツールにデプロイすることで、迅速で安全なリリースが可能になります。\n\n### マイクロサービスアーキテクチャのサポート\n\nGitLabとDockerを組み合わせることで、マイクロサービスアーキテクチャを簡単に構築できます。マイクロサービスは別々のDockerコンテナとして実行します。GitLab CI/CDパイプラインを使うと、以下のことを管理できます。\n\n* サービス間の依存関係の設定\n* 個別のセキュリティスキャン\n* バージョン管理（ロールバックが容易になります）\n\n## まとめ\n\n2013年の公表以来、Dockerは瞬く間にIT業界に広く普及しました。本記事では、Dockerの基本概念、基本技術、Dockerを使って何ができるのか、なぜDockerが重要なのか、Dockerを理解上でよく目にする用語などについて紹介してきました。\n\nDockerを使う場合には、DevSecOpsにとって大切なCI/CDを実現するためにも、GitLab CI/CDなどの自動化ツールの導入をおすすめします。GitLab のCI/CDパイプラインでDockerコンテナを使用することで、開発における一貫性の維持、スケーラビリティの実現、柔軟な環境の準備が可能になります。\n\n## FAQ（よくある質問）\n\n### Dockerで何ができるのか？\n\nDockerコンテナは、軽量でスタンドアロンの仮想化技術であり、アプリケーションコード、その依存関係、ライブラリをすべてパッケージ化します。Dockerを使うと、1台のマシン上に複数のコンテナ（仮想環境）を構築でき、開発環境や検証環境の統一が図れます。詳しくは、記事の本文をご覧ください。\n\n### Dockerは何に使うのか？\n\nDockerは、デベロッパーがアプリケーションとその依存関係をシステムから切り離したいとき使用します。コンテナにはアプリケーションとその依存関係がまとめられており、軽量な実行環境を提供します。詳しくは、記事の本文をご覧ください。\n\n### Dockerコンテナとは何ですか？\n\nDockerイメージが実行時にコンテナになります。Dockerコンテナは、アプリケーションを実行するためのランタイム環境です。Dockerコンテナに関する詳細は、記事の本文をご覧ください。\n\n*監修：川瀬 洋平 [@ykawase](https://gitlab.com/ykawase)*\n\n*（GitLab合同会社 カスタマーサクセス本部 シニアカスタマーサクセスマネージャー）*","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750226168/pf5cwmvqq09v1pe0re66.jpg",[111,762,677,678,679,680,723,681],"cloud native",{"featured":93,"template":684,"slug":764},"what-is-docker","content:ja-jp:blog:what-is-docker.yml","What Is Docker","ja-jp/blog/what-is-docker.yml","ja-jp/blog/what-is-docker",{"_path":770,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":771,"content":779,"config":789,"_id":791,"_type":16,"title":792,"_source":18,"_file":793,"_stem":794,"_extension":21},"/ja-jp/blog/how-we-decreased-gitlab-repo-backup-times-from-48-hours-to-41-minutes",{"title":772,"description":773,"ogTitle":772,"ogDescription":773,"noIndex":6,"ogImage":774,"ogUrl":775,"ogSiteName":776,"ogType":777,"canonicalUrls":775,"schema":778},"GitLabリポジトリのバックアップを48時間から41分に短縮した方法","15年前のGit関数のパフォーマンス上のボトルネックを追跡して修正し、効率性の向上、より強固なバックアップ戦略の導入、リスクの軽減を実現した方法をご紹介します。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097166/Blog/Hero%20Images/Blog/Hero%20Images/REFERENCE%20-%20display%20preview%20for%20blog%20images%20%282%29_2pKf8RsKzAaThmQfqHIaa7_1750097166565.png","https://about.gitlab.com/blog/how-we-decreased-gitlab-repo-backup-times-from-48-hours-to-41-minutes","https://about.gitlab.com","記事","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLabリポジトリのバックアップを48時間から41分に短縮した方法\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Karthik Nayak\"},{\"@type\":\"Person\",\"name\":\"Manuel Kraft\"}],\n        \"datePublished\": \"2025-06-05\",\n      }",{"title":772,"description":773,"authors":780,"heroImage":774,"date":783,"body":784,"category":14,"tags":785},[781,782],"Karthik Nayak","Manuel Kraft","2025-06-05","リポジトリのバックアップは、いかなる堅牢なディザスタリカバリ戦略においても不可欠な要素です。しかし、リポジトリのサイズが大きくなるにつれて、信頼性の高いバックアップの作成プロセスはますます難しくなります。GitLabでは、[Railsリポジトリ](https://gitlab.com/gitlab-org/gitlab)のバックアップに48時間かかっていました。そのため、バックアップ頻度かシステムパフォーマンスのどちらを優先するかを選ばないといけないという難しい状況にありました。お客様のため、そして社内ユーザーのためにこの問題に取り組むことにしました。\n\n最終的に、15年前に作成したGit関数でO(N²)レベルの複雑なアルゴリズムが使われていたのがこの問題の原因であることを突き止め、アルゴリズムを変更して修正したところ、__バックアップ時間が大幅に短縮__されました。その結果、コストの削減、リスクの軽減とともに、コードベースに合わせて実際にスケールするバックアップ戦略を実施できるようになりました。\n\nこれは、大規模なリポジトリのユーザーなら誰にでも起こりうるGitのスケーラビリティの問題であることが判明しました。この問題をどのように追跡して修正したかをご説明します。\n\n## 大規模なバックアップ\n\nまずは、問題について詳しく見ていきましょう。組織においてリポジトリのサイズが大きくなり、バックアップが複雑化するにつれて、以下のような課題が生じる可能性があります。\n\n* **時間がかかるバックアップ**：非常にサイズの大きいリポジトリを使用している場合、バックアップの作成に数時間かかる可能性があるため、定期的なバックアップを行うのが難しくなりがちです。\n* **リソースの集中**：長時間のバックアップ処理には大量のサーバーリソースが必要となることがあるため、他のオペレーションに影響を及ぼす可能性があります。\n* **バックアップの実施期間**：24時間体制で業務を行っているチームにとって、このような長時間の処理を行える適切なメンテナンス期間を確保するのは難しい場合があります。\n* **失敗するリスクの増大**：バックアップ処理に長時間かかると、ネットワークの問題、サーバーの再起動、システムエラーなどによる中断の影響を受けやすくなります。そのため、場合によっては長時間かかるバックアップ処理を最初からやり直さざるを得なくなります。\n* **競合状態**：バックアップの作成に時間がかかるため、その間にリポジトリが大きく変更される可能性があります。結果として、使用できないバックアップが作成されたり、オブジェクトにアクセスできなくなってバックアップ処理が中断されたりすることがあります。\n\nこのような課題によって、バックアップの頻度や完全性を妥協せざるを得なくなる可能性があります。しかしながら、データ保護という観点では妥協すべきではありません。バックアップの実施期間が長くなると、顧客は回避策を取らざるを得なくなることがあります。その場合、外部ツールの導入やバックアップ頻度の削減などが行われますが、結果として、組織全体で一貫したデータ保護戦略を維持できなくなる可能性があります。\n\nでは、GitLabがどのような方法でパフォーマンス上のボトルネックを特定し、解決策を見つけ、バックアップ時間を短縮するためにどのように導入したかを詳しく見ていきましょう。\n\n## 技術的な課題\n\nGitLabのリポジトリバックアップ機能では、[`git bundle create`](https://git-scm.com/docs/git-bundle)コマンドを使用しています。このコマンドは、ブランチやタグのようなすべてのオブジェクトと参照を含むリポジトリの完全なスナップショットをキャプチャします。このバンドルは、リポジトリを正確な状態で再作成するための復元ポイントとして機能します。\n\nしかしながら、このコマンドの実装には参照数に関連するスケーラビリティの低さの問題があり、パフォーマンス上のボトルネックとなっていました。リポジトリ内の参照数が増えるにつれて、処理時間が飛躍的に増加していました。当社の一番大きなリポジトリでは数百万個の参照が含まれますが、バックアップ処理に48時間以上かかることもありました。\n\n### 根本原因分析\n\nそこで、このパフォーマンス上のボトルネックの根本原因を特定するために、実行中のコマンドのフレームグラフを分析しました。\n\n![実行中のコマンドが示されたフレームグラフ](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097176/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750097176388.jpg)\n\nフレームグラフは、スタックトレースを使用してコマンドの実行パスを表示します。各バーはコード内の関数に対応しており、バーの幅はその特定の関数内でコマンドの実行に費やされた時間を示します。\n\n10,000個の参照が含まれるリポジトリで実行された`git bundle create`コマンドのフレームグラフを調べたところ、実行時間の約80%が`object_array_remove_duplicates()`関数に費やされていました。この関数は、[コミットb2a6d1c686](https://gitlab.com/gitlab-org/git/-/commit/b2a6d1c686)（バンドル：同じ参照を複数回指定できるように許可、2009年1月17日）でGitに導入されたものです。\n\nこの変更内容を理解するには、`git bundle create`を使用すると、バンドルに含める参照を指定できることを把握する必要があります。完全なリポジトリバンドルの場合、`--all`フラグを指定するとすべての参照がパッケージ化されます。\n\nこのコミットは、ユーザーがコマンドラインから重複した参照を指定（例：`git bundle create main.bundle main main`）すると、重複したmain参照を適切に処理せずにバンドルが作成されてしまうという問題に対処したものでした。Gitリポジトリでこのバンドルをアンバンドルすると、同じ参照を二度書き込もうとするため、壊れてしまいます。そのため、重複回避を目的として、すべての参照で重複の特定処理が繰り返されるようにネストされた`for`ループを用いたコードが実装されました。このようなO(N²)アルゴリズムは、参照数が多いリポジトリではパフォーマンス上の重大なボトルネックとなり、かなりの処理時間がかかっていました。\n\n### 修正方法：O(N²)アルゴリズムを効率的なマッピングに置き換える\n\nGitLabは、明らかになったパフォーマンスの問題を解決するために、ネストされたループをマップデータ構造に置き換えるアップストリーム修正をGitにコントリビュートしました。これにより、各参照がマップに追加され、各参照の単一のコピーのみが処理目的で自動的に保持されるようになりました。\n\nこの変更により、`git bundle create`のパフォーマンスが劇的に向上し、参照数の多いリポジトリのスケーラビリティが大幅に改善されました。10,000個の参照があるリポジトリでベンチマークテストを行った結果、パフォーマンスが6倍向上することが明らかになりました。\n\n```shell\nBenchmark 1: bundle (refcount = 100000, revision = master)\n  Time (mean ± σ): \t14.653 s ±  0.203 s\t[User: 13.940 s, System: 0.762 s]\n  Range (min … max):   14.237 s … 14.920 s\t10 runs\n\nBenchmark 2: bundle (refcount = 100000, revision = HEAD)\n  Time (mean ± σ):  \t2.394 s ±  0.023 s\t[User: 1.684 s, System: 0.798 s]\n  Range (min … max):\t2.364 s …  2.425 s\t10 runs\n\nSummary\n  bundle (refcount = 100000, revision = HEAD) ran\n\t6.12 ± 0.10 times faster than bundle (refcount = 100000, revision = master)\n```\n\nパッチは承認され、アップストリームのGitに[マージ](https://gitlab.com/gitlab-org/git/-/commit/bb74c0abbc31da35be52999569ea481ebd149d1d)されました。GitLabでは、次のGitバージョンがリリースされる前にお客様がすぐに恩恵を受けられるように、この修正をバックポートしました。\n\n## 結果：バックアップ時間の大幅な短縮に成功\n\nこの改善によるパフォーマンスの向上は、まさにこれまでの状況を一変させるものでした。\n\n* **バックアップ時間が48時間から41分に短縮**：GitLab最大のリポジトリ（`gitlab-org/gitlab`）のバックアップを従来のわずか1.4%の時間で作成できるようになりました。\n* **一貫したパフォーマンスの維持**：この修正はリポジトリのサイズに関係なく機能し、安定してスケールします。\n* **効率的なリソースの利用**：バックアップ処理中のサーバー負荷が大幅に軽減されました。\n* **幅広い適用性**：もっとも劇的な改善が見られるのはバックアップの作成ですが、多数の参照を処理するすべてのバンドルベースの操作においてメリットがあります。\n\n## GitLabを利用するお客様にとってのメリット\n\nGitLabを利用する組織は、この改善によって、リポジトリのバックアップとディザスタリカバリ計画方法に関して、即座に次のような具体的なメリットを得られます。\n* **バックアップ戦略の変革**   \n  * 企業チームは、開発ワークフローに影響を与えたり、長期にわたるバックアップ期間を確保したりすることなく、夜間に実施する完全バックアップのスケジュールを確立できます。   \n  * 長期のバックアップ専用の時間を設けなくとも、夜間スケジュール中にバックグラウンドでシームレスに実行できます。  \n* **事業継続性の向上**  \n  * バックアップ時間が数日から数分に短縮されたことで、組織は回復ポイント目標（RPO）を大幅に最小化できます。これはビジネスリスクの軽減につながります。災害が発生した場合でも、数日かからず、数時間の作業で復旧できる可能性があります。  \n* **運用負荷の軽減**   \n  * サーバーリソースの消費を抑えられ、メンテナンス期間が短縮されます。  \n  * バックアップ時間が短縮されるため、コンピューティングコストも削減します。特に処理時間が延びると、コストの増加に直結するクラウド環境においては顕著です。  \n* **将来にわたって活用できるインフラストラクチャ**   \n  * リポジトリの規模が大きくなっても、バックアップ頻度とシステムパフォーマンスのどちらを優先するか選ぶ必要はもうありません。   \n  * コードベースの拡大にあわせて、バックアップ戦略もシームレスに拡張できます。\n\n組織は、パフォーマンスや完全性を犠牲にしなくても、より堅牢なバックアップ戦略を実施できるようになりました。以前は難しいトレードオフに直面していたものの、今では簡単な方法で運用できます。\n\n[GitLab 18.0](https://about.gitlab.com/ja-jp/blog/gitlab-18-0-release/)のリリース以降、ライセンスプランに関係なく、GitLabをご利用のお客様は全員、ご紹介した改善点を利用して[バックアップ](https://docs.gitlab.com/administration/backup_restore/backup_gitlab/)戦略の立案および実施を行えるようになりました。設定を変更する必要はもうありません。\n\n## 今後の展望\n\n今回の革新的な改善は、スケーラブルでエンタープライズグレードなGitインフラの提供に向けた、当社の継続的な取り組みの一環です。バックアップの作成時間が48時間から41分に短縮されたことは重要なマイルストーンとなりましたが、引き続きスタック全体においてパフォーマンス上のボトルネックを特定し、対処しています。\n\n今回の改善をGitのアップストリームプロジェクトにコントリビュートでき、GitLabユーザーだけでなく、広範なGitコミュニティにメリットをもたらせたことを特に誇りに思っています。このような協調的なアプローチにより、改善に対する徹底的なレビューおよび幅広いテストの実施が行われ、誰もがそのメリットを得られるようになります。\n\n> GitLabではパフォーマンスを最適化するために、このような深いレベルでインフラに取り組んでいます。ぜひGitLab 18のオンラインリリースイベントにご参加ください。ほかにどのような根本的な機能強化が行われたかをご紹介します。[今すぐご登録ください！](https://about.gitlab.com/ja-jp/eighteen/)",[786,787,92,788,481],"Git","オープンソース","パフォーマンス",{"slug":790,"featured":93,"template":684},"how-we-decreased-gitlab-repo-backup-times-from-48-hours-to-41-minutes","content:ja-jp:blog:how-we-decreased-gitlab-repo-backup-times-from-48-hours-to-41-minutes.yml","How We Decreased Gitlab Repo Backup Times From 48 Hours To 41 Minutes","ja-jp/blog/how-we-decreased-gitlab-repo-backup-times-from-48-hours-to-41-minutes.yml","ja-jp/blog/how-we-decreased-gitlab-repo-backup-times-from-48-hours-to-41-minutes",{"_path":796,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":797,"content":804,"config":813,"_id":815,"_type":16,"title":816,"_source":18,"_file":817,"_stem":818,"_extension":21},"/ja-jp/blog/what-is-kubernetes",{"title":798,"description":799,"ogTitle":798,"ogDescription":799,"noIndex":6,"ogImage":800,"ogUrl":801,"ogSiteName":776,"ogType":802,"canonicalUrls":801,"schema":803},"Kubernetes（K8s）とは？その仕組みから利点、使い方まで","Kubernetes（K8s）とは？Kubernetes の読み方から覚えておきたい用語、仕組みやその利点について学びましょう。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687485/Blog/Hero%20Images/kubernetes.jpg","https://about.gitlab.com/blog/what-is-kubernetes","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Kubernetes（K8s）とは？その仕組みから利点、使い方まで\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"GitLab Japan Team\"},{\"@type\":\"Person\",\"name\":\"GitLab\"}],\n        \"datePublished\": \"2025-04-28\",\n      }",{"title":798,"description":799,"authors":805,"heroImage":800,"date":808,"body":809,"category":14,"tags":810},[806,807],"GitLab Japan Team","GitLab","2025-04-28","## 目次\n\n1. Kubernetesとは？その読み方と用途\n2. Kubernetes（K8s）の基本用語解説\n  - コンテナ、Pod、Node、クラスター\n  - Dockerとの違い\n3. Kubernetesの主な特徴\n  - デプロイの自動化\n  - ハイブリッド / マルチクラウドに対応\n  - 拡張性とプラグインアーキテクチャ\n  - ローリングアップデートとロールバック\n  - 柔軟なスケーラビリティ\n  - リリース後のアプリケーション監視\n4. Kubernetesの利点とは\n  - 生産性の向上\n  - 自己修復機能により障害に耐性\n  - 高い可用性を担保\n  - オンプレミスでも、クラウドでも運用可能\n  - 大量のコンテナを一括管理\n  - DevSecOpsとの親和性が高い\n  - クラウドネイティブなワークロードを安全に保つ\n5. GitLabでKubernetesを統合する\n6. Kubernetes（K8s）のよくある質問\n  - KubernetesとDockerの違いは何ですか？\n  - Kubernetesで何ができますか？\n  - Kubernetesコンテナとは何ですか？\n  - Kubernetesの読み方は？\n\n## Kubernetesとは？その読み方と用途\n\nKubernetesは、「クバネティス」、「クーベネティス」、または「クーバネーティス」と発音します。ギリシャ語のκυβερνήτηςに由来し、「統治者」や「パイロット」といった意味を持ちます。また、K8sと表記されることもあります。  \n\nKubernetesは、一言で表せばソフトウェア開発においてコンテナを操作・管理するもので、コンテナオーケストレーションの役割を果たすオープンソースソフトウェアとして開発されました。Kubernetesは、クラウドネイティブのプログラムの開発に使用します。これを使用することで[マイクロサービス](https://about.gitlab.com/ja-jp/topics/microservices/)アーキテクチャが可能になり、プログラムの開発が高速化できます。  \nでは、Kubernetesについて、もう少し掘り下げて見ていきましょう。\n\n## Kubernetes（K8s）の基本用語解説\n\n### コンテナ、Pod、Node、クラスター\n\nKubernetesは、コンテナをオーケストレーションするためのツールです。オーケストレーションとは、複数のコンピュータシステムやアプリケーション、サービスなどを調整して管理し、頻繁に繰り返される大規模なワークフローやプロセスを実行できるようにすることを指します。では、コンテナとは何でしょう。ソフトウェア開発におけるコンテナ化とは、ソフトウェアのコードをライブラリやフレームワークなどの依存関係にあるすべてのコンポーネントとともにパッケージ化し、それぞれの入れ物、「コンテナ」に隔離することを意味します。コンテナは、完全に機能するポータブルなコンピューティング環境です。また、このコンテナを複数まとめたものがPod、PodをまとめたものがNode、Nodeをまとめたものがクラスタと呼ばれます（以下の図を参照）。\n\n![kubernetesとは](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687494/Blog/Content%20Images/kubernetes-diagram.svg)\n\n*Kubernetesにおけるコンテナとクラスタの関係を示した図*\n### Dockerとの違い\n\nKuberunetesはコンテナオーケストレーションツールですが、Dockerはコンテナ化ツールの1つです。Dockerはアプリケーションのコンテナ化を行なうとき使用するプラットフォームです。仮想マシンよりも軽量で高速であることや、環境構築が簡単なことから、コンテナ化の主流ツールになっています。\n\n## Kubernetesの主な特徴\n\nKubernetesは、前述したようにコンテナを管理するコンテナオーケストレーションツールで、代表的な機能としては次のようなものが挙げられます。\n\n### デプロイの自動化\n\nKubernetesは、アプリケーションのデプロイ時に、新しいコンテナの作成や既存コンテナの削除を自動で実施します。また、新しく作成したコンテナにも自動でリソースを適用します。\n\n### ハイブリッド / マルチクラウドに対応\n\nクラウドプロバイダーに依存することなく、オンプレミス環境や様々なクラウドサービス（AWS、Azureなど）上で動作します。よって、ハイブリッドクラウドやマルチクラウド環境を簡単に構築、管理することができます。\n\n### 拡張性とプラグインアーキテクチャ\n\n多様なプラグインや拡張機能が利用できます。例えば、CustomResourceDefinitions（CRD）を使って新規にリソースタイプやロジックを追加したり、CNI（Container Network Interface）やCSI（Container Storage Interface）といったプラグインでネットワークやストレージのカスタマイズが可能です。\n\n### ローリングアップデートとロールバック\n\nKubernetesでは、アプリケーションのバージョンを更新する際、ローリングアップデートがそのデフォルトとなります。また、ビルトインでロールバック機構もあります。このため、ライブトラフィックに影響を与えず、ダウンタイムゼロでデプロイを実現できます。\n\n### 柔軟なスケーラビリティ\n\nKubernetesは、大量のコンテナを効率的に管理するためのもので、システムのスケーラビリティが向上できます。スケーラビリティとは、どのくらいシステムの拡張ができるかを示す特性で、Kubernetesではコンテナ化されたアプリケーションの数を増減することでスケーリングします。\n\n### リリース後のアプリケーション監視\n\nPrometheusやGrafanaといった監視ツールを使用することで、アプリケーション固有のメトリクスが監視できます。リリース後のパフォーマンス低下や不具合発見といった事象がアラートされるため、問題に迅速に対処できます。\n\n## Kubernetesの利点とは\n\nKubernetesには次のような7つのメリットがあります。\n\n### 生産性の向上\n\n一つ目のメリットは、アプリケーション開発で生産性が向上できる点にあります。従来の仮想化では、アプリケーションごとにゲストOSを用意する必要がありましたが、Kubernetesでは、アプリケーションを直接コンテナエンジン上にデプロイできるため、サーバーのリソース使用量が抑えられます。\n\n### 自己修復機能により障害に耐性\n\nKubernetesには、PodやNodeに障害が起きた場合、最初の定義（マニフェスト）の状態まで自動修復する機能が備わっています。\n\n### 高い可用性を担保\n\nKubernetesは、複数のNodeの集まりであるクラスターを構成します。あるクラスターで障害が発生した場合、障害が起きたコンテナを自動で再起動させます。また、他のNodeでコンテナを起動させ、処理を引き継ぐ動作も継続できるため、高い可用性が担保できます。\n\n### オンプレミスでも、クラウドでも運用可能\n\nKubernetesは、オンプレミスでも、プライベートクラウド、パブリッククラウドでも利用できます。つまり、自社サーバーでも、クラウドを使っても、どんな環境でも運用可能です。\n\n### 大量のコンテナの一括管理\n\nKubernetesでは、大量のコンテナが一括で管理・運用できます。また、設定ファイルを複数のコンテナ間で共有することによって、設定変更時も正確かつ大量に設定を反映させることが可能です。\n\n### DevSecOpsとの親和性が高い\nDevSecOpsとは、開発と運用を統合するDevOpsにセキュリティを加え、運用を視野に入れながら開発とセキュリティを同時に進め、安心・安全なソフトウェアを迅速にリリースするというコンセプトです。Kubernetesにはアプリケーションの開発と運用の双方に必要とされる機能が多く搭載されているため、DevSecOpsとの親和性が非常に高いという特長があります。\n\n### クラウドネイティブなワークロードを安全に保つ\n\nKubernetesは、クラウドネイティブアーキテクチャに基づいており、クラウドネイティブな情報セキュリティに関するベストプラクティスについて、CNCF（Cloud Native Computing Foundation）からのアドバイスを活用しています。\n\nたとえばKubernetesには、APIやセキュリティコントロールが含まれており、情報セキュリティを管理するポリシーを定義する手段も備わっています。クラウドの利用などでセキュリティ面において懸念が生じても、Kubernetesならユーザーごとにアクセス制限を設定でき、不正アクセスが防止できるため安心です。\n\nまた、Pod Security Standardによりセキュリティに3つのポリシーが定義されています。非常に緩いものから非常に厳しいものまで累積的に定義できます。\n\n## GitLabでKubernetesを統合する\n\nKubernetesクラスターとGitLabを接続すると、アプリの開発・デプロイ・管理・監視ができます。  \nGitLabをKubernetesと連携させる、またはKubernetes内で動作させるには、3つの異なる方法があります。単独で使用することも、組み合わせて使用することもできます。\n\n* GitLabからKubernetesにソフトウェアをデプロイする  \n* Kubernetesを使用してGitLabインスタンスに紐づいたRunnerを管理する  \n* GitLabのアプリケーションとサービスをKubernetesクラスター上で実行する\n\nさらに詳しい情報やお問い合わせは[こちら](https://about.gitlab.com/ja-jp/solutions/kubernetes/)をご覧ください。\n\n## Kubernetes （K8s）のよくある質問\n\n### KubernetesとDockerの違いは何ですか？\n\nDockerはコンテナ化ツールのひとつで、アプリケーションコンテナを構築し、アプリケーションの開発・配布・実行をします。Kubernetesは、より大規模に複数のマイクロサービスを管理するのに使われます。  \nまた、Kubernetesはクラスターで実行され、Dockerはノードで実行されます。Kubernetesの使用目的はコンテナ管理ですが、Dockerの使用目的の一つは、アプリケーションをコンテナに分離することになります。\n\n### Kubernetesで何ができますか？\n\nKubernetesでできることの代表例には下記のようなものが挙げられます。\n\n* 大量のコンテナの一括管理\n* 起動を含めた動作の高速化・軽量化  \n* 自動デプロイ  \n* 自己修復機能により障害に耐性\n* 高い可用性を担保\n* オンプレミスでも、クラウドでも運用可能\n* DevSecOpsとの親和性が高い\n* クラウドネイティブなワークロードを安全に保つ\n\n### Kubernetesコンテナとは何ですか？\n\nソフトウェアのコードをライブラリやフレームワークなどの依存関係にあるすべてのコンポーネントとともにパッケージ化し、それぞれの入れ物、「コンテナ」に隔離することをコンテナ化と言います。Kubernetesコンテナは、完全に機能するポータブルなコンピューティング環境で、さまざまなプラットフォームでデプロイ可能なプログラムとして[マイクロサービス](https://about.gitlab.com/blog/what-are-the-benefits-of-a-microservices-architecture/)アーキテクチャを可能にします（リンクは英語版です）。\n\n### Kubernetesの読み方は？\n\nKubernetesは、「クバネティス」、「クーベネティス」、または「クーバネーティス」と読み、「K8s（ケーエイツ）」と略されます。\n",[811,762,677,111,535,812,723,680,682],"kubernetes","open source",{"slug":814,"featured":93,"template":684},"what-is-kubernetes","content:ja-jp:blog:what-is-kubernetes.yml","What Is Kubernetes","ja-jp/blog/what-is-kubernetes.yml","ja-jp/blog/what-is-kubernetes",{"_path":820,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":821,"content":827,"config":833,"_id":835,"_type":16,"title":836,"_source":18,"_file":837,"_stem":838,"_extension":21},"/ja-jp/blog/what-is-yaml",{"ogTitle":822,"schema":823,"ogImage":824,"ogDescription":825,"ogSiteName":776,"noIndex":6,"ogType":802,"ogUrl":826,"title":822,"canonicalUrls":826,"description":825},"拡張子YAMLファイルとは？基本から使い方まで徹底解説","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"拡張子YAMLファイルとは？基本から使い方まで徹底解説\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"GitLab Japan Team\"},{\"@type\":\"Person\",\"name\":\"GitLab\"}],\n        \"datePublished\": \"2025-04-09\",\n      }","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662547/Blog/Hero%20Images/what_is_yaml.jpg","YAMLは構成ファイル紹介などに使用されるフォーマットです。この記事では、YAMLの基本からKubernetesなどでの具体的な使い方まで解説します。","https://about.gitlab.com/blog/what-is-yaml",{"title":822,"description":825,"authors":828,"heroImage":824,"date":829,"body":830,"category":14,"tags":831},[806,807],"2025-04-09","## 目次\n\n* YAMLとは？\n* YAMLを何に使う？\n* YAMLとYMLの違いとは？\n* YAMLとJSONの違い\n* YAMLとCUEの比較\n* YAMLのデータ構造と書き方（基本編） \n* GitLabでYAMLを使う\n* 実際にYAMLファイルを編集してみましょう\n* YAMLに関するFAQ\n\nYAMLは、[Kubernetes](https://about.gitlab.com/ja-jp/blog/what-is-kubernetes/)ファイルやAnsibleプレイブックに使用されるデータシリアライゼーション・フォーマットです。この記事では、YAMLファイルの基本的な書き方や具体的な利用シーンについて詳しく解説します。\n\n## YAMLとは？\n\nYAMLは、人間がデータを簡潔かつ理解しやすく表現するよう設計されており、設定ファイルやデータ転送で頻繁に使用されるプログラミング言語です。階層的情報の整理に適し、Jsonやxmlの代替と利用されることがあります。\n\n## YAMLを何に使う？\n\nYAMLは可読性の高いこともあり、設定ファイルやプレイブックの記載に使われます。いくつか例を下記に記載しますので、参考にしてください。\n\n* 設定ファイルの記述  \n* ログファイル  \n* プロセス間でのメッセージのやり取り  \n* アプリケーション間でのデータ共有  \n* 構造化データの記述\n\n## YAMLとYMLの違いとは？\n\nどちらも同じ形式のファイルを指し、拡張子が「.yml」か「.yaml」という表記の違いだけです。ヤムルファイルであることを示す正式な拡張子は.yamlですが、一般的に拡張子（.txt, .zip, .exe, .png等）は3文字で記載されるので、この3文字ルールに合わせたのが.ymlとなっています。短く簡潔に書きたい開発者には「.yml」が選ばれることが多いです。\n\n## YAMLとJSON形式の違い\n\nJSON形式では中括弧を使って要件を定義していくのに対して、YAMLは、インデントで構造が明示されるので、可読性が高くなっています。下記サンプルを見比べてください。\\\nYAMLは、プログラマーにとっての使いやすさを重視していることがわかると思います。\n\nYAML：\\\n![yamlのキーとバリューの記載例](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687456/Blog/Content%20Images/yaml-coding-sample-01.png)\n\nJSON:\n\n![JSON形式のキーとバリューの記載例](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687456/Blog/Content%20Images/json-format-coding-sample-01.png)\n\n## YAMLとCUEの比較\n\nYAMLは、可読性が高くシンプルな構造を持つのに比べ、CUEは、スキーマとデータを統合するため、複雑な設定もひとつのファイルで管理できます。また、YAML単体では実現できなかったスキーマバリデーション機能を持つので、データの整合性を担保しやすいです。\n\nまた、柔軟性も大きな特徴です。CUEは、あらゆる種類のデータを定義、生成、検証するために使用される[オープンソース](https://about.gitlab.com/ja-jp/blog/what-is-open-source/)の言語（具体的にはJSONのスーパーセット）なので、Go、JSON、OpenAPI、Protocol Buffers、YAMLなどの他の多くの言語と連携できます。\n\nまた、Go APIによるスクリプト機能を備えているので、CUEによるマニフェストを最終的な[Kubernetes](https://about.gitlab.com/ja-jp/blog/what-is-kubernetes/)リソースのYAMLとして表示したり、特定クラスタにデプロイするリソースを一覧するコマンドを実装する際などに使う機会があります。\n\n## YAMLのデータ構造と書き方（基本編）\n\n### YAMLファイル記述の注意点\n\nインデントとタブが、とても重要であることを覚えておいてください。余分なインデントやタブが使われていると、YAMLオブジェクトの意味が変わってしまうので、これらがとても重要になります。\n\n### YAMLのデータ構造\n\nYAMLは主に、コレクションとスカラーという２つのデータで成り立っています。コレクションは、シーケンスとマッピングから成り立ちます。シーケンスは配列、マッピングは名前と値のペア（Key : Valueで表現する配列）。そしてスカラーは、型を判別させるためのもので、文字列、数値などを表します。\n\n* コレクション  \n\n  * シーケンス  \n  * マッピング  \n* スカラー\n\n### YAMLの書き方\n\n![image2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687456/Blog/Content%20Images/image2.png)\n\n* 複数行のコレクション：複数の行のフォーマットを維持する必要がある場合には | (バーティカルバー) シンボルを使用します。  \n* 複数行のフォーマット：長い文字列の値があり、フォーマットを維持したまま複数行に渡って記述する必要がある場合には、 > を使用します。  \n* リスト：リストは - （ハイフン）を使って表現します。  \n* ネスト：ネストされたデータ構造はインデントを使って表現されます。\n\n### Kubernetes（k8s)のYAMLファイルの書き方\n\nKubernetesでは、リソースの定義にYAMLファイルが使用されます。今回はYAMLマニフェストの書き方を紹介します。  \n\nYAMLマニフェスト：\\\n![YAMLでKubernetesのマニフェストの書き方例](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687456/Blog/Content%20Images/YAML-manufest-sample-Kubernetes.png)\n\n### AnsibleのYAMLファイルの書き方\n\nAnsibleでは、処理内容を記載するプレイブックをYAMLで記載します。以下に、簡単なAnsibleプレイブックの例を示します。\n\n![image3](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687457/Blog/Content%20Images/image3.png)\n\n## GitLabでYAMLを使う\n\nGitLab CI/CD パイプラインは、プロジェクト毎に[.gitlab-ci.yml](https://docs.gitlab.com/ee/ci/examples/index.html)というYAMLファイルを使って[パイプラインの構造と実行順序を定義](https://gitlab.com/stylez-co-jp/gitlab-ce/-/blob/dev-v12.0.3-ja.1/doc-ja/ci/yaml/README.md)します。このファイルで設定された内容を、GitLab Runnerの中で処理します。CI/CD YAML構文については[こちらの英文まとめページ](https://docs.gitlab.com/ee/ci/yaml/)をご参照ください。\n\n## 実際にYAMLファイルを編集してみましょう\n\nYAMLは、そのシンプルさと可読性の高さから、設定ファイル、CI/CDパイプライン、Kubernetesをはじめとするコンテナオーケストレーションやドキュメント、構成管理など、多岐にわたり利用されています。その可読性の高さで、開発者や運用エンジニアが構成やデータを容易に管理し、効率的に作業を進めることができます。YAMLを理解することで、様々なシステムやツールの設定がより簡単かつ直感的に行えるようになるでしょう。\n\n## YAMLに関するFAQ\n\n### YAMLは何に使われますか\n\nYAMLは、そのシンプルさと可読性の高さから、設定ファイル、CI/CDパイプライン、Kubernetesをはじめとするコンテナオーケストレーションやドキュメントと構成管理など、多岐にわたり利用されています。\n\n### YAMLとJSONの違いは？\n\nJSONファイルは中括弧を使って要件を定義していくのに対して、YAMLは、インデントで構造が明示されるので、可読性が高くなっています。ただし、YAMLではインデントやスペースがとても重要になる点に注意が必要です。\n\n### YAMLはなぜ人気なのですか？\n\nYAMLは開発者の間で人気のあるデータシリアライズ言語です。なぜなら、その読みやすさ、汎用性、Pythonと似たインデントシステムを使うからです。YAMLは複数のデータ型をサポートしており、多くのプログラミング言語で利用可能なパーサーライブラリが提供されているため、さまざまなデータシリアライゼーションタスクを扱うことができ、幅広い場面で活用されています。\n\n\u003Cbr>\u003Cbr>\n\n*監修：佐々木 直晴 [@naosasaki](https://gitlab.com/naosasaki) （GitLab合同会社 ソリューションアーキテクト本部 シニアソリューションアーキテクト）*",[677,811,678,111,535,762,681,682,812,832],"git",{"slug":834,"featured":93,"template":684},"what-is-yaml","content:ja-jp:blog:what-is-yaml.yml","What Is Yaml","ja-jp/blog/what-is-yaml.yml","ja-jp/blog/what-is-yaml",{"_path":840,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":841,"content":847,"config":853,"_id":855,"_type":16,"title":856,"_source":18,"_file":857,"_stem":858,"_extension":21},"/ja-jp/blog/what-is-agile-development",{"title":842,"description":843,"ogTitle":842,"ogDescription":843,"noIndex":6,"ogImage":844,"ogUrl":845,"ogSiteName":776,"ogType":802,"canonicalUrls":845,"schema":846},"アジャイル開発とは？意味や進め方、DevSecOpsとの関係性を解説","この記事では、アジャイル開発の概要やウォーターフォール開発との違い、導入するメリット・デメリットなどを解説します。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663632/Blog/Hero%20Images/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E9%96%8B%E7%99%BA7.jpg","https://about.gitlab.com/blog/what-is-agile-development","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"アジャイル開発とは？意味や進め方、DevSecOpsとの関係性を解説\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"GitLab Japan Team\"},{\"@type\":\"Person\",\"name\":\"GitLab\"}],\n        \"datePublished\": \"2025-03-06\",\n      }",{"title":842,"description":843,"authors":848,"heroImage":844,"date":849,"body":850,"category":14,"tags":851},[806,807],"2025-03-06","アジャイル開発はシステム・ソフトウェア開発手法のひとつであり、近年注目されています。実際に自社の開発課題を解決するために、アジャイル開発の導入を検討している担当者は多いのではないでしょうか。\n\nこの記事では、アジャイル開発の概要やウォーターフォール開発との違い、導入するメリット・デメリットなどを解説します。アジャイル開発におけるAI活用や、[DevSecOps](https://about.gitlab.com/ja-jp/topics/devsecops/)の関係性についても触れているのでぜひ参考にして下さい。\n\n## アジャイル開発とは？\n\n![アジャイル開発2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687637/Blog/Content%20Images/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E9%96%8B%E7%99%BA2.jpg)\n\nアジャイル開発とは、ソフトウェア開発において通常1週間から4週間程度の反復期間を設定し、企画から開発、テストまでの工程を機能単位ごとに繰り返し進めていく開発手法のことです。「アジャイル」という言葉には、「素早い」「機敏な」という意味があり、その言葉の通りアジャイル開発はスピード感のある開発が可能です。\n\n近年ビジネス環境の変化が激しく、日々変化するニーズや市場に柔軟に対応していく姿勢が必要です。アジャイル開発ならスピード感を持って開発を進められるだけでなく、仮説検証を含めた柔軟な開発が可能になります。\n\n物事の予測が立てにくい不確実な要素が多い時代の中で、顧客ニーズにマッチした新しい価値を創造するための手法としてアジャイル開発が注目されているのです。\n\n## アジャイルソフトウェア開発宣言とは？\n\n「アジャイルソフトウェア開発宣言」とは、17名のソフトウェア開発者が議論を行なって文書としてまとめたアジャイル開発の原則のことです。\n\n2001年に公開されたことをきっかけに、世界中にアジャイル開発の考え方が広まり、多くのソフトウェア開発者達に支持されました。\n\nアジャイルソフトウェア宣言では、アジャイル開発を実現するために以下の4つの価値を示しています。\n\n1. プロセスやツールよりも「個人と対話」  \n2. 包括的なドキュメントよりも「動くソフトウェア」  \n3. 契約交渉よりも「顧客との協調」  \n4. 計画に従うことよりも「変化への対応」\n\n※出典：[アジャイルソフトウェア開発宣言](https://agilemanifesto.org/iso/ja/manifesto.html)\n\n## アジャイル開発とウォーターフォール開発との違い・比較\n\n![アジャイル開発5](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687637/Blog/Content%20Images/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E9%96%8B%E7%99%BA5.jpg)\nアジャイル開発が登場する前にはウォーターフォール開発が主に活用されており、ソフトウェア開発の初期段階として位置付けられています。\n\nウォーターフォール開発は機能単位ごとに開発工程を繰り返すアジャイル開発とは異なり、開発前に全ての機能計画を立て、その計画通りに開発を進める手法になります。つまり、要件定義から設計、実装、テスト、運用といった各工程を順序立てて直線的に開発を進めていきます。\n\n開発対象の機能を事前に決定して開発を進めるため、最終的なリリース時期がわかりやすいというメリットがあります。一方、開発前から全ての工程が決まっているため、仕様変更がしにくいなどの課題もあります。\n\n## アジャイル開発でよく採用されている手法とは？\n\nアジャイル開発にはさまざまな開発手法がありますが、中でも「スクラム」と呼ばれる開発手法が最も採用されています。スクラムとは、少人数のチームにわかれて密にコミュニケーションをとりながら開発を進める手法です。\n\n実際に「[17th State of Agile Report](https://digital.ai/resource-center/analyst-reports/state-of-agile-report/)」の調査では、アジャイル開発手法の中で、63%がスクラムを採用していると報告されています。なお、スクラムの人気は2006年の最初の調査以降続いています。\n\nなぜ数ある開発手法の中でスクラムが最も採用されるのでしょうか。理由のひとつとして汎用性の高さにあると考えられます。スクラムはシンプルなフレームワークであり、さまざまな開発プロジェクトに活用することが可能です。\n\nまた、スクラムのルールが示された「[スクラムガイド](https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-Japanese.pdf)」は、18ページ程度の少なめのボリューム感となっており、内容もシンプルです。そのため、スクラムの全体の流れや仕組みについて理解がしやすく、自社の開発プロジェクトに合わせて応用がしやすいといえます。\n\nさらに、スクラムは有名な手法であることから開発事例も多く、情報収集が容易であるという事情も採用される理由として挙げられます。\n\n## アジャイル開発の流れ\n\nアジャイル開発はどのような流れで進められるでしょうか。IPAの「[アジャイル開発の進め方](https://www.ipa.go.jp/jinzai/skill-standard/plus-it-ui/itssplus/ps6vr70000001i7c-att/000065606.pdf)」を参考にスクラムを例に全体の流れを紹介します。\n\n1. プロダクトバックログの作成  \n2. スプリントプランニングの実施  \n3. 開発作業の実施\n\n### 1. プロダクトバックログの作成\n\nまずプロダクトバックログの作成を行います。プロダクトバックログとは、開発したいプロダクトが提供する価値をまとめたリストのことです。具体的には、顧客が求める機能やユーザーエクスペリエンスなどを洗い出してリストを作成していきます。\n\nこの際、リストは作業の優先順位をつけて並んでいることがポイントです。また、作成するリストは顧客を含むプロジェクトの関係者全員に共有する必要があるため、誰もが理解できる言葉で記載しなければなりません。\n\n### 2. スプリントプランニングの実施\n\n「スプリント」とは、スクラムにおける開発工程の反復（作業）期間のことです。スプリントが開始される前にスプリントプランニングを実施しましょう。具体的には、作成したプロダクトバックログのリストの中から対象のスプリントで扱う項目を選び出します。ここで選び出した項目は「スプリントバックログ」と呼ばれます。\n\nその後細かにタスクに落とし込み、スクラムチーム内で作業を分担します。なお、各タスクにおいては一般的に2〜8時間程度の時間単位で見積もられます。\n\n### 3. 開発作業の実施\n\n実際にスプリント内の開発作業を実施します。スプリントの途中では、スクラムチーム内で活動状況を報告する「デイリースクラム」が行われます。デイリースクラムは、達成すべきゴールに向けて課題になっていることを共有し、チーム全員が協力して解決を目指すためのミーティングです。\n\n無事にスプリントが完了した段階では「スプリントレビュー」と呼ばれるミーティングが開催され、関係者全員で完成したプロダクトのデモンストレーションを行います。\n\nまた、スプリントレビューの後には「スプリントレトロスペクティブ」が行われ、開発におけるプロセスを振り返ります。うまくいかなかったことは改善策を洗い出し、次のスプリントに活かします。\n\n## アジャイル開発のメリット\n\n![アジャイル開発6](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687637/Blog/Content%20Images/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E9%96%8B%E7%99%BA6.jpg)\nアジャイル開発には以下のようなメリットがあります。\n\n* 開発スピードが早い  \n* ユーザーのニーズを反映しやすい  \n* 手戻りの発生を防止・軽減しやすい  \n* 継続的な学習と改善の機会が得られる\n\n### 開発スピードが早い\n\nアジャイル開発は機能を小さな単位にわけて開発とリリースを繰り返して進めるため、結果的に優先度の高い機能から素早く価値を提供することが可能です。また、最初にプロダクトの全ての機能計画を立ててから開発するわけではないため、本来不要だった機能に関するドキュメント作成などに時間と手間をかけずに開発を進められます。\n\n一方、ウォーターフォール開発の場合は計画を重視することから、開発前に要件定義書や設計書などの作成に時間をかける必要があります。ビジネスにおいて「競合優位性を確立したい」「早期に顧客のフィードバックを収集したい」などの目的があるなら、小さな単位で素早く価値を提供できるアジャイル開発の採用が適切だといえます。\n\n### ユーザーのニーズを反映しやすい\n\nアジャイル開発は小さな単位で開発を進めるため、開発途中で顧客の要望や市場の変化に応じて優先順位や仕様を見直すことができます。顧客ニーズや市場調査の結果を踏まえながら柔軟に開発を進めることで最大限の価値を提供できるため、顧客満足度の向上にもつながります。\n\n一方、ウォーターフォール開発ではプロジェクトの初期段階で計画を確定させるため、途中での変更が困難になりがちです。ただし、アジャイル開発で変更に対応できるといっても、変更自体のコストや影響度は慎重に評価する必要があります。\n\n例えば、すでに開発した機能に大きな変更が必要な場合は、再設計や再実装のコストが発生します。アジャイル開発は変更を受け入れやすい仕組みを持っていますが、それは全ての変更が容易であることを意味するわけではありません。\n\n### 手戻りの発生を防止・軽減しやすい\n\nアジャイル開発は機能単位に区切って開発からテスト、リリースまで実行するため、テストの段階で不具合や問題が発生した場合でも手戻りの工数を最小限に抑えられます。\n\nウォーターフォール開発の場合は、事前に決めた計画通りに開発を進めるため、不具合が発生した箇所によっては手戻りの工数が大きくなってしまうデメリットがあります。アジャイル開発なら、前提として開発している範囲が少ないため、大きな手戻りが発生しにくいです。\n\n### 継続的な学習と改善の機会が得られる\n\nアジャイル開発では、小さな単位での開発を繰り返し、振り返りを行うプロセスが組み込まれています。これにより、チームは実践と改善を重ねながら学習を進める機会を得られます。例えば、スプリントごとの振り返り（スプリントレトロスペクティブ）では、うまくいったことや課題を議論し、より良い進め方を模索します。\n\nまた、開発途中では毎日ミーティングが実施され、品質の高いプロダクトを生み出せるようメンバー同士が意見を出し合います。そのようなプロセスを通してチームワークの向上も期待できるでしょう。\n\n## アジャイル開発のデメリット\n\n![アジャイル開発4](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687637/Blog/Content%20Images/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E9%96%8B%E7%99%BA4.jpg)\nアジャイル開発にはデメリットもあるため、対策を踏まえて把握しておくことが大切です。\n\n* 長期的な見通しの立て方が従来と異なる  \n* プロダクトの方向性を維持するための工夫が必要\n\n### 長期的な見通しの立て方が従来と異なる\n\nアジャイル開発では、詳細な計画を前もって確定させない代わりに、反復的な開発を通じて計画を継続的に見直し、調整していきます。そのため、従来のウォーターフォール型開発のように、プロジェクト全体の詳細なスケジュールを初期段階で確定することは難しくなります。また、顧客の要望で何度も仕様変更が発生した場合、最終リリースまでのスケジュールが伸びてしまう可能性もあります。\n\nアジャイル開発において適切なスケジュール管理を行うためには、チームの開発速度を計測、定期的に計画と実績を比較し、場合によっては優先順位や計画を見直す必要があります。\n\n### プロダクトの方向性を維持するための工夫が必要\n\nアジャイル開発では、開発途中での変更を受け入れやすい特徴がある一方で、その柔軟性を適切にコントロールしなければ、本来目指していたプロダクトの方向性から逸れてしまうリスクがあります。\n\n例えば、顧客からの仕様変更や機能追加の要望を受け入れ過ぎていると、プロジェクト全体の方向性を見失ってしまう場合があります。また、顧客との摩擦や齟齬が生まれてしまう可能性もあり、プロジェクトがスムーズに進まないという事態も招いてしまうでしょう。\n\nこのようなことを避けるためには、個々の単位だけでなく定期的な全体像の把握と、関係性全員での認識の擦り合わせが必要です。\n\n## アジャイル開発が向いている・向いていないプロジェクト\n\nアジャイル開発にはさまざまなメリットがありますが、プロジェクトの特性・内容によっては向き・不向きがあるため事前に把握し、自社に適した開発手法を採用しなければなりません。\n\nアジャイル開発は柔軟に開発を進められるメリットがあるため、ニーズが漠然としていたり、状況の変化が想定されていたりするケースに向いています。また、発注者が積極的に関わる案件なら、頻繁にフィードバックを受けやすいアジャイル開発の強みを十分に活かせるでしょう。\n\n反対に、要件が明確で大きな変更が想定されず、納期の厳守を求められる場合は、アジャイル開発の採用には慎重な検討が必要といえます。また、開発メンバーと発注者との間でコミュニケーションがとりにくいケースでアジャイル開発を採用しても、開発がスムーズに進まない可能性が高いため別の手法を検討するのが良いでしょう。\n\n## アジャイル開発を成功させるためのポイント\n![アジャイル開発8](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687637/Blog/Content%20Images/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E9%96%8B%E7%99%BA8.jpg)\n\nアジャイル開発を成功させるために以下のポイントを押さえておきましょう。\n\n* アジャイル開発の特性を理解した人材を選定する  \n* メンバー間で密にコミュニケーションをとる  \n* [CI/CD](https://about.gitlab.com/ja-jp/blog/what-is-ci-cd/)など自動化のテクノロジーを取り入れる  \n* 情報の透明性を保つ\n\n### アジャイル開発の特性を理解した人材を選定する\n\nアジャイル開発では、柔軟な仕様変更に伴うメンバー間での擦り合わせや協力が重要となります。必ずしもアジャイル開発の経験が豊富である必要はありませんが、ここまで紹介してきたようなアジャイル開発の特徴を理解し、オープンな姿勢でチームや関係者とコミュニケーションを取れる人材が求められます。\n\n「プロダクトオーナー」や開発チームを支援する「スクラムマスター」の役割も重要です。場合によってはアジャイルコーチによるトレーニングを活用したり、経験豊富な外部の専門家にサポートを依頼したりすることも有効です。\n\n### メンバー間で密にコミュニケーションをとる\n\nアジャイル開発を成功に導くためには、顧客を含めた関係者全員がコミュニケーションを密にとっていくことが大切です。先ほど説明したような「デイリースクラム」や「スプリントレビュー」などのミーティングを定期的に実施し、メンバー間でのコミュニケーションを活性化させましょう。\n\nチームメンバーが自由に意見を出しやすい雰囲気の中で開発を進めることで、進捗管理や品質の維持もしやすくなります。特に上下関係などの関係性を取り払って、お互いが率直に提案や指摘をし合えるような環境ならプロジェクトの成功率をより高められるでしょう。\n\n### CI/CDなど自動化のテクノロジーを取り入れる\n\nアジャイル開発をスムーズに進めるためには、[CI/CD](https://about.gitlab.com/ja-jp/blog/what-is-ci-cd/)など自動化のテクノロジーを取り入れることもポイントです。[CI/CD](https://about.gitlab.com/ja-jp/blog/what-is-ci-cd/)とは、顧客にプロダクトを素早く提供するために、ビルド作業やテスト、リリースの工程といった、開発フローの一部を自動化する手法のことです。\n\nアジャイル開発と[CI/CD](https://about.gitlab.com/ja-jp/blog/what-is-ci-cd/)の相性は良く、機能単位ごとの開発フローを[CI/CD](https://about.gitlab.com/ja-jp/blog/what-is-ci-cd/)によって自動化することによって、一定の品質を維持したままリリース頻度の向上を実現できます。[CI/CD](https://about.gitlab.com/ja-jp/blog/what-is-ci-cd/)については以下の記事で解説しているので、併せてチェックしてみてください。\n\n[CI/CDとは？意味や導入のメリット・デメリット、ツールの選び方を解説](https://about.gitlab.com/ja-jp/blog/what-is-ci-cd/)\n\n### 情報の透明性を保つ\n\nアジャイル開発においてはチームメンバーと顧客との間で信頼関係を構築することが求められます。顧客側が開発の中でどのようなことが行われているのかが把握できないと不安を抱いてしまいます。例えば、成果物が納品されるまで状況を掴めないような進め方だと、認識の齟齬が生まれる原因になるでしょう。\n\nそのため、アジャイル開発で扱う情報においては常に透明性をもたせることが大事です。\n\n例えば、以下のような情報に透明性をもたせて、顧客とチームメンバーとの間でスムーズに情報共有できるような仕組みを構築しておきましょう。\n\n* 全体の開発スケジュール  \n* 開発の作業内容  \n* 開発メンバーの保有スキル  \n* 開発の進捗状況 など\n\n情報の透明性を保ち、チームの誰でも同じ情報にアクセスできる状態のことをSingle Source Of Truth（SSOT、信頼できる唯一の情報源）と呼び、これがあることでチームの自律的な行動を促すことができます。こちらに関する記事は下記が詳しいため、併せてチェックしてみてください。\n\n[組織の自律自走を促すコミュニケーション](https://learn.gitlab.com/c/effective-communication-for-autonomous-organization-deck?x=JBqxmQ)\n\n## アジャイル開発におけるセキュリティの課題\n\nアジャイル開発では、仕様変更や機能追加などに対して柔軟に対応でき、スピード感を持って開発を進められます。その一方で、セキュリティが後回しにされたり、おろそかにしてしまったりするケースも多いといわれています。この課題に対応するには、リリース直前に実施される人手による脆弱性診断やペネトレーションテストだけでなく、静的解析ツールやコンテナスキャンなどの自動化されたセキュリティテストを[CI/CD](https://about.gitlab.com/ja-jp/blog/what-is-ci-cd/)パイプラインに組み込むことが効果的です。\n\nなお、セキュリティ対策の重要性はアジャイル開発に限ったことではありません。[IPAの調査](https://www.ipa.go.jp/security/10threats/10threats2024.html)から近年組織ではさまざまなセキュリティインシデントが発生していることがわかります。開発の早い段階でセキュリティ上の問題を発見し、迅速な対応が可能になるこれらのプラクティスは「シフトレフト」と呼ばれ、セキュリティリスクをより早い段階で見つけ、手戻りを少なく品質をあげていく手法として、アジャイル開発以外での開発手法でも重要であると言われています。\n\n## アジャイル開発におけるAI活用について\n![アジャイル開発1](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687637/Blog/Content%20Images/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E9%96%8B%E7%99%BA1.jpg)\n\nアジャイル開発を採用する際には、AIを積極的に活用する視点も持っておきましょう。\n\n例えば、前述の通り、アジャイル開発ではリリース直前での脆弱性診断だけでなく、開発段階などでも常時セキュリティスキャンなどで脆弱性を検出することが重要です。この時に[GitLab Duo](https://about.gitlab.com/ja-jp/gitlab-duo/)のようなAIを活用することによってソフトウェアの脆弱性をより効率的に把握して修正でき、開発におけるセキュリティリスクを軽減することができます。\n\nその他にも、テストコードを書いたり、ソースコードからドキュメントから詳細設計書やパラメータシート相当のものを作成するなど、特にアジャイル開発でよく行われることにAIの支援を受けることができ、開発効率の向上を実現することができます。\n\nこれらの機能のデモもありますので、参考にしていただければと思います。\n\n\u003Ciframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/jygdsxzBC4Y?si=k6NWiV2Jc29fS0Uu\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen>\u003C/iframe>\n\n## アジャイル開発とDevSecOpsの関係性\n\n先ほど挙げたアジャイル開発のセキュリティの課題においては「[DevSecOps](https://about.gitlab.com/ja-jp/topics/devsecops/)」の必要性が高まっています。\n\n[DevSecOps](https://about.gitlab.com/ja-jp/topics/devsecops/)とは、開発（Dev）・セキュリティ（Sec）・運用（Ops）を連携した開発アプローチのことです。[DevSecOps](https://about.gitlab.com/ja-jp/topics/devsecops/)では、セキュリティを後回しにすることなく、開発工程（Dev）の段階で対策を行い、ソフトウェアの安全性を高めます。\n\nアジャイル開発と[DevSecOps](https://about.gitlab.com/ja-jp/topics/devsecops/)は親和性が高く、両者とも迅速なリリースと継続的な改善を推進する手法や考え方です。つまり、アジャイル開発において[DevSecOps](https://about.gitlab.com/ja-jp/topics/devsecops/)のアプローチも取り入れることで、セキュリティレベルを高めながら、迅速なソフトウェア開発を実現できます。補足として、アジャイル開発と同様、ウォーターフォール開発でもDevSecOpsの考え方は積極的に取り入れるべきポイントです。\n\nなお、「[GitLab](https://about.gitlab.com/ja-jp/)」なら[DevSecOps](https://about.gitlab.com/ja-jp/topics/devsecops/)のアプローチを踏まえたソフトウェア開発が可能です。アジャイル開発の代表的手法である「スクラム」を1つのプラットフォームで運用することもできるため、ぜひ自社のプロジェクトにお役立て下さい。\n\n## アジャイル開発に関するQ＆A\n![アジャイル開発3](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687637/Blog/Content%20Images/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E9%96%8B%E7%99%BA3.jpg)\n最後にアジャイル開発に関するQ＆Aを紹介します。\n\n### アジャイル開発の普及率は？\n\n「[DX白書2023](https://www.ipa.go.jp/publish/wp-dx/gmcbt8000000botk-att/000108041.pdf)」によると、アジャイル開発を「全社的に活用している」「事業部で活用している」と回答した企業の割合の合計は22.9%となっています。米国の場合は53.9%となっているため、アジャイル開発の普及率において日米差は大きいことがわかります。\n\n### アジャイル開発が失敗する原因は？\n\nアジャイル開発が失敗してしまう原因はさまざまですが、主に以下が挙げられます。\n\n* アジャイル開発に不向きなプロジェクトで採用している  \n* 顧客とチームメンバーとの間でコミュニケーションが不足している  \n* プロダクトオーナーやスクラムマスターが役割を果たせていない \n\nそもそもアジャイル開発に向いていないようなプロジェクトで採用してしまうと、アジャイル開発の強みを活かせず失敗してしまう可能性が高まります。その他、関係者間でのコミュニケーション不足が発生していたりする場合、開発の方向性が大きくブレたりなどの事態を招く原因となるでしょう。\n\n## アジャイル開発の特徴を十分に理解して自社で導入しよう\n\nアジャイル開発なら、開発途中で発生する急な仕様変更にも柔軟に対応でき、顧客ニーズにマッチした価値を提供することが可能です。\n\nしかし、アジャイル開発に限ったことではないですがセキュリティ対策における課題もあるため、[DevSecOps](https://about.gitlab.com/ja-jp/topics/devsecops/)のアプローチも積極的に取り入れていく姿勢も求められます。\n\n[DevSecOps](https://about.gitlab.com/ja-jp/topics/devsecops/)プラットフォームを提供する[GitLab](https://about.gitlab.com/ja-jp/)では、世界39か国、5,000人を超えるDevSecOps専門家のインサイトが詰まった完全版レポートを無料で公開しています。ソフトウェア開発におけるAI活用や、[DevSecOps](https://about.gitlab.com/ja-jp/topics/devsecops/)に興味がある人はぜひご覧下さい。\n\n> [2024グローバルDevSecOpsレポートはこちら](https://about.gitlab.com/ja-jp/developer-survey/?utm_medium=blog&utm_source=blog&utm_campaign=eg_apac_brand_x_x_ja_gitlabjapanblogseo_what-is-agile-development)  \n\n*監修：佐々木 直晴 [@naosasaki](https://gitlab.com/naosasaki) （GitLab合同会社 ソリューションアーキテクト本部 シニアソリューションアーキテクト）*",[852],"agile",{"slug":854,"featured":93,"template":684},"what-is-agile-development","content:ja-jp:blog:what-is-agile-development.yml","What Is Agile Development","ja-jp/blog/what-is-agile-development.yml","ja-jp/blog/what-is-agile-development",{"_path":860,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":861,"content":867,"config":872,"_id":874,"_type":16,"title":875,"_source":18,"_file":876,"_stem":877,"_extension":21},"/ja-jp/blog/what-is-ci-cd",{"title":862,"description":863,"ogTitle":862,"ogDescription":863,"noIndex":6,"ogImage":864,"ogUrl":865,"ogSiteName":776,"ogType":802,"canonicalUrls":865,"schema":866},"CI/CDとは？意味や導入のメリット・デメリット、ツールの選び方を解説","この記事では、CI/CDの概要や導入するメリット、CI/CDツールの選び方などを詳しく解説します。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663328/Blog/Hero%20Images/cicd3.jpg","https://about.gitlab.com/blog/what-is-ci-cd","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"CI/CDとは？意味や導入のメリット・デメリット、ツールの選び方を解説\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"GitLab Japan Team\"},{\"@type\":\"Person\",\"name\":\"GitLab\"}],\n        \"datePublished\": \"2025-03-03\",\n      }",{"title":862,"description":863,"authors":868,"heroImage":864,"date":869,"body":870,"category":14,"tags":871},[806,807],"2025-03-03","ソフトウェア開発においては、顧客に最大限の価値を提供するためにリリース後も繰り返し改善を行なっていくことが求められます。そのプロセスを効率化するために活用できるのが「CI/CD」です。\n\n実際に開発の効率化のための手段のひとつとしてCI/CDの採用を検討している担当者もいるのではないでしょうか。この記事では、CI/CDの概要や導入するメリット、CI/CDツールの選び方などを詳しく解説します。\n\n## CI/CDとは？\n![cicd1](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687600/Blog/Content%20Images/cicd1.jpg)\n\nCI/CDとは、ソフトウェア開発におけるビルドやテスト、デプロイなど、従来であれば手作業で介入する必要があったプロセスを自動化して、素早くプロダクトをリリースする手法のことです。\n\n「Continuous Integration」と「Continuous Delivery」の略称であり、日本語で直訳すると「継続的インテグレーション／継続的デリバリー」となります。\n\n## CIとCDの違い\n\nでは、CIとCDではどのような違いがあるのかそれぞれ意味を解説していきます。\n\n### CI （継続的インテグレーション）\n\nCI （継続的インテグレーション）は、ソフトウェア開発において自動ビルドとテストを繰り返し実行することを示します。\n\n複数の開発者が修正したソースコードを頻繁に統合して、不具合がないか確認するためのプロセスです。このプロセスを繰り返し自動的に実行することで、プログラムのバグを早期に発見・改善でき開発を効率よく進められます。\n\n### CD（継続的デリバリー）\n\nCDとは、「継続的デリバリー」という言葉の通り、CIで検証されたソフトウェアを顧客に対して継続的に公開できる仕組みをつくることです。\n\nCIのプロセスにおいて自動ビルドやテストが実行された後に、ステージング環境やテスト環境などに成果物をデプロイし、さらにセキュリティテストや負荷テストなどを実施します。\n\n最終的な本番環境へのデプロイについては手動で承認する形で行い、ボタンをクリックするだけで反映することができます。\n\n### CD（継続的デプロイメント）\n\nCDには、継続的デリバリーの他にも「継続的デプロイメント」の意味もあります。継続的デプロイメントとは、全てのソースコードの変更が自動的に本番環境に反映される仕組みのことです。\n\n継続的デリバリーと継続的デプロイメントの違いは、手動で本番環境にリリースするか自動で行うかという点です。\n\n## CI/CDパイプラインとは？\n\nCI/CDパイプラインとは、ソースコードの変更からテスト、本番環境へのデプロイまでの一連の流れを自動化したプロセスを指します。つまり、CIとCDの両者を組み合わせた仕組みのことです。\n\nCI/CDパイプラインを構築することで、ソフトウェア開発における各工程の連携がスムーズになり、ビルドやテストの工数削減や迅速なリリースを実現できます。\n\n## CI/CDの導入が必要とされる背景とDevSecOps・アジャイル開発との関係性\n![cicd4](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687600/Blog/Content%20Images/cicd4.jpg)\n\nCI/CDの導入がなぜソフトウェア開発の現場で必要とされているのでしょうか。CI/CDと[DevSecOps](https://about.gitlab.com/ja-jp/topics/devsecops/)・アジャイル開発との関係性を踏まえながら解説します。\n\n### CI/CDが必要とされる背景\n\n現代は「Society 5.0時代」と呼ばれており、IT技術の発展と進化に伴い多様なシステムを活用して社会を豊かにするという考え方が重要視されています。ビジネスの場においてもテクノロジーの急激な進化に伴い、多くのサービスが生まれる中で企業間での競争が激化しています。\n\nそうした競争に打ち勝っていくためには、変化に柔軟かつ迅速に対応できる開発環境を構築しなければなりません。CI/CDなら一定の品質を維持したうえで開発プロセスを自動化でき、変化に対応しながら迅速にソフトウェアを顧客に届けることが可能です。\n\nこの品質とスピードの両方の課題を解決できるという強みが、ソフトウェア開発の領域においてCI/CDが注目されている理由だといえます。\n\n### DevSecOps・アジャイル開発との関係性\n\nCI/CDは、[DevSecOps](https://about.gitlab.com/ja-jp/topics/devsecops/)やアジャイル開発との相性が良い開発手法であり、これらの手法が主流となってきていることも注目される理由のひとつです。つまり、CI/CDは[DevSecOps](https://about.gitlab.com/ja-jp/topics/devsecops/)とアジャイル開発を効果的に実現するための重要な要素として位置付けられています。\n\n例えば、アジャイル開発ではスピード感を持って機能をリリースしていくことが求められます。しかし、リリースを頻繁に繰り返すというプロセスは、毎回テストの実施などにおいて  \n開発者の負担が増大してしまうことを意味します。また、[DevSecOps](https://about.gitlab.com/ja-jp/topics/devsecops/)でいう「セキュリティのシフトレフト」という観点でも、コーディング直後にセキュリティスキャンを実施し、見つかったセキュリティ脆弱性を記憶が鮮明なうちに修正する、という先進的な取り組みにおいても、CI/CDは極めて重要な役割を担います。\n\nCI/CDを導入すれば開発プロセスを自動化できるため、アジャイル開発の強みを活かしながらコスト削減と品質の維持、安全なソフトウェア・サービス開発を実現することが可能です。\n\n## CI/CD導入のメリット\n![cicd2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687600/Blog/Content%20Images/cicd2.jpg)\n\n既に触れている内容でもありますが、改めてCI/CD導入のメリットについて把握しておきましょう。\n\n* 開発スピードを加速化できる  \n* 生産性と品質の向上が期待できる  \n* バグを早期に発見できる\n\n### 開発スピードを加速化できる\n\nCI/CDを導入することで、ソフトウェア開発からリリースまでの時間を短縮できます。\n\nソースコードを変更した後にはビルドやテスト、デプロイなどさまざまな工程を踏む必要があり、これらを全て手作業で行うとかなりの時間を要します。CI/CDなら手動での作業を自動化できるため、迅速に顧客のソフトウェアを提供することが可能です。\n\n### 生産性と品質の向上が期待できる\n\nCI/CDを導入すればテストからリリースまでの工程を自動化できるため、業務負担の削減につながります。これによって手動で作業していた分の時間をより重要なタスクに割くことが可能になり、生産性向上にも寄与するでしょう。\n\n例えば、プロダクトの品質向上に向けた施策立案や、顧客ニーズや市場の変化を踏まえた仕様変更や機能追加などの重要な業務に注力できるようになります。\n\n### バグを早期に発見できる\n\nCI/CD活用によってテスト工程が自動化されることから、頻繁にテストを実施できるようになります。先ほども触れたようにアジャイル開発の場合は頻繁にテストを繰り返す必要があるため、CI/CDの強みを活かすことでバグを早期に発見できます。\n\n早い段階でバグを発見してその都度修正を実施すれば、機能全体に影響を及ぼすような大きな不具合の発生を未然に防止することも可能です。\n\nまた、スピードを意識するあまりテストの実施が抜けてしまったという重大なミスの防止にもつながるでしょう。\n\n## CI/CD導入における考慮点と成功への鍵\n![cicd6](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687600/Blog/Content%20Images/cicd6.jpg)\n\nCI/CDの導入を成功させるためには事前準備や継続的な改善を実施することが大切です。以下で詳しく解説します。\n\n### CI/CDパイプライン構築による開発基盤の強化を図る\n\nCI/CDを活用するためには、CI/CDパイプラインを構築して開発基盤の強化を図る必要があります。\n\n自動化の基準設定とテストコード作成を丁寧に行うことで、その後正しくCI/CDが機能し、ソフトウェア開発における長期的な品質向上の実現につながります。\n\n### 継続的な実施と改善で価値の最大化を実現する\n\nCI/CDの強みを最大限に活かすためには、アジャイル開発のように頻繁にテストとリリースを実施するような開発手法で活用することが大切です。ウォーターフォール開発の場合は、長期的な計画をベースとして開発が進められるため、CI/CDの使用頻度が少なく十分な効果を発揮できません。\n\nまた、CI/CDについては定期的な改善が必要です。例えば、ソフトウェアの変更によってテスト条件の修正を行う場合は、テストコードも書き直さなければなりません。「[GitLab Duo](https://about.gitlab.com/ja-jp/gitlab-duo/)」なら、CI/CDパイプラインの構築やメンテナンス、エラーの発見・分析を効率化できます。\n\n## CI/CDを導入する際のポイント\n\nCI/CDをスムーズに導入する際には以下のようなポイントを押さえておきましょう。\n\n* 必要なリソースを確保する  \n* メンバーに対する教育を行う\n\n### 必要なリソースを確保する\n\nCI/CDを導入する際には、予算や人材、工数の確保が求められます。自社の現状を把握してCI/CD導入にはどのくらいの予算が必要で、事前準備のためにどれだけの工数を必要とするのかを具体的に落とし込んでおくことが大切です。\n\nなお、CI/CDパイプラインの構築においては、DevOpsエンジニアやSREと呼ばれる人材のアサインが必要です。\n\n### メンバーに対する教育を行う\n\nCI/CDを導入して正しく運用していくためには、チームメンバー全体の理解が必要です。具体的には「自社でCI/CDを導入する目的や解決したい課題」「CI/CD関連でよく使用される用語」「CI/CDツールの使い方・運用ルール」などをメンバーに教育し、理解を深めてもらいます。\n\nしかし、チームメンバーに教育するには時間とコストが多くかかってしまい、その期間は利益を生み出していないことを意味します。「[GitLab Duo](https://about.gitlab.com/ja-jp/gitlab-duo/)」なら、AIによりソフトウェア開発のワークフロー全体を効率化できるため、人材の採用や教育コストの削減にもつなげられます。\n\n## CI/CDツールの選び方\n![cicd5](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749687600/Blog/Content%20Images/cicd5.jpg)\n\nCI/CDツールは以下の５つの観点を意識して選びましょう。\n\n* 機能  \n* 提供形態  \n* コスト  \n* セキュリティ  \n* サポート体制\n\n### 機能\n\nまずは、自社の開発プロジェクトに必要な機能が搭載されているか確認します。例えば、以下のような機能が搭載されたツールを選ぶと良いでしょう。\n\n* CI/CDパイプラインの構築やメンテナンス機能  \n* [API](https://about.gitlab.com/ja-jp/blog/what-is-an-api/)やプラグインなどの連携機能  \n* 優れた拡張機能 など\n\n### 提供形態\n\nCI/CDツールにおいては、クラウド型とオンプレミス型の提供形態があります。\n\nクラウド型はインターネット接続を通して提供元のツールを利用する方法で、サーバーを自社で管理する必要がなく手軽に導入できることがメリットです。ただし、カスタマイズ性は劣ります。\n\n一方、オンプレミス型は自社でサーバーを用意してツールを利用する方法です。オンプレミス型の場合は、カスタマイズ性が高く、インターネット上のセキュリティリスクが軽減できることから、特に機密性の高いデータを扱うビジネスや規制の強い業種にむいています。その反面、サーバー構築に手間がかかりますので、両者の特徴を把握したうえで自社にマッチした利用形態を選択しましょう。\n\n[GitLabでは、クラウド型とオンプレミス型の両方を提供しており、自社の置かれた状況に最適な構築が可能です](https://about.gitlab.com/ja-jp/pricing/)。\n\n### コスト\n\nCI/CDツールを導入する際には当然コストが発生するため、自社の予算と照らし合わせながら利用に必要なコストを確認します。\n\nその際、コストを抑えたいからといって自社に必要な機能が搭載されていないツールを導入しても効果は得られないため、機能面も考慮しながらチェックするのがポイントです。\n\nまた、いきなり開発環境を変えてしまうとリスクもあるため、まずは無料トライアルを受けられるツールを選定して使用感を確かめておきましょう。\n\n### セキュリティ\n\n近年企業においてもさまざまなセキュリティインシデントが発生しています。ソフトウェア開発におけるセキュリティリスクを軽減するためには、CI/CDツールが持つセキュリティスキャン等の機能もチェックしておきましょう。\n\n例えば、AI機能を搭載したツールならソースコードの脆弱性をより効率的に把握して修正できます。また、CI/CDツール製品そのものに、開発元からセキュリティパッチが迅速に提供されているかどうかもチェックしておきたいポイントです。\n\n### サポート体制\n\nCI/CDツールの導入や運用においてトラブルが発生する場合もあります。その際ツール提供側でサポート体制が提供されていると、早期の問題解決につながります。\n\nそのため、サポートプランの有無を確認し、窓口の対応時間や連絡方法をチェックしておきましょう。また、ユーザーコミュニティが活発化しているか、参考資料やドキュメントが充実しているかなども確認しておくと良いでしょう。\n\n## CI/CDツールなら「GitLab」\n\nCI/CDツールをお探しならぜひ「[GitLab](https://about.gitlab.com/ja-jp/)」をご検討下さい。CI/CDの機能を確保する際には、別々のツールを管理してそれらを統合することで実現しているケースがよく見られます。しかし、この構築方法ではツールの選定や準備にも手間がかかり、効率が良いとはいえません。\n\nAIを搭載したGitLabなら、単一の統合ツールとしてCI/CDパイプラインの効率化、セキュリティ対策、品質向上、運用コストの削減などを実現することができます。実際にさまざまな企業でGitLabが導入され、リリースサイクルの短縮に成功しています。\n\nまた、GitLabではクラウド型、オンプレミス型の両方を提供していますので、自社の環境に最適な方をお選びいただけます。無料トライアル版もご用意しているため、まずは使用感をお試しください。[サポート体制](https://about.gitlab.com/support/)や[参考ドキュメント](https://docs.gitlab.com/)も充実しているため、安心して運用いただけます。\n\n## CI/CDを導入して開発効率の向上を図ろう\n\nソフトウェアの開発においてCI/CDを導入することで、開発スピードや生産性向上などが期待できます。CI/CDを導入して自社のプロジェクトを成功させるためには、適切なCI/CDパイプライン構築と、継続的なメンテナンスを徹底する意識を持つことが大切です。\n\nCI/CDツールの選定においては、ぜひ「[GitLab](https://about.gitlab.com/ja-jp/)」をご検討下さい。GitLabならCI/CDの実現に必要な機能が搭載されているため、スムーズな導入を実現できます。\n\nGitLabによるCI/CDの事例はこちらからご覧下さい。\n\n> [CI/CDと堅牢なセキュリティスキャンがHilti社のSDLCを加速した方法](https://about.gitlab.com/ja-jp/customers/hilti/?utm_medium=blog&utm_source=blog&utm_campaign=eg_apac_brand_x_x_ja_gitlabjapanblogseo)\n\n\u003Cbr>\u003Cbr>\u003Cbr>\n\n*監修： ハシュカ アンドリュー /Andrew Haschka [@tkomatsubara](https://gitlab.com/tkomatsubara)\u003Cbr>\n（GitLab合同会社 ソリューションアーキテクト本部 シニアパートナーソリューションアーキテクト）*",[111],{"slug":873,"featured":93,"template":684},"what-is-ci-cd","content:ja-jp:blog:what-is-ci-cd.yml","What Is Ci Cd","ja-jp/blog/what-is-ci-cd.yml","ja-jp/blog/what-is-ci-cd",{"_path":879,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":880,"content":886,"config":896,"_id":898,"_type":16,"title":899,"_source":18,"_file":900,"_stem":901,"_extension":21},"/ja-jp/blog/automating-container-image-migration-from-amazon-ecr-to-gitlab",{"title":881,"description":882,"ogTitle":881,"ogDescription":882,"noIndex":6,"ogImage":883,"ogUrl":884,"ogSiteName":776,"ogType":802,"canonicalUrls":884,"schema":885},"Amazon ECRからGitLabへのコンテナイメージ移行の自動化","プラットフォームチームがCI/CDをGitLabに移行する際、コンテナイメージの移行がボトルネックになってはなりません。このガイドでは、パイプライン移行を自動化する方法を詳しく解説します。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663129/Blog/Hero%20Images/blog-image-template-1800x945__28_.png","https://about.gitlab.com/blog/automating-container-image-migration-from-amazon-ecr-to-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Amazon ECRからGitLabへのコンテナイメージ移行の自動化\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Tim Rizzi\"}],\n        \"datePublished\": \"2025-02-13\",\n      }",{"title":881,"description":882,"authors":887,"heroImage":883,"date":889,"body":890,"category":14,"tags":891},[888],"Tim Rizzi","2025-02-13","「Amazon Elastic Container\nRegistry（ECR）からGitLabに数百ものコンテナイメージを移行する必要があるのですが、手伝ってもらえますか？」これまでのプラットフォームエンジニアとの会話の中で、何度もこの質問が出てきました。彼らは、DevSecOpsツールチェーンをGitLabに統合してモダナイズしようとしていたものの、コンテナイメージの移行の箇所でつまずいていました。個々のイメージの移行は簡単でも、数が多すぎると、手作業で行うのは現実的ではありません。\n\n\nまさに、あるエンジニアは「やるべきことはわかっています。プルして、再タグ付けして、プッシュするだけです。しかし、マイクロサービスが200個もあり、それぞれに複数のタグがあります。インフラストラクチャ関連の重要な仕事が山積みの中、この移行作業に何週間も費やすわけにはいきません」と話していました。\n\n\n## 課題\n\n\nこの会話をきっかけに、プロセス全体を自動化できないかと考えました。[CI/CD](https://about.gitlab.com/ja-jp/topics/ci-cd/)をGitLabに移行する際、コンテナイメージの移行がボトルネックになってはなりません。手作業はシンプルですが、繰り返しが多すぎます。各イメージをプルし、再タグ付けし、GitLabのコンテナレジストリにプッシュする…これを数十のリポジトリ、各イメージの何百ものタグに対して行うとなると、数日から数週間かかる途方もない作業になります。\n\n\n## 解決策\n\n\nそこで、こういった大変な作業を自動処理するGitLabパイプラインの作成に取り掛かりました。目標はシンプルです。プラットフォームエンジニアが数分でセットアップできて、一晩放置すればすべてのイメージの移行が完了している、そんなツールを作ることでした。\n\n\n### アクセス権の設定\n\n\nまずはセキュリティです。チームが最小限のAWS権限でこの移行作業を実行できるようにすることを重視しました。以下の読み取り専用のアイデンティティおよびアクセス管理（IAM）ポリシーを用意しました。\n\n\n```json\n\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"ecr:GetAuthorizationToken\",\n                \"ecr:BatchCheckLayerAvailability\",\n                \"ecr:GetDownloadUrlForLayer\",\n                \"ecr:DescribeRepositories\",\n                \"ecr:ListImages\",\n                \"ecr:DescribeImages\",\n                \"ecr:BatchGetImage\"\n            ],\n            \"Resource\": \"*\"\n        }\n    ]\n}\n\n```\n\n\n### GitLabの設定\n\n\nセキュリティの次はGitLab側の設定です。最小限の構成で済むようにしました。CI/CD設定で以下の変数を設定します。\n\n\n```\n\nAWS_ACCOUNT_ID: AWSのアカウントID\n\nAWS_DEFAULT_REGION: ECRのリージョン\n\nAWS_ACCESS_KEY_ID: [マスク]\n\nAWS_SECRET_ACCESS_KEY: [マスク]\n\nBULK_MIGRATE: true\n\n```\n\n\n### 移行パイプライン\n\n\nここからが本番です。このパイプラインはDocker-in-Dockerを使って構築し、すべてのイメージ操作を安定して実行できるようにしました。\n\n\n```yaml\n\nimage: docker:20.10\n\nservices:\n  - docker:20.10-dind\n\nbefore_script:\n  - apk add --no-cache aws-cli jq\n  - aws sts get-caller-identity\n  - aws ecr get-login-password | docker login --username AWS --password-stdin\n  - docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}\n```\n\n\nこのパイプラインは3つのフェーズで構成され、それぞれが前のフェーズをベースにします。\n\n\n1. 検出\n\n\nまず、すべてのECRリポジトリを取得します。\n\n\n```bash\n\nREPOS=$(aws ecr describe-repositories --query\n'repositories[*].repositoryName' --output text)\n\n```\n\n\n2. タグの列挙\n\n\n次に、各リポジトリの全タグを取得します。\n\n\n```bash\n\nTAGS=$(aws ecr describe-images --repository-name $repo --query\n'imageDetails[*].imageTags[]' --output text)\n\n```\n\n\n3. 移行\n\n\n最後に、実際にイメージ移行を実行します。\n\n\n```bash\n\ndocker pull\n${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${repo}:${tag}\n\ndocker tag\n${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${repo}:${tag}\n${CI_REGISTRY_IMAGE}/${repo}:${tag}\n\ndocker push ${CI_REGISTRY_IMAGE}/${repo}:${tag}\n\n```\n\n\n## 期待できる成果\n\n\n移行に何週間もかける時間がないというプラットフォームエンジニアのために、このソリューションは次のような成果を提供します。\n\n\n- すべてのリポジトリとタグを自動的に検出・移行\n\n- ECRとGitLabのイメージ命名規則を統一\n\n- 転送失敗時のエラーハンドリング\n\n- 進捗を追跡できる明確なログ\n\n\n\n移行スクリプトを書いたり、移行作業を監視したりする必要がなくなり、プラットフォームエンジニアは他の重要な作業に集中できるようになります。\n\n\n## 使い方\n\n\n手順はシンプルです。\n\n\n1. `.gitlab-ci.yml`をリポジトリにコピー\n\n2. AWSとGitLabの変数を設定\n\n3. `BULK_MIGRATE`を「true」に設定して、移行を開始\n\n\n## ベストプラクティス\n\n\nさまざまなチームの移行を支援する中で、いくつかの重要なポイントが見えてきました。\n\n\n- ピーク時以外に実行し、チームへの影響を最小限に抑える\n\n- パイプラインのログを確認し、必要な対応がないかチェックする\n\n- すべてのイメージが正常に転送されたことを確認するまで、ECRを廃止しない\n\n- 大規模な移行の場合、ネットワーク負荷を避けるためにレート制限の適用を検討する\n\n\nこのパイプラインは、GitLabの公開リポジトリでオープンソースとして提供しています。プラットフォームエンジニアがコンテナイメージの移行に時間を取られるのではなく、本来の業務に専念できるよう設計されています。ニーズに応じてカスタマイズしてお使いください。実装についてのご質問もお待ちしています。\n\n\n> ####\nこのパッケージおよびその他のコンポーネントの詳細については、[CI/CDカタログのドキュメント](https://gitlab.com/explore/catalog/components/package)をご覧ください。\n",[111,892,681,893,894,895],"AWS","DevSecOps platform","product","solutions architecture",{"slug":897,"featured":93,"template":684},"automating-container-image-migration-from-amazon-ecr-to-gitlab","content:ja-jp:blog:automating-container-image-migration-from-amazon-ecr-to-gitlab.yml","Automating Container Image Migration From Amazon Ecr To Gitlab","ja-jp/blog/automating-container-image-migration-from-amazon-ecr-to-gitlab.yml","ja-jp/blog/automating-container-image-migration-from-amazon-ecr-to-gitlab",{"_path":903,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":904,"content":910,"config":916,"_id":918,"_type":16,"title":919,"_source":18,"_file":920,"_stem":921,"_extension":21},"/ja-jp/blog/what-is-an-api",{"ogTitle":905,"schema":906,"ogImage":907,"ogDescription":908,"ogSiteName":776,"noIndex":6,"ogType":802,"ogUrl":909,"title":905,"canonicalUrls":909,"description":908},"APIとは？意味や利用のメリット、注意点、活用事例を徹底解説","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"APIとは？意味から注目のAPIゲートウェイまで徹底解説\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"GitLab\"}],\n        \"datePublished\": \"2024-12-16\",\n      }","https://res.cloudinary.com/about-gitlab-com/image/upload/v1756780270/zrvqwpatilino8r9qm6e.jpg","API連携の仕組みやメリット、注意点を解説します。APIの種類や具体的な活用例も解説します。","https://about.gitlab.com/blog/what-is-an-api",{"heroImage":907,"body":911,"authors":912,"updatedDate":913,"date":914,"title":905,"tags":915,"description":908,"category":14},"ソフトウェア開発の領域においては「API」の活用が注目されています。APIを導入することで開発コストの削減や効率化、高度な機能実装などを実現できます。\n\nしかし、APIといってもさまざまな種類があり、意味や仕組みについて詳しく理解していない人も多いのではないでしょうか。\n\nこの記事では、API連携の仕組みやメリット、注意点を解説します。APIの種類や具体的な活用例も解説しているので、ぜひ参考にしてください。\n\n## 1. APIとは？\n\n![APIとは？](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756780256/hjsyokgzh5fnvoux66iw.jpg)\n\nAPI連携は、その名の通り、APIを利用してアプリケーションの機能やデータを他のアプリケーションやシステムと連携させ、利用できる機能を拡張することです。事前登録したクレジットカードから自動決済されるシステムやカレンダー機能を使った自動予約システムなどにもAPIが使われています。\n\nAPI連携によって、プログラムをゼロから開発しなくても既存のソフトウェアやWebサービスが提供している機能を活用できるため、効率よく顧客体験を向上させることができるため、幅広い業界で活用が広がっています。\n\n## 2. API連携のしくみ\n\n![API連携の仕組み](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756780251/lfvsw0gtwpzw0yjtats3.jpg)\n\nAPI連携はリクエスト（要求）とレスポンス（応答）で成り立っています。利用者側がリクエストし、提供元がレスポンスするという構図です。API連携のためには、APIの提供元は事前にどのようなリクエストに対してどのようなレスポンスを返すのかルールを設定しなければなりません。\n\n利用者はそのルールに則ったコードを書くことでAPIを連携させることができます。\n\n## 3. API利用のメリット\n\n![API利用のメリット](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756780251/noicynlcnefzltl7kxkn.jpg)\n\nAPIを自社のソフトウェア開発に導入することで以下のようなメリットを享受できます。\n\n* 開発の効率化とコスト削減\n* データの2次利用　\n* セキュリティの向上\n* ユーザーの利便性の向上\n\n### 3-1 開発の効率化とコスト削減\n\nAPIを活用することで開発の効率化とコスト削減を実現できます。通常新しい機能を開発する場合、要件定義から設計、開発、テスト、リリースまでを自社で実施する必要があります。そのプロセスにおいて自社が求める機能を提供しているAPIと連携すれば、複雑なプログラミングを要してゼロから開発する必要がなくなるため、スピーディーに高度な機能を実装することが可能です。\n\nなお、多くのAPIは無料で提供されていますが、有料のAPIであっても自社でゼロから開発した場合に発生するコストと比べれば、低コストで開発を進められるでしょう。\n\n### 3-2 データの2次利用\n\n無料で提供されているAPIも多くありますし、有償APIも自社で開発から構築まで取り組んだ場合にかかる費用と比べれば、低コストに抑えられることがほとんどです。\n\nAPI連携によって他社サービスのデータを利用できます。例えば、ECサイトで提供されているAPIなら、ECサイトが保有している商品情報や在庫状況、顧客情報などを取得して自社のマーケティング戦略に活かせるでしょう。また、SNS業界でもAPIの公開が進んでいます。ユーザーの投稿やトレンドを分析すれば、新しい機能開発にもつなげられます。\n\nAPIの活用により膨大なデータの収集から登録、更新まで行う必要がないため、業務効率化や情報の信頼性向上が期待できます。\n\n### 3-3 セキュリティの向上\n\n近年セキュリティインシデントが多く発生しているため、自社でシステムを構築する際にもセキュリティ強化を徹底しなければなりません。API連携を行えば、開発におけるセキュリティ強化にもつなげられます。\n\n例えば、モバイルデバイスを利用した二段階認証をシステムに構築する場合、自社で構築・運用するよりもAPI連携で実績のある認証サービスを利用すれば、セキュリティレベルの高い二段階認証を導入できます。これによりユーザーも安心してシステムに登録できるため、登録ユーザー数の向上も期待できるでしょう。\n\n### 3-4 ユーザーの利便性の向上\n\nAPI連携を行えば、ユーザーの利便性向上も見込めます。例えば、自社のWebサービスをユーザーが初めて利用する際に登録情報の入力が面倒だと感じることも多いでしょう。\n\nそこでAPI連携によって他社サービスの登録情報を活用して登録・ログインできる仕組みを構築しておけば、ユーザーはスムーズにサービスを利用することができ、「登録・ログインの手間」による離脱防止につなげられます。\n\n## 4. APIを利用する際の注意点\n\n![APIを利用する際の注意点](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756780251/pv7pq4uaaakouzkrwqmu.jpg)\n\nAPIにはさまざまなメリットがありますが、以下のような注意点もあるため利用前に把握しておくことが大切です。\n\n* サービスの不具合の可能性\n* 突然のサービス停止のリスク\n\n### 4-1 サービスの不具合の可能性\n\nAPI提供元でシステムの不具合が発生した場合、自社で連携しているAPIの機能が使えなくなる可能性があります。つまり、APIを安定的に継続して活用できるかどうかはAPI提供元に大きく依存するということです。\n\n万が一、トラブルが発生し機能が使えなくなった場合は自社での対応はできないため、解消されるまで待たなければなりません。システムの利用ユーザーに不安や不満を感じさせてしまう原因にもなるため、事前にリスク対策を検討しておくことが大切です。\n\n### 4-2 突然のサービス停止のリスク\n\nAPI提供元のシステムの不具合だけでなく、サービスそのものが停止される可能性も考慮しておく必要があります。\n\n機能そのものが停止してしまうと、自社のサービスでも利用できなくなるため、代替となるサービスを活用する必要があります。\n\n突然サービスが停止されてから新しいAPIを探して実装するとなると時間と手間がかかるため、あらかじめ調査しておくことをおすすめします。\n\n## 5. APIの種類\n\n![APIの種類](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756780251/kkj6pd3tpcx8zmzla5g0.jpg)\n\nAPIには提供される目的や用途に応じていくつかの種類があり、いずれも提供元や活用方法が異なります。どのAPIを使うのが最適か判断するためにも、APIの種類について理解しておきましょう。\n\n### 5-1 Web API\n\nWebを介して機能の一部が提供されるAPIです。「HTTP/HTTPS」の通信方式を使ってインターネット経由でリクエスト／レスポンスのやり取りが行われます。プログラミング言語や使用するパソコンのOSに関係なく、あらゆる環境からアクセスが可能な点が大きな強みであり、多くの企業からさまざまなAPIが提供されています。\n\n### 5-2 OS API\n\nWindowsやAndroidのようなOSが提供する「OS API（ネイティブAPI）」。OSが持っている機能を、他のアプリケーションでも呼び出すことができるAPIです。WindowsがOSとして持っている機能をサードパーティ製のアプリでも使えるようにしています。OSが進化するとともに、OSが提供する機能は多岐にわたり、手軽にAPIを使えるようなツール（フレームワーク）が提供されることも増えています。\n\n### 5-3 ライブラリAPI \n\nライブラリAPIとは、プログラミング言語のライブラリが提供するAPIのことで、クラスライブラリやコアAPI、標準APIとも呼ばれる場合もあります。ライブラリには、外部から利用できる特定の機能を実装するためのプログラム部品が格納されており、APIとして利用すれば一からコードを記述する必要がなくなるため、開発効率を大幅に向上させることが可能です。\n\nつまり、ライブラリAPI を活用すれば複雑なプログラミングを短時間で実行できるようになります。\n\n### 5-4 ランタイムAPI\n\nランタイムAPIとは、プログラムが実行されている時に使用されるAPIで、プログラム実行中の情報を取得できます。例えば、アプリケーションの動作状況をリアルタイムで把握し、メモリの使用量や実行時間などを把握することが可能です。\n\nランタイムAPIを活用すれば早期にアプリケーションの状態を把握できるため、問題の早期発見・改善につながりパフォーマンスを最適化できます。\n\n## 6. APIの提供方式\n\n![APIの提供方式](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756780251/kkj6pd3tpcx8zmzla5g0.jpg)\n\nAPIにはさまざまな提供方式があり、活用の目的によって使い分ける必要があります。\n\n* オープン（パブリック）API\n* パートナーAPI\n* 内部API\n* コンポジットAPI\n\n### 6-1 オープン（パブリック）API\n\nオープンAPIは、企業が運用しているシステムのAPIを外部に公開しているAPIを指します。API提供元の企業はAPIを外部公開することで自社サービスの認知拡大を図れ、さらにAPIの提供を有料コンテンツとすれば利益の確保にもつながります。\n\nAPI利用者側は利用規約に同意すれば誰でも利用できるため、システム開発の際に自由に連携することが可能です。これにより高度な機能実装やセキュリティ向上を実現できます。\n\n### 6-2 パートナーAPI\n\nパートナーAPIは、企業間で利用されるAPIを指し、オープンAPIとは異なり外部での利用が限定されるのが特徴です。\n\nパートナーAPIを利用すれば、パートナー企業が保有しているデータや機能といったリソースを最大限に活用できるため、自社システムのパフォーマンス向上や顧客体験の強化につなげられます。\n\n### 6-3 内部API\n\n内部APIは、企業内のシステム間でデータのやり取りをするために活用されるAPIを指します。社内向けのAPIであるため、外部に公開されることはありません。\n\n多数のシステムを保有している企業なら内部APIを整備することで、社内でのデータ連携が容易になるため業務スピードの向上を実現できます。\n\n### 6-4 コンポジットAPI\n\nコンポジットAPIとは、一つのAPIで複数のAPIをまとめて利用できる形式のことです。コンポジットAPIを活用すれば、複数のアプリケーションとデータ連携する際の負担が軽減されるため開発効率の向上が期待できます。\n\nクラウドサービス間のデータ連携においてコンポジットAPIが利用されることが多いです。\n\n## 7. 代表的な4つのAPIプロトコル\n\n![代表的な4つのAPIプロトコル](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756780256/rfea6xfjdwi2iklpstev.jpg)\n\nAPIプロトコルとは、システム間でデータの送受信を行うための通信の仕組みを指します。代表的なプロトコルは以下が挙げられます。\n\n* HTTP / HTTPS\n* XML-RPC\n* JSON-RPC\n* SOAP\n\n### 7-1 HTTP / HTTPS\n\nHTTP / HTTPSは、WebサーバーとWebブラウザとの間でデータのやり取りをするために用いられるプロトコルを指し、多くのWeb  APIで利用されています。\n\nHTTPSは、通信内容が暗号化されるためHTTPよりも高いセキュリティでより安全な通信を実現できます。\n\n### 7-2 XML-RPC\n\nXML-RPCは、XML形式を利用してクライアントとサーバー間でデータのやり取りをするプロトコルです。RPC（Remote Procedure Call：リモートプロシージャコール）とは、ネットワーク上にある他のコンピューターに対して処理をリクエストして実行するための手法を指します。\n\nXML-RPCは、1998年にユーザーランド・ソフトウェア社とマイクロソフトが共同開発したもので後に紹介するSOAPへと発展しています。\n\n### 7-3 JSON-RPC\n\nJSON-RPCとは、JSONを利用してクライアントとサーバー間でデータのやり取りをするプロトコルを指します。\n\nJSONは可読性が高く、コンピューターにとっても扱いやすい軽量のデータフォーマットであるため幅広く利用されています。\n\n### 7-4 SOAP\n\nSOAPとは、「Simple Object Access Protocol」の略語のことでXML-RPCを拡張したプロトコルです。SOAPはデータをやり取りするためのルールが厳格に定められているため、XML-RPCと比べて複雑なデータの通信に使われます。例えば、決済や認証など高いセキュリティが求められるシーンで活用できます。\n\n## 8. API連携の具体例\n\n![API連携の具体例](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756780256/y02nbwxggacaweafck3r.jpg)\n\n具体的にどのような場面でAPI連携が使われているのでしょうか。\n\n* SNS\n* ECサイト\n* POSレジ\n* 地図・天気情報\n\n以上4つの例を具体的に説明します。\n\n### 8-1 SNS\n\n近年、SNSは企業と個人をつなぐツールとして不可欠な存在となりつつあります。世界中に顧客を持つ企業では、よりきめ細かなカスタマーケアを提供する方法としてX（旧Twitter）で公開されているAPI「Sprout Social」はDM（ダイレクトメール）やメンション、リプライなどで言及されたユーザーからの要望や質問を、企業内の担当者に直接転送してくれます。\n\nまた、カスタマーフィードバック機能では、XのDMで製品やサービスの満足度に関するアンケート調査を行えます。質問への回答率の向上や解答までの時間短縮が顧客体験の向上を実現します。他にもLINEを使った荷物の再配達設定など、SNSを使った顧客体験の向上は広い業界に広がっています。\n\n### 8-2 ECサイト\n\n決済サービスの運営事業者はECサイト向けのAPIやサードパーティアプリを提供しています。例えば、楽天ペイでは決済処理APIを提供しており、API連携をしたECサイトで楽天会員が決済する場合、楽天ペイに登録済みの情報を呼び出して決済できます。個人情報を入力して会員登録をする手間を省けるため、顧客体験やコンバージョン率の向上が見込めます。\n\n### 8-3 POSレジ\n\n販売情報を集計・記録するPOSレジでもAPI連携が広がっています。顧客管理システムとの連携で会員情報の共有や購買履歴にあわせた商品レコメンドが可能になります。また、在庫管理システムとの連携で仕入れ効率を向上するなどデータ管理の効率化でも使われています。業種や店舗形態によってさまざまな活用が広がっています。\n\n### 8-4 地図・天気情報\n\n自社のWebサイトやアプリに対して、地図や天気情報をAPI連携を通して反映させることができます。\n\n例えば、商品の認知拡大や購買意欲の向上を目的として屋外イベントを開催する際には、API連携してWebサイトに地図や天気情報を掲載して告知すればユーザーに有益な情報を提供できます。これによりユーザーの情報収集の手間が省けるため、顧客満足度の向上にもつながるでしょう。\n\n## 9. 注目のAPI提供元とそのサービス\n\n![注目のAPI提供元とそのサービス](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756780251/rfo3pqrzugdasqidprzn.jpg)\n\nここからは、注目のAPI提供元をご紹介します。\n\n### 9-1 Google\n\nGoogleでは、クラウド基盤である「Google Cloud Platform」上で、利用できるAPIをライブラリにまとめており、GmailやMap、YouTube、Calendar、Driveの他、300種類のAPIが公開されています。\n\nこうしたAPIを使って、メールを簡単に取得するツールやカレンダーアプリを作ったり、ブラウザの拡張機能や画像認識を使ったスマホアプリ、ソフトウェア、Webサービスを構築できます。\n\n### 9-2 X（旧Twitter）\n\n大手SNSであるXもAPIを提供しています。Webサイトに表示される投稿内容や投稿をまとめたり、自動で投稿してくれるツールなど、全てAPIをベースに作られています。\n\nSNSを使った情報発信や、情報収集を効率化したい場合には、真っ先にチェックすべきAPIと言えるでしょう。\n\n### 9-3 OpenAI\n\n話題のChatGPTを提供するOpenAIもAPIを提供しています。画像生成、機械文字起こし、自動分類、機械学習を実装するAPIに注目が集まっています。\n\n### 9-4 ヤマト運輸\n\nWebAPIにより、配送連携APIを提供しています。二次元コードをかざすだけでコンビニやオープン型宅配便ロッカーからの荷物を発送するため、匿名配送や発送時の支払い簡略化が可能になり、高い顧客満足を誇っています。\n\n### 9-5 Slack\n\nアメリカ発のビジネス向けコミュニケーションツールであるSlackも、「Slack API」という独自のAPIを提供しています。利用することで、リマインドやリアルタイムでのアラートなどの通知が行えます。Botを活用し、タスク自動化、メッセージの送受信や会話へのリアクションなども実装できます。\n\nSlackへ外部サービスからのAPIも提供されており、例えばGitLabも[Slack向けのAPI](https://about.gitlab.com/ja-jp/solutions/slack/)を提供しています。\n\n## 10. APIの使い方・利用手順\n\n![APIの使い方・利用手順](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756780251/kwai9kgdry7kvcbwabu1.jpg)\n\n1. API提供元のWebサービスに登録する\n2. APIキーとAPIシークレットを取得し設定を行う\n3. 実装・テストを行う\n\n多くの場合、まずAPIを提供しているWebサービスへの登録が必要になり、基本情報の入力を行います。登録が完了すればAPIキーとAPIシークレットを取得できます。これらはAPIを利用するためのコードであるため大切に保管しておいて下さい。\n\nコードの取得まで終わり、準備が整えば実装の段階に移ります。APIの実装手順は提供事業者によって異なるため、ドキュメントなどを確認しながら行いましょう。実装が完了したら実際に操作してみて動作に問題がないか確認します。\n\n## 11. API連携に関するよくある質問\n\n![API連携に関するよくある質問](https://res.cloudinary.com/about-gitlab-com/image/upload/v1756780256/o82yfn9ph698fmhcv41x.jpg)\n\n最後にAPI連携に関するよくある質問とその回答を紹介します。\n\n### 11-1 APIゲートウェイとは何ですか？\n\nAPIゲートウェイとは、APIの管理ツールです。複数のAPIと連携を行う場合、APIゲートウェイを使えば、APIゲートウェイがそれぞれのAPIへリクエストを振り分け、集約し適正なレスポンスを返却してくれます。\n\n### 11-2 APIは誰でも利用できますか？\n\n基本的には誰でも利用可能です。ただし、利用における必要な技術や、APIによっては有償化されているものもあるので、利用する際には、きちんとした理解と検討が必要です。\n\n### 11-3 RESTとSOAPの違いは？\n\nRESTは「Representational State Transfer」の略語であり、Webのアーキテクチャスタイルの一つです。HTTPプロトコルを使用しますが、REST自体はプロトコルではありません。\n\n一方、SOAPはメッセージングプロトコルであるため、両者は根本的に異なるアプローチだといえます。\n\n### 11-4 WebhookとAPIとの違いは？\n\nWebhookとAPIにおいては、どちらもアプリケーション間でデータを連携するために活用されますが、両者は仕組みの観点から明確な違いがあります。\n\nAPIの場合は、必要に応じてデータをリクエストしてレスポンスを受け取る方式ですが、Webhookは事前に設定した条件を満たすことでこちら側からリクエストしなくてもレスポンスを受け取れます。\n\nつまり、Webhookならリアルタイムで必要な情報を受け取ることができます。しかし、APIとは異なりユーザーを認証する機能がないため、悪意ある情報を受け取ったりなどセキュリティにおけるリスクがあります。\n\n## まとめ\t自社のビジネスやサービス開発にAPI戦略を取り入れよう！\n\n自社のソフトウェア開発やビジネスにおいてAPIを積極的に活用することで、開発効率の向上やコスト削減などを実現できます。\n\nAPIにはさまざまな種類がありますが、自社に必要な要件を満たしたAPIを探して積極的に開発に取り入れていくと良いでしょう。\n\n[GitLab](https://about.gitlab.com/ja-jp/)でも開発者向けに包括的なAPIを提供しており、CI/CDパイプラインの自動化から課題管理まで、様々な機能をAPI経由で利用できます。GitLabの利便性の高いAPIを、ぜひこの機会に体験して下さい。\n\nなお、[GitLab](https://about.gitlab.com/ja-jp/)では世界39か国、5,000人を超えるDevSecOps専門家のインサイトが詰まった完全版レポートを無料で公開しているので、ぜひこちらもご覧ください。\n\n[2024グローバルDevSecOpsレポートはこちら](https://about.gitlab.com/ja-jp/developer-survey/)",[807],"2025-09-02","2024-12-16",[812,236],{"slug":917,"featured":93,"template":684},"what-is-an-api","content:ja-jp:blog:what-is-an-api.yml","What Is An Api","ja-jp/blog/what-is-an-api.yml","ja-jp/blog/what-is-an-api",{"_path":923,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":924,"content":930,"config":939,"_id":941,"_type":16,"title":942,"_source":18,"_file":943,"_stem":944,"_extension":21},"/ja-jp/blog/using-child-pipelines-to-continuously-deploy-to-five-environments",{"title":925,"description":926,"ogTitle":925,"ogDescription":926,"noIndex":6,"ogImage":927,"ogUrl":928,"ogSiteName":776,"ogType":802,"canonicalUrls":928,"schema":929},"子パイプラインを使用して5つの環境に継続的にデプロイする","使用するGitLabワークフローを最小限に抑えつつ、複数の環境（事前の準備なしに一時的に利用できるsandboxなど）への継続的デプロイを管理する方法を解説します。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097012/Blog/Hero%20Images/Blog/Hero%20Images/AdobeStock_397632156_3Ldy1urjMStQCl4qnOBvE0_1750097011626.jpg","https://about.gitlab.com/blog/using-child-pipelines-to-continuously-deploy-to-five-environments","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"子パイプラインを使用して5つの環境に継続的にデプロイする\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Olivier Dupré\"}],\n        \"datePublished\": \"2024-09-26\",\n      }",{"title":925,"description":926,"authors":931,"heroImage":927,"date":933,"body":934,"category":14,"tags":935,"updatedDate":938},[932],"Olivier Dupré","2024-09-26","DevSecOpsチームでは、複数の環境にまたがる継続的デプロイを管理する機能が必要となることがあります。その場合、ワークフローを変更せずに、デプロイを行えるようにする必要があります。[GitLab\nDevSecOpsプラットフォーム](https://about.gitlab.com/)なら、事前の準備なしに一時的に利用できるsandboxを使用して工数を最小限に抑えるアプローチなどを通じて、こうしたニーズに対応できます。この記事では、Terraformを使って複数の環境上でインフラの継続的デプロイを行う方法についてご紹介します。\n\n\nこの手法は、[Pulumi](https://www.pulumi.com/)や[Ansible](https://www.ansible.com/)のような別の技術を使用したInfrastructure\nas\nCode（IaC）でも、どのような言語で書かれたソースコードでも、または多様な言語が混在するモノレポであっても、あらゆるプロジェクトに簡単に適用できます。\n\n\nこのチュートリアルの終了時には、以下のような環境をデプロイするパイプラインが完成します。\n\n\n* 各フィーチャーブランチの一時的な**レビュー（review）**環境。\n\n* 簡単に消去可能で、mainブランチからデプロイされる**統合（integration）**環境。\n\n* **品質管理（qa）**環境。同様にmainブランチからデプロイされ、品質管理プロセスを実行します。\n\n* タグ付けされるたびにデプロイされる**ステージング（staging）**環境。これは本番環境前の最後のステージです。\n\n*\nステージング環境の直後の**本番（production）**環境。今回はデモ用に手動でトリガーしますが、継続的にデプロイされるようにすることも可能です。\n\n\n>この記事で使用されるフローチャートの説明は以下のとおりです。\n\n> * 角が丸いボックスはGitLabブランチです。\n\n> * 四角のボックスは環境です。\n\n> * 矢印上のテキストは、あるボックスから次のボックスへのアクションを指します。\n\n> * ひし形のボックスは決定ステップです。\n\n\n\u003Cpre class=\"mermaid\">\n\nflowchart LR\n    A(main) -->|新機能| B(feature_X)\n\n    B -->|自動デプロイ| C[review/feature_X]\n    B -->|マージ| D(main)\n    C -->|破棄| D\n\n    D -->|自動デプロイ| E[integration]\n    E -->|手動| F[qa]\n\n    D -->|タグ付け| G(X.Y.Z)\n    F -->|検証| G\n\n    G -->|自動デプロイ| H[staging]\n    H -->|手動| I{plan}\n    I -->|手動| J[production]\n\u003C/pre>\n\n\nステップごとに、[理由](#why)と[行うこと](#what)を説明した上で、[方法](#how)をご紹介します。これにより、このチュートリアルを完全に理解し、正確に実行しやすくなります。\n\n\n## 理由\n\n\n*\n[継続的インテグレーション](https://about.gitlab.com/topics/ci-cd/#what-is-continuous-integration-ci)はほぼ事実上の業界標準と言えます。ほとんどの企業は、CIパイプラインを実装済みであるか、その実践の標準化を検討しています。\n\n\n*\nまた、CIパイプラインの最後にリポジトリまたはレジストリにアーティファクトをプッシュする[継続的なデリバリー](https://about.gitlab.com/topics/ci-cd/#what-is-continuous-delivery-cd)も一般的です。\n\n\n*\n継続的デプロイメントはさらに進んで、これらのアーティファクトを自動的にデプロイしますが、その普及はまだ限定的です。導入されている場合、主にアプリケーション分野で見られます。インフラの継続的デプロイメントに関しては、状況がやや不明瞭で、複数の環境の管理に重きが置かれる傾向があります。一方で、インフラのコードをテストし、セキュリティを確保し、検証することはより難しいとされています。この分野は、DevOpsがまだ成熟に至っていない分野のひとつです。ほかの分野としては、セキュリティのシフトレフトが挙げられます。具体的には、セキュリティチームの介入、さらに重要なことに、セキュリティ上のリスクへの対応をデリバリーライフサイクルの早期に組み込み、DevOpsから***DevSecOps***へと発展させる取り組みのことです。\n\n\nこのような概況を踏まえ、本チュートリアルでは、インフラにDevSecOpsをシンプルかつ効果的に導入するシナリオに取り組みます。5つの環境にリソースをデプロイする例を交えながら、開発から本番環境へと段階的に進めていきます。\n\n\n__注__：個人的にはFinOpsアプローチを採用し、環境の数を減らすことを推奨していますが、開発環境、ステージング環境、本番環境以外の環境を保持すべき場合もあります。そのため、これからご紹介する例をご自身のニーズに合わせて調整してください。\n\n\n## 行うこと\n\n\nクラウド技術の台頭により、IaCの利用が促進されています。この分野を最初に開拓したのは、AnsibleとTerraformでした。OpenTofu、Pulumi、AWS\nCDK、Google Deploy Managerを始めとする多くの会社がその後に続きました。\n\n\nIaCを定義することは、インフラストラクチャを安全にデプロイするのに最適なソリューションです。目標を達成できるまで必要なだけ、テスト、デプロイ、再実行を繰り返し行えます。\n\n\n残念なことに、ターゲット環境ごとに複数のブランチやリポジトリを保持している企業がよくあります。これが原因で問題が生じます。こういった企業では、プロセスの実施が徹底されていません。本番環境のコードベースへの変更が、その前の環境で正しくテストされているかどうかも確認できません。その結果、ある環境から別の環境へ流れるだけになります。\n\n\nこのチュートリアルが必要だと気づいたのは、あるカンファレンスに参加した際に、本番環境へのデプロイ前にインフラストラクチャを十分にテストするワークフローがないと参加者全員から聞いたときです。みなが、本番環境で直接コードにパッチを適用することもあると言っていました。確かにこの方法は手っ取り早いですが、果たして安全でしょうか？前の環境にフィードバックをどう戻すのでしょうか？また副次効果が生じないようにするにはどうすればよいのでしょうか？新たな脆弱性が本番環境にあまりにも早くプッシュされることで会社がリスクにさらされないようにするには、どのように管理すべきでしょうか？\n\n\nここで重要なのは、DevOpsチームが本番環境に直接デプロイするのは*なぜ*かということです。パイプラインの効率性や速度を向上できる可能性があるためでしょうか？自動化できないのでしょうか？それどころか、*本番環境以外で正確にテストする方法がない*からなのでしょうか？\n\n\n次のセクションでは、インフラストラクチャを自動化し、ほかの人に影響を及ぼす環境にコードがプッシュされる前に、DevOpsチームが効果的かつ確実にテストを実施するための方法をご説明します。また、コードがどのように保護され、エンドツーエンドでデプロイが管理されているかも確認していきます。\n\n\n## 方法\n\n\n前述のとおり、現在では多くのIaC言語が存在しているため、この記事だけで客観的に*すべて*を取り上げることはできません。そのため、この記事ではバージョン1.4で実行される基本的なTerraformコードを使用します。IaC言語そのものではなく、貴社のエコシステムに適用できるプロセスに注目してください。\n\n\n### Terraformコード\n\n\nまずは、基本的なTerraformコードから始めましょう。\n\n\n仮想ネットワークであるAWSの仮想プライベートクラウド（VPC）にデプロイしたいと思います。VPCには、パブリックサブネットとプライベートサブネットをデプロイします。名前からわかるように、これらはメインVPCのサブネットです。最後に、パブリックサブネットにAmazon\nElastic Cloud Compute（EC2）インスタンス（仮想マシン）を追加します。\n\n\nこれは、比較的簡単な方法で4つのリソースをデプロイする方法を示しています。コードではなく、パイプラインに焦点を当てることがここでの目的です。\n\n\nここで目指すリポジトリの完成形は、以下のとおりです。\n\n\n![リポジトリの完成図](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097033/Blog/Content%20Images/Blog/Content%20Images/image5_aHR0cHM6_1750097033415.png)\n\n\nステップごとに行っていきましょう。\n\n\nまずは、`terraform/main.tf`ファイルでリソースをすべて宣言します。\n\n\n```terraform\n\nprovider \"aws\" {\n  region = var.aws_default_region\n}\n\n\nresource \"aws_vpc\" \"main\" {\n  cidr_block = var.aws_vpc_cidr\n\n  tags = {\n    Name     = var.aws_resources_name\n  }\n}\n\n\nresource \"aws_subnet\" \"public_subnet\" {\n  vpc_id     = aws_vpc.main.id\n  cidr_block = var.aws_public_subnet_cidr\n\n  tags = {\n    Name = \"Public Subnet\"\n  }\n}\n\nresource \"aws_subnet\" \"private_subnet\" {\n  vpc_id     = aws_vpc.main.id\n  cidr_block = var.aws_private_subnet_cidr\n\n  tags = {\n    Name = \"Private Subnet\"\n  }\n}\n\n\nresource \"aws_instance\" \"sandbox\" {\n  ami           = var.aws_ami_id\n  instance_type = var.aws_instance_type\n\n  subnet_id = aws_subnet.public_subnet.id\n\n  tags = {\n    Name     = var.aws_resources_name\n  }\n}\n\n```\n\n\nご覧のとおり、このコードではいくつかの変数が必要となるため、`terraform/variables.tf`ファイルでそれらを宣言します。\n\n\n```terraform\n\nvariable \"aws_ami_id\" {\n  description = \"The AMI ID of the image being deployed.\"\n  type        = string\n}\n\n\nvariable \"aws_instance_type\" {\n  description = \"The instance type of the VM being deployed.\"\n  type        = string\n  default     = \"t2.micro\"\n}\n\n\nvariable \"aws_vpc_cidr\" {\n  description = \"The CIDR of the VPC.\"\n  type        = string\n  default     = \"10.0.0.0/16\"\n}\n\n\nvariable \"aws_public_subnet_cidr\" {\n  description = \"The CIDR of the public subnet.\"\n  type        = string\n  default     = \"10.0.1.0/24\"\n}\n\n\nvariable \"aws_private_subnet_cidr\" {\n  description = \"The CIDR of the private subnet.\"\n  type        = string\n  default     = \"10.0.2.0/24\"\n}\n\n\nvariable \"aws_default_region\" {\n  description = \"Default region where resources are deployed.\"\n  type        = string\n  default     = \"eu-west-3\"\n}\n\n\nvariable \"aws_resources_name\" {\n  description = \"Default name for the resources.\"\n  type        = string\n  default     = \"demo\"\n}\n\n```\n\n\nすでにIaC側に関しては、これでほぼ準備が整いました。しかしながら、これではTerraformの状態を共有できません。ご存知ない方のために大まかに説明すると、Terraformは以下を行うことで動作します。\n\n\n* `plan`により、インフラストラクチャの現在の状態とコートで定義されている内容の差分を確認してから、差分を出力します。\n\n* `apply`により、`plan`の差分を適用して、状態を更新します。\n\n\n最初のラウンドでは状態は空で、その後、Terraformによって適用されたリソースの詳細（IDなど）が挿入されます。\n\n\n問題は、その状態がどこに保存されるかということです。また、複数のデベロッパーがコード上で共同作業を行えるようにするにはどうすればよいのでしょうか？\n\n\n解決策はとても簡単で、GitLabを利用して、[Terraform\nHTTPバックエンド](https://docs.gitlab.com/ee/user/infrastructure/iac/terraform_state.html)を介して状態を保存して共有するだけです。\n\n\nこのバックエンドを使用するには、まずはもっともシンプルな`terraform/backend.tf`ファイルを作成します。次のステップは、パイプラインで処理します。\n\n\n```terraform\n\nterraform {\n  backend \"http\" {\n  }\n}\n\n```\n\n\nこれで、4つのリソースをデプロイするための最低限のTerraformコードができあがりました。変数の値は実行する際に指定するので、後でご説明します。\n\n\n### ワークフロー\n\n\nこれから以下のワークフローを実装します。\n\n\n\u003Cpre class=\"mermaid\">\n\nflowchart LR\n    A(main) -->|新機能| B(feature_X)\n\n    B -->|自動デプロイ| C[review/feature_X]\n    B -->|マージ| D(main)\n    C -->|破棄| D\n\n    D -->|自動デプロイ| E[integration]\n    E -->|手動| F[qa]\n\n    D -->|タグ付け| G(X.Y.Z)\n    F -->|検証| G\n\n    G -->|自動デプロイ| H[staging]\n    H -->|手動| I{plan}\n    I -->|手動| J[production]\n\u003C/pre>\n\n\n1.\n**フィーチャー**ブランチを作成します。これにより、コードに対して継続的にすべてのスキャナーが実行され、コンプライアンスとセキュリティを確保できます。このコードは、現在のブランチの名前が付けられた一時的な環境`review/feature_branch`に継続的にデプロイされます。これは、デベロッパーと運用チームが誰にも影響を与えることなくコードをテストできる安全な環境です。また、ここでコードレビューやスキャナーの実行などのプロセスを実施し、コードの品質とセキュリティが許容範囲内であることを確認し、資産が危険にさらされることのないようにします。このブランチでデプロイされたインフラストラクチャは、ブランチが閉じられると自動的に破棄されます。これにより予算範囲内に収めやすくなります。\n\n\n\u003Cpre class=\"mermaid\">\n\nflowchart LR\n    A(main) -->|新機能| B(feature_X)\n\n    B -->|自動デプロイ| C[review/feature_X]\n    B -->|マージ| D(main)\n    C -->|破棄| D\n\u003C/pre>\n\n\n2.\n承認されると、フィーチャーブランチはmainブランチに**マージ**されます。これは[保護ブランチ](https://docs.gitlab.com/ee/user/project/protected_branches.html)であり、誰もプッシュできません。本番環境への変更リクエストをすべて十分にテストするために必要です。このブランチも継続的にデプロイされます。ここでのターゲットは`integration`環境です。この環境をもう少し安定させるために、削除は自動化されておらず、手動でトリガーできるようになっています。\n\n\n\u003Cpre class=\"mermaid\">\n\nflowchart LR\n    D(main) -->|自動デプロイ| E[integration]\n\u003C/pre>\n\n\n3.\nここから次のデプロイをトリガーするには、手動による承認が必要となります。これにより、mainブランチが`qa`環境にデプロイされます。ここでパイプラインからの削除を防ぐルールを設定します。何しろすでに3つ目のこの環境はかなり安定しているはずなので、このルールは誤って削除されるのを防ぐことを目的とします。貴社のプロセスに合わせて、お好きなようなルールを調整してください。\n\n\n\u003Cpre class=\"mermaid\">\n\nflowchart LR\n    D(main)-->|自動デプロイ| E[integration]\n    E -->|手動| F[qa]\n\u003C/pre>\n\n\n4.\n次に進むには、コードに**タグ付け**する必要があります。[保護タグ](https://docs.gitlab.com/ee/user/project/protected_tags.html)を使用して、特定のユーザーのみが最後の2つの環境にデプロイできるようにします。これにより、`staging`環境へのデプロイが即座にトリガーされます。\n\n\n\u003Cpre class=\"mermaid\">\n\nflowchart LR\n    D(main) -->|タグ付け| G(X.Y.Z)\n    F[qa] -->|検証| G\n\n    G -->|自動デプロイ| H[staging]\n\u003C/pre>\n\n\n5.\nついに`production`に到達しました。インフラストラクチャに関して言うと、（10%や25%など）段階的にデプロイするのは難しい場合が多いため、インフラストラクチャ全体をデプロイします。ただし、この最後のステップで行う手動トリガーで、このデプロイを制御します。そして、この極めて重要な環境を最大限に制御できるようにするために、[保護環境](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)として管理します。\n\n\n\u003Cpre class=\"mermaid\">\n\nflowchart LR\n    H[staging] -->|手動| I{plan}\n    I -->|手動| J[production]\n\u003C/pre>\n\n\n### パイプライン\n\n\n上記の[ワークフロー](#the-workflow)を実装するために、2つの[ダウンストリームパイプライン](https://docs.gitlab.com/ee/ci/pipelines/downstream_pipelines.html)とともにパイプラインを構築します。\n\n\n#### メインパイプライン\n\n\nまずは、メインパイプラインから始めましょう。メインパイプラインは、**フィーチャーブランチへのプッシュ**、**デフォルトブランチへのマージ**、または**タグ付け**が発生すると、必ず自動的にトリガーされます。*このパイプライン*によって、`dev`、`integration`、`staging`環境に対する真の**継続的デプロイ**を実現できます。プロジェクトのルートにある`.gitlab-ci.yml`ファイルで宣言します。\n\n\n![リポジトリのターゲット](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097033/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750097033417.png)\n\n\n```yml\n\nStages:\n  - test\n  - environments\n\n.environment:\n  stage: environments\n  variables:\n    TF_ROOT: terraform\n    TF_CLI_ARGS_plan: \"-var-file=../vars/$variables_file.tfvars\"\n  trigger:\n    include: .gitlab-ci/.first-layer.gitlab-ci.yml\n    strategy: depend            # Wait for the triggered pipeline to successfully complete\n    forward:\n      yaml_variables: true      # Forward variables defined in the trigger job\n      pipeline_variables: true  # Forward manual pipeline variables and scheduled pipeline variables\n\nreview:\n  extends: .environment\n  variables:\n    environment: review/$CI_COMMIT_REF_SLUG\n    TF_STATE_NAME: $CI_COMMIT_REF_SLUG\n    variables_file: review\n    TF_VAR_aws_resources_name: $CI_COMMIT_REF_SLUG  # Used in the tag Name of the resources deployed, to easily differenciate them\n  rules:\n    - if: $CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n\nintegration:\n  extends: .environment\n  variables:\n    environment: integration\n    TF_STATE_NAME: $environment\n    variables_file: $environment\n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n\nstaging:\n  extends: .environment\n  variables:\n    environment: staging\n    TF_STATE_NAME: $environment\n    variables_file: $environment\n  rules:\n    - if: $CI_COMMIT_TAG\n\n#### TWEAK\n\n# This tweak is needed to display vulnerability results in the merge\nwidgets.\n\n# As soon as this issue https://gitlab.com/gitlab-org/gitlab/-/issues/439700\nis resolved, the `include` instruction below can be removed.\n\n# Until then, the SAST IaC scanners will run in the downstream pipelines,\nbut their results will not be available directly in the merge request\nwidget, making it harder to track them.\n\n# Note: This workaround is perfectly safe and will not slow down your\npipeline.\n\ninclude:\n  - template: Security/SAST-IaC.gitlab-ci.yml\n#### END TWEAK\n\n\n```\n\n\nこのパイプラインは、`test`と`environments`の2つのステージのみを実行します。前者は、*TWEAK（微調整）*により、スキャナーを実行するために必要です。後者では、上記で定義したケース（ブランチへのプッシュ、デフォルトブランチへのマージ、タグ付け）ごとに異なる変数セットを持つ子パイプラインがトリガーされます。\n\n\nここで子パイプラインに[strategy:depend](https://docs.gitlab.com/ee/ci/yaml/index.html#triggerstrategy)キーワードで依存を追加します。これにより、デプロイの完了後にGitLabのパイプラインビューが更新されます。\n\n\nご覧のとおりベースとなるジョブが[無効になる](https://docs.gitlab.com/ee/ci/jobs/#hide-jobs)ように定義し、特定の変数とルールで拡張して、ターゲット環境ごとに単一のデプロイメントだけがトリガーされるようにしています。\n\n\n[定義済み変数](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html)に加え、定義する必要がある新たな2つのエントリを使用します。\n\n1. 各環境[固有の変数](#the-variable-definitions)：`../vars/$variables_file.tfvars`\n\n2. [子パイプライン](#the-child-pipeline)。`.gitlab-ci/.first-layer.gitlab-ci.yml`で定義\n\n\nまずは、簡単な方、つまり変数の定義から始めましょう。\n\n\n### 変数の定義\n\n\nここでは、2つのソリューションを組み合わせてTerraformに変数を提供します。\n\n\n*\n1つ目は、[.tfvarsファイル](https://developer.hashicorp.com/terraform/language/values/variables#variable-definitions-tfvars-files)を使用して、機密性の低い入力をすべて行う方法です。これはGitLab内に保存する必要があります。\n\n\n![Terraformに変数を提供するための1つ目のソリューション](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097034/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750097033419.png)\n\n\n*\n2つ目は、プレフィックスに`TF_VAR`を付けた[環境変数](https://developer.hashicorp.com/terraform/language/values/variables#environment-variables)を使用する方法です。変数を挿入するこの2つ目の方法は、[変数をマスク](https://docs.gitlab.com/ee/ci/variables/#mask-a-cicd-variable)し、[保護](https://docs.gitlab.com/ee/ci/variables/#protect-a-cicd-variable)し、さらに[スコープの環境を設定する](https://docs.gitlab.com/ee/ci/environments/index.html#limit-the-environment-scope-of-a-cicd-variable)GitLabの機能とも関係する、**機密情報の漏えいを防ぐ**強力なソリューションです（本番環境のプライベートClassless\nInter-Domain\nRouting（CIDR）で非常に機密性が高いデータをやり取りすると考えられる場合は、この方法で保護すれば、本番環境、および保護ブランチやタグに対して実行されるパイプラインでのみ利用できるようにし、ジョブのログでその値がマスクされるようにすることができます）。\n\n\n![Terraformに変数を提供するための2つ目のソリューション](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097034/Blog/Content%20Images/Blog/Content%20Images/image4_aHR0cHM6_1750097033422.png)\n\n\nまた、各変数ファイルを変更できるユーザーを設定するために、[`CODEOWNERS`ファイル](https://docs.gitlab.com/ee/user/project/codeowners/)で各変数ファイルを管理する必要があります。\n\n\n```\n\n[Production owners] \n\nvars/production.tfvars @operations-group\n\n\n[Staging owners]\n\nvars/staging.tfvars @odupre @operations-group\n\n\n[CodeOwners owners]\n\nCODEOWNERS @odupre\n\n```\n\n\nこの記事は、Terraformのトレーニング用ではないため、詳しく説明せず、ここでは`vars/review.tfvars`ファイルを紹介するだけに留めます。当然ながら、これに続く環境ファイルもほぼ同じです。ここでは機密性の低い変数とその値を設定するだけです。\n\n\n```shell\n\naws_vpc_cidr = \"10.1.0.0/16\"\n\naws_public_subnet_cidr = \"10.1.1.0/24\"\n\naws_private_subnet_cidr = \"10.1.2.0/24\"\n\n```\n\n\n#### 子パイプライン\n\n\n実際の作業はこのパイプライン内で行われます。そのため、最初のパイプラインよりも少し複雑です。しかしながら、力を合わせれば何でも乗り越えられます！\n\n\n[メインパイプライン](#the-main-pipeline)の定義で説明したように、ダウンストリームパイプラインは`.gitlab-ci/.first-layer.gitlab-ci.yml`で宣言されています。\n\n\n![ファイルで宣言されているダウンストリームパイプライン](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097033/Blog/Content%20Images/Blog/Content%20Images/image3_aHR0cHM6_1750097033424.png)\n\n\n小さなステップに分けて説明します。最後に全体像が見えるはずです。\n\n\n##### Terraformコマンドを実行してコードを保護する\n\n\nまずは、Terraformのパイプラインを実行したいと思います。GitLabはオープンソースであるため、Terraform用のテンプレートもオープンソースです。そのため、このテンプレートを含めるだけで済みます。以下のスニペットを使用して行えます。\n\n\n```yml\n\ninclude:\n  - template: Terraform.gitlab-ci.yml\n```\n\n\nこのテンプレートは、planとapplyが行われる前に、Terraformによるフォーマットのチェックとコードの検証を実行します。デプロイしたものを破棄することもできます。\n\n\nさらに、GitLabは統合された単一のDevSecOpsプラットフォームであるため、このテンプレート内に2つのセキュリティスキャナーを自動的に組み込み、コード内の潜在的な脅威を検出し、次の環境にデプロイされる前に警告を発します。\n\n\nこれでコードの確認、保護、ビルド、デプロイが完了したので、いくつかの便利な技をご紹介します。\n\n\n##### ジョブ間でキャッシュを共有する\n\n\nジョブの結果をキャッシュして、後続のパイプラインジョブで再利用します。これはとても簡単で、以下のコードを追加するだけで行えます。\n\n\n```yml\n\ndefault:\n  cache:  # Use a shared cache or tagged runners to ensure terraform can run on apply and destroy\n    - key: cache-$CI_COMMIT_REF_SLUG\n      fallback_keys:\n        - cache-$CI_DEFAULT_BRANCH\n      paths:\n        - .\n```\n\n\nここでは、コミットごとに異なるキャッシュを定義し、必要に応じてmainブランチ名にフォールバックするようにします。\n\n\n使用しているテンプレートをよく見ると、ジョブの実行タイミングを制御するルールがあることがわかります。全ブランチですべての制御（QAとセキュリティの両方）を実行したいと思います。そのため、次にこれらの設定を上書きします。\n\n\n##### すべてのブランチで制御を実行する\n\n\nGitLabテンプレートは強力な機能で、テンプレートの一部のみを上書きできます。品質チェックとセキュリティチェックが必ず実行されるよう、一部のジョブのルールを上書きしたいと思います。これらのジョブ向けに定義するその他すべては、テンプレートで定義された内容のままにします。\n\n\n```yml\n\nfmt:\n  rules:\n    - when: always\n\nvalidate:\n  rules:\n    - when: always\n\nkics-iac-sast:\n  rules:\n    - when: always\n\niac-sast:\n  rules:\n    - when: always\n```\n\n\nこれで品質とセキュリティの制御を実施できたため、[ワークフロー](#the-workflow)内のメインの環境（integrationとstaging）とreview環境の動作に違いを付けたいと思います。まずはメインの環境の振る舞いを定義し、review環境用にこの設定を微調整していきましょう。\n\n\n##### integrationとstaging環境への継続的デプロイ\n\n\n前述のように、この2つの環境にmainブランチとタグをデプロイしたいため、そのように制御するルールを`build`と`deploy`の両方のジョブに追加します。そして、`integration`環境でのみ`destroy`を有効にします。`staging`環境は重要度が高いため、ワンクリックで削除できないようにします。この操作はエラーを引き起こしやすく、避けたいと考えています。\n\n\n最後に、`deploy`ジョブを`destroy`ジョブにリンクして、GitLab GUIから直接環境を`stop`できるようにします。\n\n\nここで使用する`GIT_STRATEGY`は、破棄する際にRunner内のソースブランチからコードが取得されることを防ぎます。これは、ブランチが手動で削除された場合は失敗するため、キャッシュを使用して、Terraformの命令を実行するために必要なものすべてを取得します。\n\n\n```yml\n\nbuild:  # terraform plan\n  environment:\n    name: $TF_STATE_NAME\n    action: prepare\n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n    - if: $CI_COMMIT_TAG\n\ndeploy: # terraform apply --> automatically deploy on corresponding env\n(integration or staging) when merging to default branch or tagging. Second\nlayer environments (qa and production) will be controlled manually\n  environment: \n    name: $TF_STATE_NAME\n    action: start\n    on_stop: destroy\n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n    - if: $CI_COMMIT_TAG\n\ndestroy:\n  extends: .terraform:destroy\n  variables:\n    GIT_STRATEGY: none\n  dependencies:\n    - build\n  environment:\n    name: $TF_STATE_NAME\n    action: stop\n  rules:\n    - if: $CI_COMMIT_TAG  # Do not destroy production\n      when: never\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $TF_DESTROY == \"true\" # Manually destroy integration env.\n      when: manual\n```\n\n前述のとおり、これは`integration`と`staging`環境へのデプロイというニーズに即しています。しかしながら、デベロッパーがほかの人に影響を及ぼさずに、自分のコードに触れて検証できる一時的な環境がまだ不足しています。そのため、次は`review`環境へのデプロイを行います。\n\n\n##### review環境への継続的デプロイ\n\n\nreview環境へのデプロイは、`integration`や`staging`環境へのデプロイと大差はありません。そこで、ここでもGitLabの機能を活用して、ジョブ定義の一部のみを上書きします。\n\n\nまずは、これらのジョブがフィーチャーブランチでのみ実行されるようルールを設定します。\n\n\n次に、`deploy_review`ジョブを`destroy_review`ジョブにリンクします。これにより、GitLabユーザーインターフェイスから**手動で**環境を停止できるようになりますが、さらに重要なのは、フィーチャーブランチの完了時に**環境の破棄が自動的にトリガー**されるようになります。これは、運用にかかる費用を抑えるのに効果的な、優れたFinOpsプラクティスです。\n\n\nTerraformでは、インフラストラクチャの構築時と同様に、破棄する際にもplanファイルが必要なため、`destroy_review`から`build_review`に依存を追加して、そのアーティファクトを取得します。\n\n\n最後に、ご覧のとおり、環境の名前を`$environment`に設定します。これは、[メインパイプライン](#the-main-pipeline)で`review/$CI_COMMIT_REF_SLUG`に設定され、`trigger:forward:yaml_variables:true`という命令により、その子パイプラインに転送されます。\n\n\n```yml\n\nbuild_review:\n  extends: build\n  rules:\n    - if: $CI_COMMIT_TAG\n      when: never\n    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n      when: on_success\n\ndeploy_review:\n  extends: deploy\n  dependencies:\n    - build_review\n  environment:\n    name: $environment\n    action: start\n    on_stop: destroy_review\n    # url: https://$CI_ENVIRONMENT_SLUG.example.com\n  rules:\n    - if: $CI_COMMIT_TAG\n      when: never\n    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n      when: on_success\n\ndestroy_review:\n  extends: destroy\n  dependencies:\n    - build_review\n  environment:\n    name: $environment\n    action: stop\n  rules:\n    - if: $CI_COMMIT_TAG  # Do not destroy production\n      when: never\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH   # Do not destroy staging\n      when: never\n    - when: manual\n```\n\n\nさて、まとめると、これで次のことを行うパイプラインができました。\n\n\n* 一時的なreview環境へのデプロイ。フィーチャーブランチの完了時に、自動的にクリーンアップされます\n\n* **デフォルトブランチ**から`integration`への継続的デプロイ\n\n* **タグ**から`staging`への継続的デプロイ\n\n\nさらにレイヤを追加し、今回は手動でのトリガーをもとに`qa`と`production`環境にデプロイされるようにしましょう。\n\n\n##### qaとproduction環境への継続的デプロイ\n\n\n誰もが本番環境に継続的デプロイしたいわけではないため、次の2つのデプロイには手動による検証を追加します。単に**CD**の観点で考えた場合、このトリガーを追加することはありませんが、ほかのトリガーからジョブを実行する方法を学ぶ機会として捉えてください。\n\n\nこれまでデプロイを実行する際は、必ず[メインパイプライン](#the-main-pipeline)から[子パイプライン](#the-child-pipeline)を開始してきました。\n\n\nデフォルトブランチとタグからさらにデプロイを実行したいため、これらの追加ステップ用に別のレイヤを追加します。新たな手順は必要ありません。[メインパイプライン](#the-main-pipeline)で行ったのとまったく同じプロセスを再度繰り返します。この方法だと、必要な数だけレイヤを操作できます。中には最大で9つの環境がある例も見たことがあります。環境の数を抑えることの利点についてはあらためて説明しませんが、このプロセスを使用することで、初期段階から最終的なデリバリーまで、同じパイプラインを非常に簡単に実装できます。その上、パイプラインの定義をシンプルに保ちつつ、コストをかけずに維持できる小さな塊に分割可能です。\n\n\nここでは変数の競合を防ぐために、新しいvar名を使用してTerraformの状態と入力ファイルを識別しています。\n\n\n```yml\n\n.2nd_layer:\n  stage: 2nd_layer\n  variables:\n    TF_ROOT: terraform\n  trigger:\n    include: .gitlab-ci/.second-layer.gitlab-ci.yml\n    # strategy: depend            # Do NOT wait for the downstream pipeline to finish to mark upstream pipeline as successful. Otherwise, all pipelines will fail when reaching the pipeline timeout before deployment to 2nd layer.\n    forward:\n      yaml_variables: true      # Forward variables defined in the trigger job\n      pipeline_variables: true  # Forward manual pipeline variables and scheduled pipeline variables\n\nqa:\n  extends: .2nd_layer\n  variables:\n    TF_STATE_NAME_2: qa\n    environment: $TF_STATE_NAME_2\n    TF_CLI_ARGS_plan_2: \"-var-file=../vars/$TF_STATE_NAME_2.tfvars\"\n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n\nproduction:\n  extends: .2nd_layer\n  variables:\n    TF_STATE_NAME_2: production\n    environment: $TF_STATE_NAME_2\n    TF_CLI_ARGS_plan_2: \"-var-file=../vars/$TF_STATE_NAME_2.tfvars\"\n  rules:\n    - if: $CI_COMMIT_TAG\n```\n\n\n**ここで重要なテクニックは、新しいダウンストリームパイプラインに使用するstrategyの設定です。**`trigger:strategy`はデフォルトの値のままにしておきます。そうしなければ、[メインパイプライン](#the-main-pipeline)は、[孫パイプライン](#the-grand-child-pipeline)が完了するまで待機することになります。手動トリガーだと、非常に長い時間かかり、パイプラインダッシュボードが読みづらく、理解しにくくなる可能性があります。\n\n\nここでインクルードした`.gitlab-ci/.second-layer.gitlab-ci.yml`ファイルが何なのか疑問に感じた方もいらっしゃるかもしれません。こちらは次のセクションで説明します。\n\n\n##### 1つ目のレイヤのパイプラインに関する全定義\n\n\n1つ目のレイヤの全詳細（`.gitlab-ci/.first-layer.gitlab-ci.yml`に保存）を確認したい場合は、以下のセクションを参照してください。\n\n\n```yml\n\nvariables:\n  TF_VAR_aws_ami_id: $AWS_AMI_ID\n  TF_VAR_aws_instance_type: $AWS_INSTANCE_TYPE\n  TF_VAR_aws_default_region: $AWS_DEFAULT_REGION\n\ninclude:\n  - template: Terraform.gitlab-ci.yml\n\ndefault:\n  cache:  # Use a shared cache or tagged runners to ensure terraform can run on apply and destroy\n    - key: cache-$CI_COMMIT_REF_SLUG\n      fallback_keys:\n        - cache-$CI_DEFAULT_BRANCH\n      paths:\n        - .\n\nstages:\n  - validate\n  - test\n  - build\n  - deploy\n  - cleanup\n  - 2nd_layer       # Use to deploy a 2nd environment on both the main branch and on the tags\n\nfmt:\n  rules:\n    - when: always\n\nvalidate:\n  rules:\n    - when: always\n\nkics-iac-sast:\n  rules:\n    - if: $SAST_DISABLED == 'true' || $SAST_DISABLED == '1'\n      when: never\n    - if: $SAST_EXCLUDED_ANALYZERS =~ /kics/\n      when: never\n    - when: on_success\n\niac-sast:\n  rules:\n    - if: $SAST_DISABLED == 'true' || $SAST_DISABLED == '1'\n      when: never\n    - if: $SAST_EXCLUDED_ANALYZERS =~ /kics/\n      when: never\n    - when: on_success\n\n###########################################################################################################\n\n## Integration env. and Staging. env\n\n##  * Auto-deploy to Integration on merge to main.\n\n##  * Auto-deploy to Staging on tag.\n\n##  * Integration can be manually destroyed if TF_DESTROY is set to true.\n\n##  * Destroy of next env. is not automated to prevent errors.\n\n###########################################################################################################\n\nbuild:  # terraform plan\n  environment:\n    name: $TF_STATE_NAME\n    action: prepare\n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n    - if: $CI_COMMIT_TAG\n\ndeploy: # terraform apply --> automatically deploy on corresponding env\n(integration or staging) when merging to default branch or tagging. Second\nlayer environments (qa and production) will be controlled manually\n  environment: \n    name: $TF_STATE_NAME\n    action: start\n    on_stop: destroy\n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n    - if: $CI_COMMIT_TAG\n\ndestroy:\n  extends: .terraform:destroy\n  variables:\n    GIT_STRATEGY: none\n  dependencies:\n    - build\n  environment:\n    name: $TF_STATE_NAME\n    action: stop\n  rules:\n    - if: $CI_COMMIT_TAG  # Do not destroy production\n      when: never\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $TF_DESTROY == \"true\" # Manually destroy integration env.\n      when: manual\n###########################################################################################################\n\n\n###########################################################################################################\n\n## Dev env.\n\n##  * Temporary environment. Lives and dies with the Merge Request.\n\n##  * Auto-deploy on push to feature branch.\n\n##  * Auto-destroy on when Merge Request is closed.\n\n###########################################################################################################\n\nbuild_review:\n  extends: build\n  rules:\n    - if: $CI_COMMIT_TAG\n      when: never\n    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n      when: on_success\n\ndeploy_review:\n  extends: deploy\n  dependencies:\n    - build_review\n  environment:\n    name: $environment\n    action: start\n    on_stop: destroy_review\n    # url: https://$CI_ENVIRONMENT_SLUG.example.com\n  rules:\n    - if: $CI_COMMIT_TAG\n      when: never\n    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n      when: on_success\n\ndestroy_review:\n  extends: destroy\n  dependencies:\n    - build_review\n  environment:\n    name: $environment\n    action: stop\n  rules:\n    - if: $CI_COMMIT_TAG  # Do not destroy production\n      when: never\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH   # Do not destroy staging\n      when: never\n    - when: manual\n###########################################################################################################\n\n\n###########################################################################################################\n\n## Second layer\n\n##  * Deploys from main branch to qa env.\n\n##  * Deploys from tag to production.\n\n###########################################################################################################\n\n.2nd_layer:\n  stage: 2nd_layer\n  variables:\n    TF_ROOT: terraform\n  trigger:\n    include: .gitlab-ci/.second-layer.gitlab-ci.yml\n    # strategy: depend            # Do NOT wait for the downstream pipeline to finish to mark upstream pipeline as successful. Otherwise, all pipelines will fail when reaching the pipeline timeout before deployment to 2nd layer.\n    forward:\n      yaml_variables: true      # Forward variables defined in the trigger job\n      pipeline_variables: true  # Forward manual pipeline variables and scheduled pipeline variables\n\nqa:\n  extends: .2nd_layer\n  variables:\n    TF_STATE_NAME_2: qa\n    environment: $TF_STATE_NAME_2\n    TF_CLI_ARGS_plan_2: \"-var-file=../vars/$TF_STATE_NAME_2.tfvars\"\n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n\nproduction:\n  extends: .2nd_layer\n  variables:\n    TF_STATE_NAME_2: production\n    environment: $TF_STATE_NAME_2\n    TF_CLI_ARGS_plan_2: \"-var-file=../vars/$TF_STATE_NAME_2.tfvars\"\n  rules:\n    - if: $CI_COMMIT_TAG\n###########################################################################################################\n\n```\n\n\nこの段階で、すでに3つの環境に問題なくデプロイしています。個人的にはこのアプローチが理想的でおすすめです。ただし、もっと多くの環境が必要であれば、CDパイプラインに追加してください。\n\n\n`trigger:include`というキーワードでダウンストリームパイプラインをインクルードしていることはすでにお気づきだと思います。これにより、`.gitlab-ci/.second-layer.gitlab-ci.yml`ファイルがインクルードされます。ほぼ同じパイプラインを実行したいため、当然ながら先ほど詳しく説明したものと内容は非常に似ています。ここで[孫パイプライン](#the-grand-child-pipeline)を定義する主な利点は、それ自体が独立しているため、変数やルールを非常に定義しやすくことです。\n\n\n### 孫パイプライン\n\n\nこの2つ目のレイヤとなるパイプラインは、まったく新しいパイプラインです。そのため、1つ目のレイヤの定義を模倣しつつ、以下を行う必要があります。\n\n\n* [Terraformテンプレートのインクルード](#run-terraform-commands-and-secure-the-code)。\n\n*\n[セキュリティチェックの実施](#run-controls-on-all-branches)。Terraformの検証は1つ目のレイヤと重複するものの、セキュリティスキャナーにより以前にスキャナーが実行されたときにはまだ存在していなかった脅威を見つけられる可能性があります（stagingへのデプロイの数日後にproductionへのデプロイを行う場合など）。\n\n*\n[buildとdeployジョブを上書きして特定のルールを設定](#cd-to-review-environments)。早すぎる削除を防ぐために、`destroy`ステージは自動化されないようになったことにご注意ください。\n\n\n上述のとおり、`TF_STATE_NAME`と`TF_CLI_ARGS_plan`は、[メインパイプライン](#the-main-pipeline)から[子パイプライン](#the-child-pipeline)に渡されています。これらの値を[子パイプライン](#the-child-pipeline)から[孫パイプライン](#the-grand-child-pipeline)に渡すには、別の変数名が必要でした。そのため、子パイプラインでは変数名の末尾に`_2`を付け足し、`before_script`の実行中に適切な変数に値をコピーしています。\n\n\n各ステップについては説明済みであるため、ここでは細かいところは省き、直接グローバルな2つ目のレイヤの定義（`.gitlab-ci/.second-layer.gitlab-ci.yml`に保存）の全体像をご確認ください。\n\n\n```yml\n\n# Use to deploy a second environment on both the default branch and the\ntags.\n\n\ninclude:\n  template: Terraform.gitlab-ci.yml\n\nstages:\n  - validate\n  - test\n  - build\n  - deploy\n\nfmt:\n  rules:\n    - when: never\n\nvalidate:\n  rules:\n    - when: never\n\nkics-iac-sast:\n  rules:\n    - if: $SAST_DISABLED == 'true' || $SAST_DISABLED == '1'\n      when: never\n    - if: $SAST_EXCLUDED_ANALYZERS =~ /kics/\n      when: never\n    - when: always\n\n###########################################################################################################\n\n## QA env. and Prod. env\n\n##  * Manually trigger build and auto-deploy in QA\n\n##  * Manually trigger both build and deploy in Production\n\n##  * Destroy of these env. is not automated to prevent errors.\n\n###########################################################################################################\n\nbuild:  # terraform plan\n  cache:  # Use a shared cache or tagged runners to ensure terraform can run on apply and destroy\n    - key: $TF_STATE_NAME_2\n      fallback_keys:\n        - cache-$CI_DEFAULT_BRANCH\n      paths:\n        - .\n  environment:\n    name: $TF_STATE_NAME_2\n    action: prepare\n  before_script:  # Hack to set new variable values on the second layer, while still using the same variable names. Otherwise, due to variable precedence order, setting new value in the trigger job, does not cascade these new values to the downstream pipeline\n    - TF_STATE_NAME=$TF_STATE_NAME_2\n    - TF_CLI_ARGS_plan=$TF_CLI_ARGS_plan_2\n  rules:\n    - when: manual\n\ndeploy: # terraform apply\n  cache:  # Use a shared cache or tagged runners to ensure terraform can run on apply and destroy\n    - key: $TF_STATE_NAME_2\n      fallback_keys:\n        - cache-$CI_DEFAULT_BRANCH\n      paths:\n        - .\n  environment: \n    name: $TF_STATE_NAME_2\n    action: start\n  before_script:  # Hack to set new variable values on the second layer, while still using the same variable names. Otherwise, due to variable precedence order, setting new value in the trigger job, does not cascade these new values to the downstream pipeline\n    - TF_STATE_NAME=$TF_STATE_NAME_2\n    - TF_CLI_ARGS_plan=$TF_CLI_ARGS_plan_2\n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n    - if: $CI_COMMIT_TAG && $TF_AUTO_DEPLOY == \"true\"\n    - if: $CI_COMMIT_TAG\n      when: manual\n###########################################################################################################\n\n```\n\n\nこれで**準備完了です。**\n本番環境にデプロイする前に、ジョブの実行を管理する方法は自由に変更できます。たとえば、GitLabの機能を活用して、本番環境へのデプロイ前に[ジョブを遅延させる](https://docs.gitlab.com/ee/ci/jobs/job_control.html#run-a-job-after-a-delay)設定をすることも可能です。\n\n\n## 実際に試す\n\n\nついに目標を達成できました。**フィーチャーブランチ**、**mainブランチ**、**タグ**だけで、**5つの異なる環境へのデプロイ**を管理できるようになりました。\n\n* パイプラインの効率とセキュリティを確保するために、GitLabのオープンソーステンプレートを集中的に再利用しました。\n\n* GitLabテンプレートの機能を活用して、個別に制御が必要なブロックだけを上書きしました。\n\n* パイプラインを小さな塊に分割し、ニーズに完全に合うようにダウンストリームパイプラインを制御しました。\n\n\nここからは、自由に進めてください。たとえば、[trigger:rules:changes](https://docs.gitlab.com/ee/ci/yaml/#ruleschanges)キーワードを使って、ソフトウェアのソースコードのダウンストリームパイプラインをトリガーするように、メインパイプラインを簡単に更新することも可能です。また、発生した変更に応じて、別の[テンプレート](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/)を使用できます。その方法はまた別の機会に。\n",[111,936,937,893,681],"CI","CD","2025-06-12",{"slug":940,"featured":6,"template":684},"using-child-pipelines-to-continuously-deploy-to-five-environments","content:ja-jp:blog:using-child-pipelines-to-continuously-deploy-to-five-environments.yml","Using Child Pipelines To Continuously Deploy To Five Environments","ja-jp/blog/using-child-pipelines-to-continuously-deploy-to-five-environments.yml","ja-jp/blog/using-child-pipelines-to-continuously-deploy-to-five-environments",{"_path":946,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":947,"content":953,"config":959,"_id":961,"_type":16,"title":962,"_source":18,"_file":963,"_stem":964,"_extension":21},"/ja-jp/blog/building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way",{"title":948,"description":949,"ogTitle":948,"ogDescription":949,"noIndex":6,"ogImage":950,"ogUrl":951,"ogSiteName":776,"ogType":802,"canonicalUrls":951,"schema":952},"モノレポ用のGitLab CI/CDパイプラインを簡単に構築する方法","単一のリポジトリで複数のアプリケーションをホストするモノレポ用に、GitLab CI/CDパイプラインを作成する方法についてご紹介します。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749660151/Blog/Hero%20Images/blog-image-template-1800x945__26_.png","https://about.gitlab.com/blog/building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"モノレポ用のGitLab CI/CDパイプラインを簡単に構築する方法\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sam Morris\"}],\n        \"datePublished\": \"2024-07-30\",\n      }",{"title":948,"description":949,"authors":954,"heroImage":950,"date":956,"body":957,"category":14,"tags":958},[955],"Sam Morris","2024-07-30","モノレポを使用すると、単一のリポジトリで複数のアプリケーションのコードをホストできます。GitLabでこれを実現しようとすると、プロジェクト内の各ディレクトリに異なるアプリケーションのソースコードを配置することになります。この方法だとコードの保存場所をバージョン管理できるものの、GitLabの[CI/CD](https://about.gitlab.com/ja-jp/topics/ci-cd/)パイプライン機能を最大限に活用するのは困難でした。しかしながら、新たな方法が登場しました！\n\n\n## モノレポにおけるCI/CDの理想的な実例\n\n\n通常、リポジトリには複数のアプリケーションのコードが格納されているため、複数のパイプライン設定が必要となります。たとえば、.NETアプリケーションとSpringアプリケーションがあるプロジェクトの場合、アプリケーションごとに異なるビルドジョブとテストジョブを実施している可能性があります。この場合、パイプラインを完全に切り離し、特定のアプリケーションのソースコードの変更が発生した場合のみ、各パイプラインを実行するのが理想的です。\n\n\nこのようなプロセスを技術的に実現するには、特定のディレクトリの変更に基づいて特定のYAMLファイルをインクルードする、プロジェクトレベルのパイプライン設定ファイル`.gitlab-ci.yml`を用意します。`.gitlab-ci.yml`パイプラインは、コードに加えられた変更に基づき、適切なパイプラインをトリガーするコントロールプレーンとして機能します。\n\n\n## 従来のアプローチ\n\n\nGitLab\n16.4より前のバージョンでは、プロジェクト内のディレクトリまたはファイルへの変更に基づいてYAMLファイルをインクルードすることはできませんでした。ただし、回避策を使えばこの機能を実現することは可能でした。\n\n\nこれからご紹介するモノレポプロジェクトの例では、異なるアプリケーション用に2つのディレクトリがあるとします。それぞれJavaアプリ用の`java`ディレクトリとPythonアプリ用の`python`ディレクトリがあります。それぞれのディレクトリには、各アプリをビルドするためのアプリケーション固有のYAMLファイルが含まれています。シンプルにプロジェクトのパイプラインファイルに両アプリケーションのパイプラインファイルをインクルードし、それらのファイルで直接ロジック処理を行います。\n\n\n`.gitlab-ci.yml`：\n\n\n```\n\nstages:\n  - build\n  - test\n  - deploy\n\ntop-level-job:\n  stage: build\n  script:\n    - echo \"Hello world...\"\n\ninclude:\n  - local: '/java/j.gitlab-ci.yml'\n  - local: '/python/py.gitlab-ci.yml'\n\n```\n\n\nアプリケーション固有の各パイプラインファイルで「.java-common」もしくは「.python-common」という名前の非表示ジョブを作成します。これらのジョブは対応するアプリのディレクトリに変更が加えられた場合にのみ実行されます。デフォルトでは[非表示ジョブ](https://docs.gitlab.com/ee/ci/jobs/#hide-jobs)は実行されず、通常は特定のジョブ設定を再利用するために使用されます。各パイプラインは、非表示ジョブを拡張して変更がないか監視するファイルを定めたルールを継承してから、パイプラインジョブを開始します。\n\n\n`j.gitlab-ci.yml`：\n\n\n```\n\nstages:\n  - build\n  - test\n  - deploy\n\n.java-common:\n  rules:\n    - changes:\n      - '../java/*'\n\njava-build-job:\n  extends: .java-common\n  stage: build\n  script:\n    - echo \"Javaのビルド\"\n\njava-test-job:\n  extends: .java-common\n  stage: test\n  script:\n    - echo \"Javaのテスト\"\n\n```\n\n\n`py.gitlab-ci.yml`：\n\n\n```\n\nstages:\n  - build\n  - test\n  - deploy\n\n.python-common:\n  rules:\n    - changes:\n      - '../python/*'\n\npython-build-job:\n  extends: .python-common\n  stage: build\n  script:\n    - echo \"Pythonのビルド\"\n\npython-test-job:\n  extends: .python-common\n  stage: test\n  script:\n    - echo \"Pythonのテスト\"\n\n```\n\n\nこの方法にはいくつかのデメリットがあります。たとえば、確実にルールに準拠するために、YAMLファイル内の他のジョブ用にそれぞれジョブを拡張しなければならないため、多くの冗長なコードが発生し、ヒューマンエラーが起きやすくなります。さらに拡張されたジョブでは重複するキーは持てないため、各ジョブにおいて独自の`rules`ロジックを定義できません。定義しようとした場合、キーの競合が発生し、[キーの値はマージされません](https://docs.gitlab.com/ee/ci/yaml/index.html#extends)。\n\n\n結果として、`java/`が更新されると、j.gitlab-ci.ymlジョブを含むパイプラインが実行され、`python/`が更新されると、py.gitlab-ci.ymlジョブを含むパイプラインが実行されます。\n\n\n## 新たなアプローチ：パイプラインファイルを条件付きでインクルードする\n\n\n\u003C!-- 空白行 -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/6phvk8jioAo?si=y6ztZODvUtM-cHmZ\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- 空白行 -->\n\n\nGitLab\n16.4では、[パイプライン向けに`rules:changes`を含む`include`](https://docs.gitlab.com/ee/ci/yaml/includes.html#include-with-ruleschanges)が導入されました。それまでは`include`に`rules:if`を使用することはできたものの、`rules:changes`は使用できませんでした。これは非常に強力なアップデートです。これにより、プロジェクトのパイプライン設定で`include`キーワードを使用するだけで、モノレポのルールを定義できるようになりました。\n\n\n新たな`.gitlab-ci.yml`：\n\n\n```\n\nstages:\n  - build\n  - test\n\ntop-level-job:\n  stage: build\n  script:\n    - echo \"Hello world...\"\n\ninclude:\n  - local: '/java/j.gitlab-ci.yml'\n    rules:\n      - changes:\n        - 'java/*'\n  - local: '/python/py.gitlab-ci.yml'\n    rules:\n      - changes:\n        - 'python/*'\n\n```\n\n\nその後、各アプリケーションのYAMLファイルにおいて非表示ジョブを何度も拡張せずに済むため、アプリケーションコードのビルドとテストだけに集中できます。これによって、より柔軟にジョブを定義できるようになり、エンジニアによるコードの書き直し作業が軽減します。\n\n\n新たな`j.gitlab-ci.yml`：\n\n\n```\n\nstages:\n  - build\n  - test\n  - deploy\n\njava-build-job:\n  stage: build\n  script:\n    - echo \"Javaのビルド\"\n\njava-test-job:\n  stage: test\n  script:\n    - echo \"Javaのテスト\"\n\n```\n\n\n新たな`py.gitlab-ci.yml`：\n\n```\n\nstages:\n  - build\n  - test\n  - deploy\n\npython-build-job:\n  stage: build\n  script:\n    - echo \"Pythonのビルド\"\n\npython-test-job:\n  stage: test\n  script:\n    - echo \"Pythonのテスト\"\n\n```\n\n\n上記の設定により、JavaとPythonのディレクトリがそれぞれ変更された場合にのみ、JavaまたはPythonのジョブをインクルードするという同じタスクを実行できます。実装時に考慮すべき点は、[`changes`を使用すると、ジョブが予期せぬタイミングで実行される可能性がある](https://docs.gitlab.com/ee/ci/jobs/job_troubleshooting.html#jobs-or-pipelines-run-unexpectedly-when-using-changes)ということです。新しいブランチやタグをGitLabにプッシュすると、changesルールは必ず「true」と評価されるため、`rules:changes`の定義内容にかかわらず、ブランチへの最初のプッシュ時に、含まれるすべてのジョブが実行されます。こういった事態がなるべく起こらないようにするために、まずはフィーチャーブランチを作成してからマージリクエストを開いて開発を始めることをおすすめします。ブランチの作成時に最初にプッシュすることで、すべてのジョブが強制的に実行されるためです。\n\n\n総括すると、モノレポはGitLabおよびCI/CDと組み合わせて、戦略的に利用できる手法です。新たな`rules:changes`機能を含む`include`キーワードの登場により、GitLab\nCIにおいてモノレポを使う際に適用できる優れたベストプラクティスができました。モノレポの利用をお考えの場合は、ぜひGitlab\nUltimateの無料トライアルをご利用ください。\n\n\n## CI/CDに関するその他のリソース\n\n\n*\n[GitLabでモノレポを管理するためのヒント5選](https://about.gitlab.com/blog/tips-for-managing-monorepos-in-gitlab/)\n\n*\n[CI/CDについて素早く学ぶ方法](https://about.gitlab.com/blog/how-to-learn-ci-cd-fast/)\n",[111,681],{"slug":960,"featured":6,"template":684},"building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way","content:ja-jp:blog:building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way.yml","Building A Gitlab Ci Cd Pipeline For A Monorepo The Easy Way","ja-jp/blog/building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way.yml","ja-jp/blog/building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way",{"_path":966,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":967,"content":973,"config":981,"_id":983,"_type":16,"title":984,"_source":18,"_file":985,"_stem":986,"_extension":21},"/ja-jp/blog/demystifying-ci-cd-variables",{"title":968,"description":969,"ogTitle":968,"ogDescription":969,"noIndex":6,"ogImage":970,"ogUrl":971,"ogSiteName":776,"ogType":802,"canonicalUrls":971,"schema":972},"GitLabの環境変数をわかりやすく解説","CI/CD変数はジョブやパイプラインを制御するのに便利（かつ柔軟に利用可能）なツールです。この記事では、GitLabの環境変数について知っておくべき情報をすべてご紹介します。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664679/Blog/Hero%20Images/blog-image-template-1800x945__24_.png","https://about.gitlab.com/blog/demystifying-ci-cd-variables","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLabの環境変数をわかりやすく解説\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Veethika Mishra\"}],\n        \"datePublished\": \"2021-04-09\",\n      }",{"title":968,"description":969,"authors":974,"heroImage":970,"date":976,"body":977,"category":14,"tags":978,"updatedDate":980},[975],"Veethika Mishra","2021-04-09","[CI/CD](https://about.gitlab.com/ja-jp/topics/ci-cd/)変数は、さまざまな方法で定義・使用でき、高い柔軟性を持っています。変数はジョブやパイプラインを制御する上で非常に便利で、`.gitlab-ci.yml`設定ファイルに値をハードコーディングせずに済みます。このブログ記事では、変数のスコープや機能を分かりやすくお伝えするため、変数の定義や使い方に関する情報を網羅的に整理し、全体像をご紹介します。記事全体をとおして、関連するドキュメントがリンクされています。\n\n\n[GitLab\nCI/CD](https://docs.gitlab.com/ee/ci/)では、値を定義して保存することで、変数を使用してジョブをカスタマイズできます。変数を使用すれば、値をハードコーディングする必要はありません。GitLabでCI/CD変数を定義するには、**「設定」>>「CI/CD」>>「変数」**の順に移動します。または`.gitlab-ci.yml`ファイルで定義することも可能です。\n\n\n変数は、異なるデプロイ環境（`testing`、`staging`、`production`など）におけるサードパーティサービスの設定に役立ちます。それらの環境に紐づけられたサービスは、必要なAPIエンドポイントを指す変数を変更するだけで、簡単に変更できます。また、変数を使用してジョブを設定し、ジョブ実行時にジョブ内で環境変数として利用できるようにすることも可能です。\n\n\n![GitLabは、.gitlab-ci.ymlファイルを読み込んで、参照される変数をスキャンし、GitLab\nRunnerにその情報を送信します。変数情報はRunnerに渡され、Runnerによって出力されます。](https://about.gitlab.com/images/blogimages/demystifying-ci-cd-variables/variables_processing.jpeg)\n\n\n## 変数と環境の関係\n\n\nソフトウェア開発プロセスには、製品をユーザー向けにリリースする前にテストするステージが含まれます。[環境](https://docs.gitlab.com/ee/ci/environments/)は、これらのステージの内容を定義するために使用されるもので、チームや組織によって異なる可能性があります。\n\n\n一方、変数とは、ユーザーによる製品の操作によって変化する可能性のあるデータ値を指します。これには、年齢や好み、またはタスクフローにおける次のステップを決定する要素となるあらゆる入力が該当します。\n\n\n[環境変数](https://docs.gitlab.com/ee/administration/environment_variables.html)という言葉は、皆さんもよく耳にされると思います。これは、ある環境で定義されているものの、アプリケーションの外部に存在する変数を指します。GitLab\nCI/CD変数を使用すると、デベロッパーはコード内で値を設定できます。変数の使用には、コードの柔軟性が保証されるという利点があります。GitLab\nCI/CD変数を使用すれば、コードに変更を加えることなく、特定の環境にデプロイされたアプリケーションを変更できます。これにより、アプリケーションの外部で設定の環境変数を変更するだけで、テストの実行やサードパーティサービスの統合を簡単に行えます。\n\n\n## CI/CD変数のスコープ\n\n\n![CI/CD変数の優先順位：1) 手動によって実行、トリガー、スケジュールされたパイプライン変数、2)\nプロジェクトレベル、グループレベル、インスタンスレベルの保護変数、3) 継承されたCI/CD変数、4)\nymlに定義された、ジョブレベルのグローバル変数、5) デプロイ変数、6)\n定義済みのCI/CD変数](https://about.gitlab.com/images/blogimages/demystifying-ci-cd-variables/variables_precedence.jpeg)\n\n\n### `.gitlab-ci.yml`に定義された変数\n\n\nGitLabには、ジョブ環境で利用する必要がある変数を追加できます。これらのCI/CD変数は、`.gitlab-ci.yml`ファイルのデータベースURLのような、機密性の低いプロジェクト設定を保存するために使用されます。この変数は、複数のジョブやスクリプトで再利用でき、必要な場所で値を参照できます。値を変更する場合は、変数を一度更新するだけで、変数が使用されているすべての箇所に変更が反映されます。\n\n\n### プロジェクトのCI/CD変数\n\n\nリポジトリ固有の要件に縛られることなく、[プロジェクト設定](https://docs.gitlab.com/ee/ci/variables/#for-a-project)でCI/CD変数を定義できます。これにより、CI/CDパイプラインで利用できるようになります。これらの変数は、リポジトリの外部（`.gitlab-ci.yml`ファイルには保存されません）に保存されますが、CI/CDの設定やスクリプトで引き続き利用可能です。変数を`.gitlab-ci.yml`ファイル外に保存することで、これらの値のスコープをプロジェクト内のみに限定し、プロジェクトにプレーンテキストとして保存されることを防ぎます。\n\n\n### グループおよびインスタンスのCI/CD変数\n\n\n一部の変数は、グループレベル、あるいはインスタンスレベルで適用でき、グループやインスタンス内のすべてのプロジェクトで有用となる可能性があります。[グループまたはインスタンス設定](https://docs.gitlab.com/ee/ci/variables/#for-a-group)で変数を定義することで、それらのスコープ内にあるすべてのプロジェクトにおいて、実際の値がわからなくても、変数を使用できるようになります。下位スコープの変数を作成する必要もありません。たとえば、複数のプロジェクトにおいて更新が必要な共通の値がある場合、1か所で最新の状態に保つことで管理しやすくなります。また、パスワードの値を実際に知らなくても、複数のプロジェクトで特定のパスワードを使用することも可能です。\n\n\n## 環境としてのジョブとパイプライン\n\n\nGitLab\nCI/CDの変数は、環境変数としてだけでなく、`.gitlab-ci.yml`設定ファイル内でパイプラインの動作を設定するためにも使用されます。この場合、特定の環境に依存しない状況でも利用できます。また、プロジェクト、グループ、インスタンスの設定に保存しておくことで、パイプライン内のジョブで利用可能になります。\n\n\n以下に例を示します。\n\n\n```  \n\njob:  \n  rules:  \n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH  \n  script:  \n  - echo \"This job ran on the $CI_COMMIT_BRANCH branch.\"  \n```\n\n\nスクリプトセクション内で使用されている変数（例：`$CI_COMMIT_BRANCH`）は、定義されたジョブのスコープ内で実行されます。このスコープは「ジョブ環境」と呼ばれます。つまり、ジョブが開始されると、GitLab\nRunnerはDockerコンテナを起動し、その環境でジョブを実行します。Runnerはその変数（および他のすべての定義済み変数やカスタム変数）をジョブに提供します。さらに、その値をログ出力に表示することも可能です。\n\n\nただし、この変数は、ジョブの実行タイミングを決定するために、`if:`セクション**でも**使用されます。ただし、そのセクション自体は環境ではないため、これらの変数を「CI/CD変数」と呼びます。CI/CDジョブを動的に設定する際に使用できるのは**もちろん**、ジョブの実行時に環境変数としても利用できます。\n\n\n## 定義済み変数\n\n\nGitLab\nCI/CDパイプラインが開始されたタイミングで、[定義済み変数](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html)がすでに存在します。ユーザーは変数自体を定義せずに、コミットやプロジェクト、パイプラインの詳細などの値にすぐにアクセスできます。\n\n\n## カスタムCI/CD変数\n\n\n![Runnerは、2種類のカスタムCI/CD変数（タイプとファイル）を作成できます。](https://about.gitlab.com/images/blogimages/demystifying-ci-cd-variables/variable_types.jpeg)\n\n\nGitLabでは、設定でCI/CD変数を作成する際に、変数に対してより詳細な設定オプションを利用できます。次のような追加の設定オプションを使用して、機密性の高い変数をより厳密に管理することが可能です。\n\n\n**環境スコープ**：ある変数を特定の環境でのみ使用する必要がある場合に、その環境でのみ使用できるように設定します。たとえば、デプロイトークンを`production`環境でのみ使用できるように設定できます。\n\n\n**保護変数**：環境スコープと同様に、デフォルトブランチなどの保護ブランチでパイプラインが実行される場合にのみ、変数を使用できるように設定できます。\n\n\n**変数タイプ**：一部のアプリケーションでは、設定をファイル形式で渡す必要があります。そうした設定が必要なアプリケーションを利用する場合は、変数タイプを「File」に設定します。この方法でCI/CD変数を設定する場合、Runnerが環境内で変数を利用できるようにする際に、実際に一時ファイルに変数を書き出し、そのファイルパスを変数の値として保存します。その後、アプリケーションに必要なファイルパスを渡すことで設定が適用されます。\n\n\nご紹介した変数の定義方法や使用方法に加えて、GitLabでは、手動でパイプラインを実行する必要がある場合に、事前入力済みの変数を生成する機能が導入されました。事前入力済みの変数が生成されることで、エラーの発生リスクが軽減され、パイプラインを実行しやすくなります。\n\n\n**マスクされた変数**：[マスクされた変数](https://docs.gitlab.com/ee/ci/variables/#mask-a-cicd-variable)は、変数の値が表示されないように**ジョブログに隠された**CI変数です。\n\n\n**マスクおよび非表示化された変数**：[GitLab\n17.4](https://about.gitlab.com/ja-jp/blog/gitlab-17-4-released/)で導入された[マスクおよび非表示化された](https://docs.gitlab.com/ee/ci/variables/#hide-a-cicd-variable)変数は、ジョブログと同じマスキング機能を利用し、**設定UI**でも**値を非表示**にします。これらの変数を機密データ（シークレットなど）に使用した場合、誤って公開されてしまう可能性があるため、推奨されません。\n\n\n## シークレット\n\n\nシークレットとは、機密性が高く、秘密に保つべき認証情報のことを指し、以下のようなものが該当します。\n\n\n* パスワード\n\n* SSH鍵\n\n* アクセストークン\n\n* その他、漏洩すると組織に害を及ぼす可能性のある認証情報\n\n\nGitLabでは現在、キーやトークン、その他のシークレットをプロジェクトレベルで安全に管理するために、HashiCorp Vault、Google\nCloud Secret Manager、Azure Key\nVaultを活用できます。これにより、[CIで外部シークレットを使用](https://docs.gitlab.com/ee/ci/secrets/)することが可能です。そのため、セキュリティ上の理由から、これらのシークレットを他のCI/CD変数から分離して管理できます。\n\n\n### GitLabシークレットマネージャー\n\n\nGitLabでは、CIにおける外部シークレットのサポートに加えて、GitLab内でシークレットを安全かつ便利に保存するための[ネイティブなシークレット管理ソリューション](https://gitlab.com/groups/gitlab-org/-/epics/10108)の導入にも取り組んでいます。このソリューションは、お客様がGitLab固有のコンポーネントや環境で保存されたシークレットを使用したり、ネームスペースグループやプロジェクトレベルでのアクセスを簡単に管理したりする上でも役立ちます。\n\n\n## 関連リンク\n\n*\n[GitLabネイティブシークレットマネージャーでソフトウェアサプライチェーンのセキュリティを強化](https://about.gitlab.com/blog/gitlab-native-secrets-manager-to-give-software-supply-chain-security-a-boost/)\n\n\n***免責事項**：このブログには、今後リリース予定の製品、機能、および機能性に関する情報が記載されています。ただし、それらの情報はあくまで参考のために提供されているため、購入や計画の判断材料として使用することはお控えください。すべてのプロジェクトと同様に、このブログおよびリンク先のページに記載されている項目は、変更または遅延される場合があります。製品、機能、機能性の開発、リリース、およびタイミングに関する決定権は、GitLabに帰属します。*\n",[937,679,979,936,111,681],"inside GitLab","2025-01-13",{"slug":982,"featured":6,"template":684},"demystifying-ci-cd-variables","content:ja-jp:blog:demystifying-ci-cd-variables.yml","Demystifying Ci Cd Variables","ja-jp/blog/demystifying-ci-cd-variables.yml","ja-jp/blog/demystifying-ci-cd-variables",{"_path":988,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":989,"content":994,"config":1003,"_id":1005,"_type":16,"title":1006,"_source":18,"_file":1007,"_stem":1008,"_extension":21},"/ja-jp/blog/ci-deployment-and-environments",{"config":990,"ogImage":991,"description":992,"title":993},{"noIndex":6},"https://res.cloudinary.com/about-gitlab-com/image/upload/f_auto,q_auto,c_lfill/v1749662033/Blog/Hero%20Images/intro.jpg","GitLab CI の多様性とパワーをAWS(S3)を例に学び、デプロイに活かせる開発力を身に着けましょう。","GitLab CIを使って複数の環境にデプロイする方法 | GitLab",{"heroImage":991,"body":995,"authors":996,"updatedDate":999,"date":1000,"title":1001,"tags":1002,"description":992,"category":14},"いくつかのシナリオを通じて、[GitLab\n\n\nCI](https://about.gitlab.com/ja-jp/solutions/continuous-integration/)\n\n\nが持つ多様性と強みをご紹介します。\n\n\n\nこの投稿は、ある架空のニュースポータルのサクセスストーリーです。あなたは、そのポータルの所有者かつエディターで、唯一の開発者でもあります。プロジェクトコードは既に GitLab.com でホストされており、GitLab CI/CD で[テストを実行する (英語版)](https://docs.gitlab.com/ee/ci/testing/)こともできます。ここであなたは考えます。これを[デプロイに使う (英語版)](https://about.gitlab.com/blog/2022/02/03/how-to-keep-up-with-ci-cd-best-practices/)ことはできないだろうかと。そして、どこまで活用できるのだろう、と。\n\n\n\nこのサクセスストーリーを技術スタックに依存しないものにするために、このアプリは単なるHTML ファイルを集めたものだと仮定しましょう。サーバー側のコードも、高度な JavaScript のコンパイルもないものとします。\n\n\n\nデプロイ先のプラットフォームも単純なものにしましょう。ここでは、「[Amazon S3](https://aws.amazon.com/jp/s3/)」を使います。\n\n\n\nこの記事の目的は、コピー＆ペースト可能なスニペットを数多く紹介することではありません。[GitLab CI](https://about.gitlab.com/ja-jp/solutions/continuous-integration/) の基本原理や各種機能をご紹介し、それを現場の技術スタックに簡単に適用できるようにすることが目的です。\n\n\n\nそれでは、はじめましょう。このストーリーには、まだ、継続的インテグレーション (CI) は登場しません。\n\n\n\n\n\n## 最初のステップ\n\n\n\n**デプロイ**：今回、「デプロイ」とは、一連の HTML ファイルが ([静的な Web サイトホスティング ](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/HostingWebsiteOnS3Setup.html)用に設定済み) S3 バケット上に表示されることを意味します。\n\n\n\nこれを実現する方法は無数にあります。ここでは、Amazon から提供されている[ awscli ライブラリ (英語版)](http://docs.aws.amazon.com/cli/latest/reference/s3/cp.html#%E4%BE%8B) を使います。\n\n\n\nコマンドは、全体ではこのようになります。\n\n\n\n```shell\n\n\naws s3 cp ./ s3://yourbucket/ --recursive --exclude \"*\" --include \"*.html\"\n\n\n```\n\n\n\n![Manual deployment](https://about.gitlab.com/images/blogimages/ci-deployment-and-environments/13.jpg){: .center}\n\n\n\nリポジトリへのコードのプッシュと、デプロイは別々のプロセスです。\n\n\n\n{: .note .text-center}\n\n\n\n重要なポイント：このコマンドは、2 つの環境変数`AWS_ACCESS_KEY_ID` と  `AWS_SECRET_ACCESS_KEY` の指定を[コードデベロッパーが行なうものと想定](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-getting-started.html#config-settings-and-precedence)しています。また、\n\n\n\n重要なポイント：このコマンドは、2 つの環境変数 AWS_ACCESS_KEY_ID と AWS_SECRET_ACCESS_KEY の指定を[コードデベロッパーが行なうものと想定](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-getting-started.html#config-settings-and-precedence)しています。また、`AWS_DEFAULT_REGION` も指定する必要があるかもしれません。\n\n\n\nでは、[GitLab CI](https://about.gitlab.com/ja-jp/solutions/continuous-integration/) を使って自動化してみましょう。\n\n\n\n\n\n\n## **はじめての自動化デプロイ**\n\n\n\nGitLab では、どのコマンドを実行しても違いはありません。GitLab CI はユーザーの具体的なニーズに合わせて、あたかもコンピュータ上のローカルターミナルで操作している感覚でセットアップできます。ここで実行するコマンドをGitLabにも実行させるよう、CI に指定可能です。 `.gitlab-ci.yml`ファイルにスクリプトを記述し、コードをプッシュするだけです。これで、CI がジョブをトリガーし、指定コマンドが実行されます。\n\n\n\nでは、ここでストーリーにもう少し肉付けをしましょう。私たちの Web サイトは小規模で、1日あたり 20～30 人の訪問者がいるだけです。コードリポジトリには`main` という1つのデフォルトブランチ (があるものとします。\n\n\n\nそれでは、 `.gitlab-ci.yml` ファイルに、先程のコマンドを使った*ジョブ*を指定することから始めましょう。\n\n\n\n```yaml\n\n\ndeploy:\n  script: aws s3 cp ./ s3://yourbucket/ --recursive --exclude \"*\" --include \"*.html\"\n```\n\n\n\nうまくいかないようです：\n\n\n\n![Failed command](https://about.gitlab.com/images/blogimages/ci-deployment-and-environments/fail1.png){: .shadow}\n\n\n\n実行ファイルには`aws` が必要です。これを確認するのは、私たちの*ジョブ*です。`awscli` をインストールするには、pipが必要です。これは、Pythonパッケージのインストール用のツールです。では、Pythonが事前にインストール済みのDockerイメージを指定しましょう。これには`pip` が含まれているはずです。\n\n\n\n\n\n\n```yaml\n\n\ndeploy:\n  image: python:latest\n  script:\n  - pip install awscli\n  - aws s3 cp ./ s3://yourbucket/ --recursive --exclude \"*\" --include \"*.html\"\n```\n\n\n\n![Automated deployment](https://about.gitlab.com/images/blogimages/ci-deployment-and-environments/14.jpg){: .center}\n\n\n\nGitLab にコードをプッシュすると、CI により自動的にデプロイされます。awscli のインストールによりジョブの実行時間が伸びますがこの時点ではそれほど問題ではありません。プロセスを高速化する場合、awscliが事前にインストールされた [Docker イメージを探す (英語版)](https://hub.docker.com/)  ことが可能です。または、イメージをご自身で作成しても構いません。\n\n\n\nここで、[AWS コンソール (英語版) ](https://console.aws.amazon.com/)から取得した環境変数を忘れないでください。\n\n\n\n\n\n\n```yaml\n\n\nvariables:\n  AWS_ACCESS_KEY_ID: \"AKIAIOSFODNN7EXAMPLE\"\n  AWS_SECRET_ACCESS_KEY: \"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\"\ndeploy:\n  image: python:latest\n  script:\n  - pip install awscli\n  - aws s3 cp ./ s3://yourbucket/ --recursive --exclude \"*\" --include \"*.html\"\n```\n\n\n\n今回は上手くいくはずですが、シークレットキーをオープンにしたままにすることは、プライベートリポジトリであってもよくありません。ではどうすればよいのか、もう少し見てみましょう。\n\n\n\n### **シークレット事項を守り抜くために**\n\n\n\nGitLab にはシークレット変数用に特別な項目があります:  **Settings（設定） > CI/CD > Variables（変数）**\n\n\n\n![Picture of Variables page](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674076/Blog/Content%20Images/add-variable-updated.png)\n\n\n\nここに入力したものすべてが**環境変数**になります。「Visibility（表示レベル）」の「Masked（マスクする）」ラジオボタンをオンにすると、ジョブログ内で変数がマスクされます。「Protect variable（変数の保護）」チェックボックスにチェックを入れると、変数は保護されているブランチやタグ上で実行されているパイプラインにのみ、エクスポートされます。プロジェクトの「オーナー」や「メンテナー」の権限を持つユーザーが、このセクションにアクセスできます。\n\n\n\nCI 設定から、variables セクションを削除することも可能ですが、別の目的で使用してみましょう。\n\n\n\n\n\n\n### **シークレットではない変数を指定して使用する方法**\n\n\n\n構成が大きくなる場合、初期段階で、いくつかのパラメータを変数として設定しておくと便利です。これは特に、パラメータを複数の場面で使用する場合に便利です。今回のケースではまだそのような状況ではありませんが、デモとして、S3 バケット名を **[variable](https://docs.gitlab.com/ee/ci/variables/)** に設定してみましょう。\n\n\n\n```yaml\n\n\nvariables:\n  S3_BUCKET_NAME: \"yourbucket\"\ndeploy:\n  image: python:latest\n  script:\n  - pip install awscli\n  - aws s3 cp ./ s3://$S3_BUCKET_NAME/ --recursive --exclude \"*\" --include \"*.html\"\n```\n\n\n\nここまで、順調ですね。\n\n\n\n![Successful build](https://about.gitlab.com/images/blogimages/ci-deployment-and-environments/build.png){: .shadow.medium.center}\n\n\n\nこの架空シナリオでは、Web サイトの訪問者数が増えたため、開発者を雇いました。これでチームができました。チームワークにより、[GitLab CI](https://about.gitlab.com/ja-jp/solutions/continuous-integration/) ワークフローがどのように変化するのか、見てみましょう。\n\n\n\n\n\n\n## **GitLab CIをチームで使う方法**\n\n\n\n同一のリポジトリで 2 人が作業をするようになったため、開発に main ブランチを使うのは得策ではなくなりました。そこで、新規機能や新規記事ごとに異なるブランチを使うことにし、準備ができたら、main ブランチにマージする、ということに決めました。\n\n\n\nここで問題があります。現行の CI 設定は、ブランチをまったく考慮していない、という点です。GitLab に何かをプッシュするたびに、S3 にデプロイされてしまいます。\n\n\n\nこの問題は簡単に回避できます。deploy するジョブに、only: main を追加するだけです。\n\n\n\n\n\n\n![Automated deployment of main branch](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674076/Blog/Content%20Images/15-updated.png){: .center}\n\n\n\n本番の Web サイトに、すべてのブランチをデプロイしたくありませんが、フィーチャーブランチからの変更点を何らかの方法でプレビューできたら嬉しいですね。\n\n\n\n\n\n\n{: .note .text-center}\n\n\n\n### **コードのテスト用に別の場所を設定する方法**\n\n\n\n最近雇った人 (ここでは「パトリック」と呼びましょう) が、GitLab には[ GitLab Pages (英語版)](https://about.gitlab.com/stages-devops-lifecycle/pages/) という機能がある、と教えてくれました。作業中のコードをプレビューする場所にもってこいです。\n\n\n\n[GitLab Pagesで Web サイトをホストする (英語版) ](https://about.gitlab.com/blog/2016/04/07/gitlab-pages-setup/) には、CI 設定ファイルが 次の3 つのシンプルなルールを満たしている必要があります。\n\n\n\n* ジョブはpagesと名付けなければならない\n\n\n* artifacts セクションがあり、その中に public フォルダを作成しなければならない\n\n\n* ホストしたいすべてのファイルは、このpublic フォルダ内に置かなければならない\n\n\n\npublic フォルダの中身は、http://\u003Cusername>.gitlab.io/\u003Cprojectname>/でホストされます。\n\n\n\nプレーン[ HTML Web サイト用の設定例](https://gitlab.com/pages/plain-html/blob/master/.gitlab-ci.yml)を適用した後は、CI設定全体はこのようになります。\n\n\n\n\n\n\n```yaml\n\n\nvariables:\n  S3_BUCKET_NAME: \"yourbucket\"\n\ndeploy:\n  image: python:latest\n  script:\n  - pip install awscli\n  - aws s3 cp ./ s3://$S3_BUCKET_NAME/ --recursive --exclude \"*\" --include \"*.html\"\n  only:\n  - main\n\npages:\n  image: alpine:latest\n  script:\n  - mkdir -p ./public\n  - cp ./*.html ./public/\n  artifacts:\n    paths:\n    - public\n  except:\n  - main\n```\n\n\n\n2 つのジョブを指定しました。1つは、顧客用に Web サイトを S3 にデプロイします (deploy)。もう1つのジョブ (pages) は、Web サイトを GitLab Pages にデプロイします。2 つのジョブは、それぞれ「本番環境」と「ステージング環境」と呼びます。\n\n\n\n\n\n\n![Deployment to two places](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674076/Blog/Content%20Images/16-updated.png){: .center}\n\n\n\nマスター以外の全ブランチが GitLab Pages にデプロイされます。\n\n\n\n\n\n\n{: .note .text-center}\n\n\n\n## **環境の導入**\n\n\n\nGitLab は[ 環境へのサポート (英語版)](https://docs.gitlab.com/ee/ci/environments/) (動的環境および静的環境を含む) を提供しているため、ユーザーは、各デプロイジョブに対応する環境を指定するだけで済みます。\n\n\n\n```yaml\n\n\nvariables:\n  S3_BUCKET_NAME: \"yourbucket\"\n\ndeploy to production:\n  environment: production\n  image: python:latest\n  script:\n  - pip install awscli\n  - aws s3 cp ./ s3://$S3_BUCKET_NAME/ --recursive --exclude \"*\" --include \"*.html\"\n  only:\n  - main\n\npages:\n  image: alpine:latest\n  environment: staging\n  script:\n  - mkdir -p ./public\n  - cp ./*.html ./public/\n  artifacts:\n    paths:\n    - public\n  except:\n  - main\n```\n\n\n\nGitLab はユーザーのデプロイを追跡するため、サーバー上で何がデプロイされているのかを常に把握できます。\n\n\n\n![List of environments](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674076/Blog/Content%20Images/envs-updated.png){: .shadow.center}\n\n\n\nGitLab は現在の環境のそれぞれについて、デプロイの完全履歴を提供してくれます。\n\n\n\n\n\n\n![List of deployments to staging environment](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674077/Blog/Content%20Images/staging-env-detail-updated.png){: .shadow.center}\n\n\n\n![Environments](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674077/Blog/Content%20Images/17-updated.png){: .center}\n\n\n\nすべてが自動化され、セットアップも完了です。これで、新しい課題にチャレンジする準備が整いました。\n\n\n\n## **デプロイのトラブルシューティング方法**\n\n\n\nまた、同じことが起きました。ステージング環境で自分のフィーチャーブランチをプレビューするためにプッシュした 1 分後、パトリックが彼のブランチをプッシュしたのです。ステージング環境はパトリックの作業内容で上書きされてしまいました。大変です。今日で 3 回目です。\n\n\n\nそこで、アイデアが浮かびました。Slackを使ってデプロイを通知するようにすれば、デプロイが完了した時に、コンテンツを別の人がプッシュしてしまうことがなくなります。\n\n\n\n\n\n\n> [GitLabとSlackを連携する方法はこちら](https://docs.gitlab.com/ee/user/project/integrations/gitlab_slack_application.html)\n\n\n\n## **規模に応じたチームワーク**\n\n\n\n時は過ぎ、Web サイトの人気は非常に上がり、チームも 2 人から 8 人に増えました。チームメンバーは同時進行で開発を行うため、「ステージング」でプレビューを待ち合うことが多くなってきました。「ステージングに対してすべてのブランチをデプロイする」という方針はうまくいかなくなってしまったのです。\n\n\n\n\n\n\n![Queue of branches for review on Staging](https://about.gitlab.com/images/blogimages/ci-deployment-and-environments/queue.jpg){: .center}\n\n\n\nもう一度、プロセスを見直す時がきました。誰かがステージングサーバー上でコードへの変更内容を確認したいときは、まず「ステージング」ブランチに変更内容をマージする、ということにチームで同意しました。\n\n\n\n.gitlab-ci.yml への変更は最小限に抑えられます。\n\n\n\n```yaml\n\n\nexcept:\n\n\n\n- main\n\n\n```\n\n\n\nを次のように変更します：\n\n\n\n```yaml\n\n\nonly:\n\n\n\n- staging\n\n\n```\n\n\n\n![Staging branch](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674077/Blog/Content%20Images/18-updated.png){: .center}\n\n\n\nステージングサーバー上でプレビューを行なう前に、フィーチャーブランチをマージしなければなりません。\n\n\n\n{: .note .text-center}\n\n\n\nもちろん、これによりマージに追加の時間や労力がかかりますが、待機するよりは良い、ということで全員が同意しました。\n\n\n\n### **緊急時の対応**\n\n\n\nすべてを制御することは不可能です。そのため、時として何かがうまくいかないこともあります。誰かがブランチを誤った方法でマージしてしまい、あなたのサイトが HackerNews のトップに載ったタイミングで、本番環境に直接プッシュしてしまいました。何千人もの人が、輝かしいメインページの代わりに、完全に崩れたレイアウトを目撃してしまったのです。\n\n\n\nしかし幸運なことに、「**ロールバック**」ボタンを見つけた人がいたため、問題発覚 1 分後に、Web サイトは修正されました。\n\n\n\n\n\n\n![List of environments](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674077/Blog/Content%20Images/prod-env-rollback-arrow-updated.png){: .shadow.center}\n\n\n\n「ロールバック」により、1つ前のコミットでの1つ前のジョブが再起動されます\n\n\n\n\n\n\n{: .note .text-center}\n\n\n\nとにかく、この問題に対応する必要があると感じたため、本番環境への GitLab 自動デプロイを停止して、手動デプロイに切り替えることにしました。そのためには、ジョブに when: manual を追加する必要があります。\n\n\n\n予想通り、その後は「本番環境」への自動デプロイは行なわれなくなりました。手動でデプロイするには、**CI/CD > Pipelines（パイプライン）** に移動し、下図にあるボタンをクリックします。\n\n\n\n\n\n\n![Skipped job is available for manual launch](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674076/Blog/Content%20Images/manual-pipeline-arrow-updated.png){: .shadow.center}\n\n\n\n時間を早送りしましょう。ついに、あなたの組織は法人化されました。Web サイトに取り組んでいる人も数百人になり、これまでの妥協策はもう通用しません。\n\n\n\n### **「Review Apps」の出番です**\n\n\n\n次にすべき論理的なステップは、レビュー用に、フィーチャーブランチごとにアプリケーションの一時インスタンスを起動することでしょう。\n\n\n\nここでは、そのために S3 上に別のバケットをセットアップします。ただ一つ違うところは、開発ブランチの名前で Web サイトのコンテンツを「フォルダ」にコピーする点です。URL は次のようになります。\n\n\n\nhttp://\u003CREVIEW_S3_BUCKET_NAME>.s3-website-us-east-1.amazonaws.com/\u003Cbranchname>/\n\n\n\n前に使った pages ジョブを次のコードで置き換えます。\n\n\n\n\n\n\n```yaml\n\n\nreview apps:\n  variables:\n    S3_BUCKET_NAME: \"reviewbucket\"\n  image: python:latest\n  environment: review\n  script:\n  - pip install awscli\n  - mkdir -p ./$CI_BUILD_REF_NAME\n  - cp ./*.html ./$CI_BUILD_REF_NAME/\n  - aws s3 cp ./ s3://$S3_BUCKET_NAME/ --recursive --exclude \"*\" --include \"*.html\"\n```\n\n\n\n興味深いのは、$CI_BUILD_REF_NAME という変数がどこからきたか、という点です。GitLab は [多くの環境変数 (英語版)](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html) があらかじめ定義されています。そのため、ジョブではすぐ変数が使えます。\n\n\n\nここでご注意いただきたいのは、S3_BUCKET_NAME 変数はジョブ内で定義している、ということです。トップレベルの定義を再定義するとき、これを行ないます。\n\n\n\n\n\n\n\n\n{: .alert .alert-info}\n\n\n\nこの構成を視覚的にわかりやすく描くと、次のようになります。\n\n\n\n\n\n![How to use GitLab CI - update - 19 - updated](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674077/Blog/Content%20Images/19-updated.png){: .illustration}\n\n\n\n\n\n「Review Apps」の実装の詳細は、実際に現場で使っている技術スタックやデプロイプロセスなどにより大きく異なります。そのため、このブログ記事では詳細をカバーできません。\n\n\n\n現実は、この静的な HTML Web サイトのように簡単ではないのです。例えば、あるインスタンスを一時インスタンスにして、必要なソフトウェアやサービスを即座に、自動的に起動させることは簡単な作業ではありません。しかし、特に Docker コンテナ、または Chef や Ansible を使えば実現可能です。\n\n\n\nDocker を使ったデプロイについては、今後のブログ記事で取り上げます。GitLab デプロイプロセスをシンプルな HTML ファイルのコピーに単純化し、より複雑なシナリオにしなかったことに対して、少々後めたい気持ちがあります。複雑なシナリオを知りたい方は、「Building an Elixir Release into a Docker image using GitLab CI (英語版のみ：[GitLab CI を使用して、Elixir リリースを Docker イメージにビルドする)」 をご覧ください](https://about.gitlab.com/blog/2016/08/11/building-an-elixir-release-into-docker-image-using-gitlab-ci-part-1/)。\n\n\n\nさて、記事に戻ります。最後の点について、お話しましょう。\n\n\n\n\n\n\n### **異なるプラットフォームへの GitLab デプロイ**\n\n\n\n現実は、S3 や GitLab Pages だけに限定されるものではありません。GitLab はまざまなサービスにアプリやパッケージをホストし、デプロイしています。\n\n\n\nさらに、ある時点で、新しいプラットフォームへの移行を決定し、デプロイスクリプトをすべて書き直す必要が生じるかもしれません。そういった場合のダメージを最小限に抑えるために、dpl という Gem を使えます。\n\n\n\n上の例では、サービス (Amazon S3) へのコードのサンプルツールとして awscli を使用しました。しかし、どのツールを使っても、また、デプロイ先のシステムに何を選んでも、基本原則は変わりません。いくつかのパラメータでコマンドを実行し、何らかの方法で認証用にシークレットキーを渡すということです。\n\n\n\ndpl のデプロイツールは、この基本原則に従い、[このプロバイダーのリスト](https://github.com/travis-ci/dpl#supported-providers)に対して統一されたインターフェイスを提供します。\n\n\n\nこちらが、dplを使用した場合の、本番デプロイジョブの例です。\n\n\n\n\n\n```yaml\n\n\nvariables:\n  S3_BUCKET_NAME: \"yourbucket\"\n\ndeploy to production:\n  environment: production\n  image: ruby:latest\n  script:\n  - gem install dpl\n  - dpl --provider=s3 --bucket=$S3_BUCKET_NAME\n  only:\n  - main\n```\n\n\n\n異なるシステムにデプロイする場合、またはデプロイ先のプラットフォームを頻繁に変更する場合には、デプロイ用スクリプトが統一されるように dplを使うことを検討してください。\n\n\n\n\n\n\n## **まとめ：5つの重要なポイント**\n\n\n\nGitLab での CI デプロイについて、CI/CD AWS を使って説明してきました。GitLab AWS デプロイについて役立つ知識が得られたでしょうか。これまで学んできたポイントをまとめると、次のようになります。\n\n\n\n1. デプロイとは、定期的に実行される、単一の (もしくは一連の) コマンドにすぎません。このため、デプロイは [GitLab CI](https://about.gitlab.com/ja-jp/solutions/continuous-integration/) 内で実行できます。\n\n\n2. ほとんどの場合、実行するコマンドに対していくつかの (もしくは単一の) シークレットキーを指定する必要があります。指定するシークレットキーは、**Settings （設定）> CI/CD > Variables（変数）** に格納します。\n\n\n3. [GitLab CI](https://about.gitlab.com/ja-jp/solutions/continuous-integration/) では、デプロイ先のブランチを柔軟に指定できます。\n\n\n4. 複数の環境にデプロイする場合、GitLab はデプロイ履歴を保持します。そのため、任意の前バージョンにロールバックできます。\n\n\n5. インフラストラクチャの重要な部分については、GitLab 自動デプロイの代わりに、GitLab インターフェイスからの手動デプロイを有効化できます。\n\n\n\n\u003Cstyle>\n\n\n\nimg.illustration {\n  padding-left: 12%;\n  padding-right: 12%;\n\n}\n\n\n\n@media (max-width: 760px) {\n  img.illustration {\n    padding-left: 0px;\n    padding-right: 0px;\n  }\n}\n\n\n\n\u003C/style>\n\n\n\n*監修：小松原 つかさ [@tkomatsubara](https://gitlab.com/tkomatsubara)*\n\n\n\n*（GitLab合同会社 ソリューションアーキテクト本部 シニアパートナーソリューションアーキテクト）*\n",[997,998],"Ivan Nemytchenko","Cesar Saavedra","2025-08-22","2021-02-05","GitLab CIを使って複数の環境にデプロイする方法",[936,937,681],{"featured":6,"template":684,"slug":1004},"ci-deployment-and-environments","content:ja-jp:blog:ci-deployment-and-environments.yml","Ci Deployment And Environments","ja-jp/blog/ci-deployment-and-environments.yml","ja-jp/blog/ci-deployment-and-environments",{"_path":1010,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":1011,"content":1017,"config":1027,"_id":1029,"_type":16,"title":1030,"_source":18,"_file":1031,"_stem":1032,"_extension":21},"/ja-jp/blog/we-need-to-talk-no-proxy",{"title":1012,"description":1013,"ogTitle":1012,"ogDescription":1013,"noIndex":6,"ogImage":1014,"ogUrl":1015,"ogSiteName":776,"ogType":802,"canonicalUrls":1015,"schema":1016},"no_proxyを標準化する方法：お客様事例で徹底解説","環境変数“no proxy”が原因で問題発生したことは？お客様事例を取り上げ、標準化の方法を考えてみました。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659507/Blog/Hero%20Images/AdobeStock_623844718.jpg","https://about.gitlab.com/blog/we-need-to-talk-no-proxy","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"no_proxyを標準化する方法：お客様事例で徹底解説\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Stan Hu\"}],\n        \"datePublished\": \"2021-01-27\",\n      }",{"title":1012,"description":1013,"authors":1018,"heroImage":1014,"date":1020,"body":1021,"category":14,"tags":1022,"updatedDate":1026},[1019],"Stan Hu","2021-01-27","ウェブプロキシサーバーを使用した経験がある方なら、環境変数`http_proxy`や`HTTP_PROXY`をよくご存知でしょう。しかし、`no_proxy`（ノープロキシ）に関しては、どうもわかりにくい、と感じていらっしゃる方も多いのではないでしょうか。\n\nno proxyとは、あるホスト宛のトラフィックでプロキシを経由させないようにする環境変数です。世界基準が存在するHTTPと違い、ウェブクライアントがno proxyを処理する方法に「標準」は存在しません。その結果、ウェブクライアントは場合により異なる方法で処理を行います。\n\nその違いが原因でサービスが通信を停止し、その原因を突き止めるために週末返上で作業する羽目になったGitLabのお客様もいらっしゃいます。\n\nそこで、この記事ではGitLabのお客様が直面した問題について、具体例を挙げながら根本原因を探り、「no proxyを標準化する方法」というテーマを掘り下げてみます。\n\n### no proxyはなぜ「わかりにくい」のか\n\nno proxyがなぜわかりにくいのか、具体例を挙げて説明します。\n\n現在、ほとんどのウェブクライアントは環境変数を介してプロキシサーバーへの接続をサポートしています。環境変数には大文字表記と小文字表記があります。\n\n- `http_proxy` / `HTTP_PROXY`\n- `https_proxy` / `HTTPS_PROXY`\n- `no_proxy` / `NO_PROXY`\n\nこれらの変数は、プロキシサーバーにアクセスするのにどのURLを使用するか、またどういった例外を作っているか、クライアントに指示するものです。\n\nたとえば、ある企業で田中さんが`http://tanaka.example.com:8080` でリッスンしているプロキシサーバーの場合、次のようになります。\n\n```sh\nexport http_proxy=http://tanaka.example.com:8080\n```\n\n一方、同僚の斎藤さんも、次のように大文字バージョンの`HTTP_PROXY` で定義していたとします。\n\n```sh\nexport HTTP_PROXY=http://saito.example.com:8080\n```\n\nこの場合、どちらのプロキシサーバーが使用されることになるのでしょうか？答えは「状況によって異なる」です。ある場合は田中さんのプロキシサーバーが有効になる場合もあれば、ある場合は斎藤さんのプロキシサーバーが有効になる場合があります。\n\nこの場合、どちらのプロキシサーバーが使用されることになるのでしょうか？答えは「状況によって異なる」です。ある場合は田中さんのプロキシサーバーが有効になる場合もあれば、ある場合は斎藤さんのプロキシサーバーが有効になる場合があります。\n\nでは、例外を設定したい場合はどうなるでしょうか。たとえば、`internal.example.com`と`internal2.example.com`以外のすべてで、プロキシサーバーを経由したい場合です。このような場合が`no_proxy`変数の出番です。`no_proxy`を次のように定義します。\n\n```sh\nexport no_proxy=internal.example.com,internal2.example.com\n```\n\nでは、IPアドレスを除外したい場合はどうすればよいでしょうか？アスタリスクやワイルドカードは使用できるのでしょうか？CIDRブロック（例:`192.168.1.1/32`）は？\n\nこれらの答えも、「状況によって異なる」です。つまり「使用言語やツールという”PC環境”によって、proxy変数の処理方法が異なる」のが、no proxyがわかりにくいとされている理由です。次の項では、proxy変数の処理方法の違いについてさらに掘り下げます。\n\n### なぜno proxyはこんなに複雑なのか？\n\nこの問題の理解を深めるため、no proxyを巡るこれまでの経緯を説明しておきます。\n\n1994年においてほとんどのウェブクライアントは、[`http_proxy`と`no_proxy`環境変数をサポートするCERNの](https://courses.cs.vt.edu/~cs4244/spring.09/documents/Proxies.pdf)`libwww`を使用していました。`libwww`は、`http_proxy`の小文字形式のみを使用し、[`no_proxy`構文は以下のようにシンプルでした。](https://github.com/w3c/libwww/blob/8678b3dcb4191065ca39caea54bb1beba809a617/Library/src/HTAccess.c#L234-L239)\n\n```\nno_proxy is a comma- or space-separated list of machine\nor domain names, with optional :port part.  If no :port\npart is present, it applies to all ports on that domain.\n\nExample:\n\t\tno_proxy=\"cern.ch,some.domain:8001\"\n```\n\nつまり、元々「小文字表記のみ」で始まったのですが、その後新しいクライアントである`wget`や`curl`の登場により、`no proxy`の大文字が使用可になったり、不可とされたりと変遷しているのです。\n\n1996年1月にHrvoje Niksicが、`libwww`をリンクせずに独自のHTTP実装を追加する新しいクライアント、`geturl`（現在の`wget`の前身）をリリースしました。翌月には`geturl`が[バージョン1.1でhttp\\_proxyのサポートを追加](https://ftp.sunet.se/mirror/archive/ftp.sunet.se/pub/www/utilities/wget/old-versions/)され、同年5月には`geturl`バージョン1.3で`no_proxy`のサポートが追加されました。ここでは`libwww`と同様に、`geturl`では小文字形式`no_proxy`のみのサポートでした。\n\n1998年1月には、Daniel Stenbergが`curl`v5.1をリリースし、[`http_proxy`および`no_proxy`](https://github.com/curl/curl/blob/ae1912cb0d494b48d514d937826c9fe83ec96c4d/CHANGES#L929-L944)変数をサポート。また、大文字の形式の`HTTP_PROXY`および`NO_PROXY`も許可されました。\n\n2009年3月にはcurl v7.19.4がセキュリティ上の懸念から、大文字`HTTP_PROXY`のサポートを廃止します。`curl`では`HTTP_PROXY`は無視されますが、`HTTPS_PROXY`は現在でも動作します。\n\n### 一目でわかるproxy変数の処理方法の違い\n\nGitLabの[Nourdinel Bachaが調査したところ](https://gitlab.com/gitlab-com/support/support-team-meta/-/issues/2991)、これらのプロキシサーバー変数の処理方法は、使用言語やツールによって異なることがわかりました。\n\n#### http_proxyとhttps_proxyの場合\n\n各行はサポートされている動作を表し、各列にはそれが適用されるツール（例：curl）または言語（例：Ruby）を表しています。\n\n|                 | curl      | wget           | Ruby          | Python    | Go        |\n|-----------------|-----------|----------------|---------------|-----------|-----------|\n| `http_proxy`    | はい       | はい            | はい           | はい       | はい       |\n| `HTTP_PROXY`    | いいえ        | いいえ             | はい ([警告](https://github.com/ruby/ruby/blob/0ed71b37fa9af134fdd5a7fd1cebd171eba83541/lib/uri/generic.rb#L1519)) | はい (`REQUEST_METHOD` が環境にない場合)       | はい       |\n| `https_proxy`   | はい       | はい            | はい           | はい       | はい       |\n| `HTTPS_PROXY`   | はい       | いいえ             | はい           | はい       | はい       |\n| 大文字と小文字の優先順位 | 小文字 | 小文字のみ | 小文字     | 小文字 | 大文字 |\n| 参照       | [出所](https://github.com/curl/curl/blob/30e7641d7d2eb46c0b67c0c495a0ea7e52333ee2/lib/url.c#L2250-L2266) | [出所](https://github.com/jay/wget/blob/099d8ee3da3a6eea5635581ae517035165f400a5/src/retr.c#L1222-L1239) | [出所](https://github.com/ruby/ruby/blob/0ed71b37fa9af134fdd5a7fd1cebd171eba83541/lib/uri/generic.rb#L1474-L1543) | [出所](https://github.com/python/cpython/blob/030a713183084594659aefd77b76fe30178e23c8/Lib/urllib/request.py#L2488-L2517) | [出所](https://github.com/golang/go/blob/682a1d2176b02337460aeede0ff9e49429525195/src/vendor/golang.org/x/net/http/httpproxy/proxy.go#L82-L97) |\n\nこの表から以下のことがわかります。\n\n* http\\_proxyとhttps\\_proxyは常に全面的にサポートされているが、HTTP\\_PROXYは必ずしもサポートされているわけではない。  \n* Python（urllib経由）では状況がさらに複雑となる。HTTP\\_PROXYが使用できるのは、[REQUEST\\_METHODが環境で定義されていない場合に限られる](https://github.com/python/cpython/blob/030a713183084594659aefd77b76fe30178e23c8/Lib/urllib/request.py#L2504-L2508)。  \n* Goだけは他と異なり、小文字バージョンより大文字バージョンを優先する。\n\n環境変数はすべて大文字だと思われがちですが、実は最初に登場した`http_proxy`に倣い、小文字表記が事実上のスタンダードとなっています。よくわからない場合は、普遍的にサポートされている小文字形式の使用をおすすめします。\n\n#### no_proxyの場合\n\nさて、次は`no_pproxy`について説明します。次の表は、さまざまな実装の状態を示しています。こちらの表は`http_proxy`の場合に比べてもっと複雑です。例えば、`no_proxy`設定が次の様に定義されているとします。\n\n```sh\nexport no_proxy=example.com\n```\n\nこれはドメインが完全一致である必要があるのか、それともsubdomain.example.comのようなサブドメインも含まれるのでしょうか。次の表は様々な実装状況を示しています。「サフィックス（接尾辞）と一致？」の行を見ると分かるように、実際にはすべての実装がサフィックス（ドメイン末尾）を適切に一致させることができます。\n\n|                       | curl      | wget           | Ruby      | Python    | Go        |\n|-----------------------|-----------|----------------|-----------|-----------|-----------|\n| `no_proxy`            | はい       | はい            | はい       | はい       | はい       |\n| `NO_PROXY`            | はい       | いいえ             | はい       | いいえ       | はい       |\n| 大文字と小文字の優先順位       | 小文字 | 小文字のみ | 小文字 | 小文字のみ | 大文字 |\n| サフィックス（接尾辞）と一致？     | はい       | はい            | はい       | はい       | はい       |\n| `.`でリーディング停止？   | はい       | いいえ             | はい       | はい       | いいえ        |\n| `*` はすべてのホストに一致？| はい       | いいえ             | いいえ        | はい       | はい       |\n| 正規表現をサポート？     | いいえ        | いいえ             | いいえ        | いいえ        | いいえ        |\n| CIDRブロックをサポート？ | いいえ        | いいえ             | はい       | いいえ        | はい       |\n| ループバックIPを検出する？ | いいえ        | いいえ             | いいえ        | いいえ        | はい       |\n| 参考             | [出所](https://github.com/curl/curl/blob/30e7641d7d2eb46c0b67c0c495a0ea7e52333ee2/lib/url.c#L2152-L2206) | [出所](https://github.com/jay/wget/blob/099d8ee3da3a6eea5635581ae517035165f400a5/src/retr.c#L1266-L1274) | [出所](https://github.com/ruby/ruby/blob/0ed71b37fa9af134fdd5a7fd1cebd171eba83541/lib/uri/generic.rb#L1545-L1554) | [出所](https://github.com/python/cpython/blob/030a713183084594659aefd77b76fe30178e23c8/Lib/urllib/request.py#L2519-L2551)| [出所](https://github.com/golang/go/blob/682a1d2176b02337460aeede0ff9e49429525195/src/vendor/golang.org/x/net/http/httpproxy/proxy.go#L170-L206) |\n\nただし、`no_proxy`設定の先頭に「.」がある場合、動作が異なります。\n\nたとえば、`curl`と`wget`は動作が異なります。`curl`は常に先頭の「.」を削除し、ドメインサフィックスと照合します。次の呼び出しはプロキシをバイパスします。\n\n```sh\n$ env https_proxy=http://non.existent/ no_proxy=.gitlab.com curl https://gitlab.com\n\u003Chtml>\u003Cbody>You are being \u003Ca href=\"https://about.gitlab.com/\">redirected\u003C/a>.\u003C/body>\u003C/html>\n```\n\nただし、`wget`は先頭の「`.`」を削除せず、ホスト名に対して正確な文字列一致を実行します。その結果、`wget`はトップレベルドメインが使用されている場合にプロキシの使用を試みます。\n\n```sh\n$ env https_proxy=http://non.existent/ no_proxy=.gitlab.com wget https://gitlab.com\nResolving non.existent (non.existent)... failed: Name or service not known.\nwget: unable to resolve host address 'non.existent'\n```\n\nすべての実装において、正規表現はサポートされません。\n\n正規表現には独自の特徴（PCRE、POSIXなど）があるため、正規表現を使用すると問題がさらに複雑になると思われます。また、正規表現を使用すると、パフォーマンスとセキュリティの問題が発生する可能性があります。\n\n`no_proxy`を`*`に設定するとプロキシが完全に無効になる場合もあるが、これはすべてに共通するルールではない。  \n\nプロキシを使用するかどうかを決定する際に、ホスト名をIPアドレスに解決するためのDNSルックアップを実行する実装はない。\n\nクライアントによってIPアドレスが明示的に使用されることが予想される場合を除き、`no_proxy`変数にIPアドレスを指定しないようにしましょう。\n\n`18.240.0.1/24`などのCIDRブロックは、リクエストが直接IPアドレスに対して行われた場合にのみ機能します。CIDRブロックが許可されるのはGoとRubyのみです。他の実装とは異なり、GoではループバックIPアドレスが検出されると、プロキシの使用が自動的に無効になります。\n\n### GitLabのお客様が抱えたno proxy問題\n\n大文字小文字表記、言語とツールによるリアクションの違いに注意を払う必要があるのは、複数の言語で記述されたアプリケーションを、プロキシサーバーを備えた企業のファイアウォールの背後で動作させる場合です。GitLabもそのひとつであり、RubyとGoで記述された複数のサービスで構成されています。\n\nここでGitLabのあるお客様の例を挙げましょう。お客様はプロキシ構文を次のように設定しました。\n\n```yaml\nHTTP_PROXY: http://proxy.company.com\nHTTPS_PROXY: http://proxy.company.com\nNO_PROXY: .correct-company.com\n```\n\nこのお客様からGitLabに以下の問題の報告がありました。\n\n1. コマンドラインからの`git` pushが起動した\n2. ウェブUI経由で行われたGitの変更が失敗した\n\n連絡を受けたサポートエンジニアは、[Kubernetes](https://about.gitlab.com/ja-jp/blog/what-is-kubernetes/)の構文の問題により、古い値が残っていることを発見しました。ポッドの環境は実際には次のようになっていました。\n\n```yaml\nHTTP_PROXY: http://proxy.company.com\nHTTPS_PROXY: http://proxy.company.com\nNO_PROXY: .correct-company.com\nno_proxy: .wrong-company.com\n```\n\n`no_proxy`と`NO_PROXY`、両者の定義が一致していないため警告が出ました。定義を一致させるか／誤ったエントリを削除することで、この問題を解決できます。\n\nこの古いエントリの何が原因で問題が起きたのか、もう少し詳しく見てみることにします。先ほど「[no proxyの場合](#bookmark=id.3j5kjy3c5qh2)」で述べたことをここで思い出してみましょう。\n\n1. Rubyはまず小文字形式を試す\n2. Goはまず大文字形式を試す\n\nその結果、GitLab WorkhorseなどのGoで記述されたサービスには正しいプロキシ構文となりました。Goサービスが主にこのアクティビティを処理したため、コマンドラインからの`git push`は正常に機能しました。\n\n```mermaid\nsequenceDiagram\n    participant C as Client\n    participant W as Workhorse\n    participant G as Gitaly\n    C->>W: 1. git push\n    W->>G: 2. gRPC: PostReceivePack\n    G->>W: 3. OK\n    W->>C: 4. OK\n```\n\ngRPC呼び出しでは、`no_proxy`がGitalyに直接接続するように適切に構成されていたため、プロキシの使用が試行されませんでした。\n\nただし、ユーザーがUIを変更すると、GitalyはリクエストをRubyで記述された`gitaly-ruby`サービスに転送します。`gitaly-ruby`はリポジトリに変更を加え、[gRPCコールバックを介して親プロセスにレポートを返します](https://gitlab.com/gitlab-org/gitaly/-/issues/3189)(英語）。ただし、以下の手順4に示すように、レポート手順は実行されませんでした。\n\n```mermaid\nsequenceDiagram\n    participant C as Client\n    participant R as Rails\n    participant G as Gitaly\n    participant GR as gitaly-ruby\n    participant P as Proxy\n    C->>R: 1. Change file in UI\n    R->>G: 2. gRPC: UserCommitFiles\n    G->>GR: 3. gRPC: UserCommitFiles\n    GR->>P: 4. CONNECT\n    P->>GR: 5. FAIL\n```\n\ngRPCは基盤となるトランスポートとしてHTTP/2を使用するため、`gitaly-ruby`は間違った`no_proxy`設定で構成されたプロキシへのCONNECTを試行しました。プロキシはこのHTTP要求を即座に拒否し、ウェブUIプッシュケースで失敗を引き起こしました。\n\n環境から小文字の`no_proxy`を削除すると、UIからのプッシュが期待どおりに機能し、`gitaly-ruby`が親のGitalyプロセスに直接接続されました。以下の図のステップ4は適切に機能しました。\n\n```mermaid\nsequenceDiagram\n    participant C as Client\n    participant R as Rails\n    participant G as Gitaly\n    participant GR as gitaly-ruby\n    participant P as Proxy\n    C->>R: 1. Change file in UI\n    R->>G: 2. gRPC: UserCommitFiles\n    G->>GR: 3. gRPC: UserCommitFiles\n    GR->>G: 4. OK\n    G->>R: 5. OK\n    R->>C: 6. OK\n```\n\n#### もう一つの原因はgRPCにあった\n\n`https://`ではなく`http://`が使用されています。セキュリティの観点からは理想的ではありませんが、TLS証明書の検証の問題によりクライアントが失敗するという面倒を避けるために行う場合もあります。\n\nしかしこの場合、HTTPSプロキシが指定されていれば、この問題は発生しなかったでしょう。HTTPSプロキシが使用されている場合、gRPCは[HTTPSプロキシをサポートしていない](https://github.com/grpc/grpc/issues/20939)ため、この設定を無視するからです。\n\n### 解決策：最小限の共通項で設定する\n\n小文字と大文字のプロキシ設定で矛盾した値を定義すべきではないことは、誰もが同意すると思います。ただし、複数の言語で記述されたスタックを管理する必要がある場合は、HTTPプロキシ構文を最も共通する設定で行うよう検討することをおすすめします。\n\n#### `http_proxy` と `https_proxy`\n\n* 小文字形式を使用する。 `HTTP_PROXY` は常にサポートまたは推奨されるわけではない。\n    * どうしても大文字形式も使用する必要がある場合は、__必ず__ 同じ値を共有する。\n\n#### `no_proxy`\n\n1. 小文字形式を使用する。\n2. カンマ区切りの`hostname:port`値を使用する。\n3. IPアドレスは問題ないが、ホスト名は解決されない。\n4. サフィックスは常にマッチングされる(例:`example.com`は`test.example.com`と一致)。\n5. トップレベルドメインを一致させる必要がある場合は、先頭のドット(`.`)を使用しない。\n6. GoとRubyのみがCIDRマッチングをサポートしているため、CIDRマッチングの使用は避ける。\n\n### 解決策：`no_proxy`の標準化チェックリスト\n\n最小公分母を知っておくと、定義が異なるウェブクライアントにコピーされた場合に、問題を回避する上で役立ちます。しかし、`no_proxy`やその他のプロキシ設定には、間に合わせの標準よりも、文書化された標準が必要かもしれません。以下のリストを出発点としてお役立てください。\n\n1. 大文字の変数よりも小文字の変数を優先する (例 `http_proxy` は`HTTP_PROXY`の前に検索すべき)。\n2. カンマ区切りの `hostname:port` 値を使用する。\n    * 各値にはオプションの空白を含めることができる。\n3. DNSルックアップの実行や、正規表現の使用を行わない。\n4. **すべての** ホストに一致させるには`*`を使用する。\n5. 先頭のドット (`.`) を削除し、ドメインサフィックスに対してマッチングさせる。\n6. CIDRブロックマッチングをサポートする。\n7. 特別なIPアドレスを想定しない（たとえば`no_proxy`のループバックアドレス)。\n\n#### まとめ\n\n最初のウェブプロキシがリリースされてから25年以上経ちました。環境変数を介してウェブクライアントを構成する基本的な仕組みはあまり変わっていませんが、さまざまな実装で微妙な違いが生じています。\n\n今回、GitLabのあるお客様の具体的な事例をご紹介しました。このお客様の状況は以下のとおりでした。\n\n* 競合する`no_proxy`変数と`NO_PROXY`変数を誤って定義  \n* RubyとGoはこれらの設定を処理する方法が異なるため、トラブルシューティングに何時間も費やす\n\nこのブログではこの2つの違いに焦点を当て、解説しました。皆様の本番スタックで将来の問題発生回避にお役立ていただけると幸いです。また、設定標準チェックリストを参照して、ウェブクライアントの保守担当者様が動作を標準化し、このような問題を根本的に回避することを願っています。\n\nGitの利便性を生かしつつ、一元化されたプラットフォームでデベロッパー、セキュリティ担当者、運用チームをサポートするGitLabでは、[AIによるコード提案機能があるため、効率性を高められます](https://about.gitlab.com/ja-jp/platform/)。導入検討中の方は、ぜひ無料でのトライアルをお試しください。\n\n> [無料トライアルを開始してみる](https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/ja-jp/platform&glm_content=default-saas-trial)\n\n画像出展： [PixaBay](https://pixabay.com/illustrations/question-mark-pile-questions-symbol-2492009)\n{: .note}\n\n\u003Cbr>\u003Cbr>\u003Cbr>\n\n*監修：小松原 つかさ  [@tkomatsubara](https://gitlab.com/tkomatsubara)\u003Cbr>\n（GitLab合同会社 ソリューションアーキテクト本部 シニアパートナーソリューションアーキテクト）*",[272,1023,1024,1025],"careers","user stories","startups","2025-03-17",{"slug":1028,"featured":6,"template":684},"we-need-to-talk-no-proxy","content:ja-jp:blog:we-need-to-talk-no-proxy.yml","We Need To Talk No Proxy","ja-jp/blog/we-need-to-talk-no-proxy.yml","ja-jp/blog/we-need-to-talk-no-proxy",{"_path":1034,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":1035,"content":1041,"config":1048,"_id":1050,"_type":16,"title":1051,"_source":18,"_file":1052,"_stem":1053,"_extension":21},"/ja-jp/blog/basics-of-gitlab-ci-updated",{"title":1036,"description":1037,"ogTitle":1036,"ogDescription":1037,"noIndex":6,"ogImage":1038,"ogUrl":1039,"ogSiteName":776,"ogType":802,"canonicalUrls":1039,"schema":1040},"CI 入門：ジョブを順序どおりに、並列に、または順不同で実行する方法","継続的インテグレーション (CI) 入門：CI は初めてですか？GitLab CI の使い方を学び、最初のCIパイプラインをGitLabでビルドしてみましょう。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662061/Blog/Hero%20Images/cicdcover.png","https://about.gitlab.com/blog/basics-of-gitlab-ci-updated","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"CI 入門：ジョブを順序どおりに、並列に、または順不同で実行する方法\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Itzik Gan Baruch\"}],\n        \"datePublished\": \"2020-12-10\",\n      }",{"title":1036,"description":1037,"authors":1042,"heroImage":1038,"date":1044,"body":1045,"category":14,"tags":1046,"updatedDate":1047},[1043],"Itzik Gan Baruch","2020-12-10","[継続的インテグレーション (CI) (英語版)](https://about.gitlab.com/topics/ci-cd/)\nのことを何一つ知らず、ソフトウェア開発ライフサイクルに [どうして CI が必要なのか\n(英語版)](https://about.gitlab.com/blog/how-to-keep-up-with-ci-cd-best-practices/)\n分からない、と仮定しましょう。\n\n\nいま、あるプロジェクトで作業をしていて、そこには2つのテキストファイルから成るコードがあるものとします。さらに、これらの2つのファイルには「Hello\nworld」というフレーズが含まれている必要がある、という点に注意してください。\n\n\nこのフレーズが含まれていなければ、開発チームがその月のお給料を受け取れないことになるかもしれないくらい、重要なポイントです。\n\n\nそこで、責任感のあるソフトウェアデベロッパーが、顧客にコードを納品する前に実行する、短いスクリプトを書きました。\n\n\n以下のような非常に洗練されたコードです。\n\n\n```bash\n\ncat file1.txt file2.txt | grep -q \"Hello world\"\n\n```\n\n\nここでの懸念事項はチームには10名のデベロッパーがいて、人的要因がコードの品質に大きな影響を及ぼす可能性があるという点です。\n\n\n1週間前、新しくチームに入ったメンバーがこのスクリプトを実行し忘れ、3件のクライアントに機能しないビルドが納品されるという事態が発生しました。この事態の解決にあたり、幸いにもコードは既にGitLab\nにあり、[ビルトインの\nCI](https://about.gitlab.com/ja-jp/solutions/continuous-integration/)\nがあることが分かりました。さらに、あるカンファレンスで、テスト実行にCIを使うのが一般的ということを耳にしていました。\n\n\n## CI 内で最初のテストを実行する\n\n\nドキュメントによると、CI の実行に必要なのは `.gitlab-ci.yml` ファイル内に 以下の2 行のコードを追加することだけでした。\n\n\n```yaml\n\ntest:\n  script: cat file1.txt file2.txt | grep -q 'Hello world'\n```\n\n\nコミットして...無事にビルドが成功しました。\n\n\n![CI内でビルドに成功](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674096/Blog/Content%20Images/build_succeeded.png)\n\n\nでは、2 つ目のファイルの「world」という文言を「Africa」に置き換え、何が起こるか確認してみましょう。\n\n\n![CI内でビルドに失敗](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674096/Blog/Content%20Images/build_failed.png)\n\n\nビルドは予想どおり失敗します。\n\nここで、自動化テストが完成しました。GitLab CI は、DevOps\n環境内でソースコードのリポジトリに新しいコードをプッシュするたびにこのテストスクリプトを実行します。\n\n\n__注:__ 上記例では、file1.txt と file2.txt がGitLabランナーを実行するホストに存在すると仮定しています。\n\n\nこの例を実際に GitLabで実行するには、以下のようにファイルを作成するコードを実行した後、テストスクリプトを実行する必要があります。\n\n\n```yaml\n\ntest:\n\nbefore_script:\n      - echo \"Hello \" > | tr -d \"\\n\" | > file1.txt\n      - echo \"world\" > file2.txt\nscript: cat file1.txt file2.txt | grep -q 'Hello world'\n\n```\n\n\nなお、分かりやすくするために、この 2 つのファイルは既にホストに存在していると仮定し、以降の例では作成しないものとします。\n\n\n## CIビルド結果をダウンロード可能にする\n\n\n次にすることは、顧客に納品するコードをパッケージ化することです。ソフトウェア開発プロセスのこの部分も自動化してしまいましょう。\n\n\nまず、CI に別のジョブを定義する必要があります。このジョブは「package」という名前にしましょう。\n\n\n```yaml\n\ntest:\n  script: cat file1.txt file2.txt | grep -q 'Hello world'\n\npackage:\n  script: cat file1.txt file2.txt | gzip > package.gz\n```\n\n\nよって、今ここにはタブが 2 つあります。\n\n\n![2つのタブ ―\n2つのジョブから生成](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674096/Blog/Content%20Images/two_tabs.png)\n\n\nしかし、新たに作成されるファイルがダウンロードできるようにビルドの「アーティファクト」であることを指定し忘れてしまいました。。修正するには、`artifacts`\nセクションを追加します。\n\n\n```yaml\n\ntest:\n  script: cat file1.txt file2.txt | grep -q 'Hello world'\n\npackage:\n  script: cat file1.txt file2.txt | gzip > packaged.gz\n  artifacts:\n    paths:\n    - packaged.gz\n```\n\n\n修正した結果を確認すると、アーティファクトが作成されダウンロードできるようになっています。\n\n\n![ダウンロードボタンのチェック](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674096/Blog/Content%20Images/artifacts.png)\n\n\nしかし、ここで修正が必要な新たな問題があります。2\nつのジョブは現在は並列実行されていますが、テストに失敗した場合、アプリケーションをパッケージ化しないように変更をする必要があります。\n\n\n## ジョブを順次実行する\n\n\nそこで「package」ジョブは、テストが成功した場合のみ実行するものとします。`stages` を指定し、ジョブの実行順序を定義しましょう。\n\n\n```yaml\n\nstages:\n  - test\n  - package\n\ntest:\n  stage: test\n  script: cat file1.txt file2.txt | grep -q 'Hello world'\n\npackage:\n  stage: package\n  script: cat file1.txt file2.txt | gzip > packaged.gz\n  artifacts:\n    paths:\n    - packaged.gz\n```\n\n\n上記のようになりました。\n\n\nちなみに、コンパイル (我々のケースでは2つのファイルを連結することを意味します) には時間がかかるため、2\n回も実行したくはありません。コンパイルは別のステップとして定義しましょう。\n\n\n```yaml\n\nstages:\n  - compile\n  - test\n  - package\n\ncompile:\n  stage: compile\n  script: cat file1.txt file2.txt > compiled.txt\n  artifacts:\n    paths:\n    - compiled.txt\n\ntest:\n  stage: test\n  script: cat compiled.txt | grep -q 'Hello world'\n\npackage:\n  stage: package\n  script: cat compiled.txt | gzip > packaged.gz\n  artifacts:\n    paths:\n    - packaged.gz\n```\n\n\nそれでは、アーティファクトを見てみましょう。\n\n\n![不必要なアーティファクト](https://about.gitlab.com/images/blogimages/the-basics-of-gitlab-ci/clean-artifacts.png)\n\n\nこの「コンパイル」ファイルを常にダウンロード可能にする必要はないようです。一時的なアーティファクトとして「20\n分」で保存期間切れとなるよう、`expire_in` を設定します。\n\n\n```yaml\n\ncompile:\n  stage: compile\n  script: cat file1.txt file2.txt > compiled.txt\n  artifacts:\n    paths:\n    - compiled.txt\n    expire_in: 20 minutes\n```\n\n\n構成ファイルは見たところ問題なさそうです。\n\n\n- アプリケーションをコンパイル、テスト、パッケージ化するために、3 つの連続したステージを作成しました。\n\n\n- コンパイル済みアプリを次のステージに渡すと、コンパイルを 2回実行する必要がなくなります(それにより実行が高速化されます)。\n\n\n- パッケージ化されたアプリケーションは、今後も使用できるようビルドアーティファクトとして保管します。\n\n\n## どのDockerイメージを使用するのか学ぶ\n\n\nここまでは順調です。しかし、CIビルドにはまだ時間がかかります。ログを見てみましょう。\n\n\n![ruby3.1](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674096/Blog/Content%20Images/ruby-31.png)\n\n\nここに注目してください。Ruby 3.1とあります。\n\n\nなぜ Ruby が必要なのかといえば、GitLab.com が [ビルド実行\n(英語版)](https://about.gitlab.com/blog/shared-runners/) に Docker\nイメージを使用しており、[デフォルトで\n(英語版)](https://docs.gitlab.com/ee/user/gitlab_com/#shared-runners) \n[`ruby:3.1`](https://hub.docker.com/_/ruby/)\nイメージを使用するからです。間違いなく、このイメージには必要のないパッケージが多数含まれています。Google\nで検索して調べたところ、[`alpine`](https://hub.docker.com/_/alpine/) というイメージがあり、ほとんど空の\nLinux イメージであることが分かりました。\n\n\nそれでは、`.gitlab-ci.yml` に  `image: alpine` を追加して、このイメージを使用したいと明示的に指定しましょう。\n\n\nうまくいきました。パイプラインの実行が3 分ほど短縮できたようです。\n\n\n![ビルド速度を短縮](https://about.gitlab.com/images/blogimages/the-basics-of-gitlab-ci/speed.png)\n\n\nパブリックイメージはたくさんあるようです。\n\n- [mysql](https://hub.docker.com/_/mysql/)\n\n- [Python](https://hub.docker.com/_/python/)\n\n- [Java](https://hub.docker.com/_/java/)\n\n- [php](https://hub.docker.com/_/php/)\n\n\nそれにより、我々の技術スタックに適したものを選ぶことができます。不必要なソフトウェアが含まれていないイメージを指定することで、ダウンロード時間が最短で済みます。\n\n\n## 複雑なシナリオに対応する\n\n\nさて、ここで新しいクライアントが、アプリを `.gz` ではなく、`.iso` イメージとしてパッケージ化してほしい、と希望しているとします。CI\nがすべての作業を行なってくれるため、コードにはジョブを 1 つ追加するだけです。ISO\nイメージはmkisofsコマンドを使用して作成できます。構成ファイルは次のようになります。\n\n\n```yaml\n\nimage: alpine\n\n\nstages:\n  - compile\n  - test\n  - package\n\n# ... \"compile\" and \"test\" jobs are skipped here for the sake of compactness\n\n\npack-gz:\n  stage: package\n  script: cat compiled.txt | gzip > packaged.gz\n  artifacts:\n    paths:\n    - packaged.gz\n\npack-iso:\n  stage: package\n  script:\n  - mkisofs -o ./packaged.iso ./compiled.txt\n  artifacts:\n    paths:\n    - packaged.iso\n```\n\n\nジョブ名は同じにする必要はありません。ジョブ名が同じだと、ソフトウェア開発プロセスの同じステージでジョブを並列実行できません。そのため、ジョブやステージの名前が同じになるのは、偶然のことだと考えてください。\n\n\nさて、ビルドは失敗しました。\n\n\n![mkisofs\nが欠落しているために失敗したビルド](https://about.gitlab.com/images/blogimages/the-basics-of-gitlab-ci/mkisofs.png)\n\n\n`mkisofs` が `alpine` イメージに含まれていないことが原因です。まずはこのパッケージをインストールする必要があります。\n\n\n## 欠落しているソフトウェアやパッケージの対応\n\n\n[Alpine Linux Web サイト\n(英語版)](https://pkgs.alpinelinux.org/contents?file=mkisofs&path=&name=&branch=edge&repo=&arch=)\nによると、`mkisofs` は `xorriso`パッケージと `cdrkit`\nパッケージの一部です。次のコマンドを実行することでパッケージをインストールできます。\n\n\n```bash\n\necho \"ipv6\" >> /etc/modules  # enable networking\n\napk update                   # update packages list\n\napk add xorriso              # install package\n\n```\n\n\nCI ではこれらは他のコマンドと何ら変わりません。`script` セクションで実行する必要があるコマンドの全リストは、このようになります。\n\n\n```yml\n\nscript:\n\n- echo \"ipv6\" >> /etc/modules\n\n- apk update\n\n- apk add xorriso\n\n- mkisofs -o ./packaged.iso ./compiled.txt\n\n```\n\n\n構文的に正しくするため、パッケージのインストールに関連したコマンドは `before_script` 内に置きましょう。`before_script`\nを構成の最上位レベルで使うと、そのコマンドがすべてのジョブの前に実行されることに留意してください。今回は特定のジョブの前で実行させます。\n\n\n## DAG（有向非巡回グラフ）：より高速で柔軟なパイプラインのために\n\n\nステージを定義して、テストに合格した場合にのみパッケージジョブを実行するようにしました。後のステージに定義されているジョブに対し、いくつかのジョブのステージ順序を並び替えて先に実行させたい場合はどうすればいいでしょうか。場合によっては、従来のステージ順序がパイプライン全体の実行時間を遅くしてしまう可能性があります。\n\n\nテストステージに、実行に時間のかかる負荷の高いテストがいくつか含まれており、それらのテストが必ずしもパッケージジョブに関連していないとします。この場合、テストの完了を待たずにパッケージジョブを開始できれば、より効率的になります。それにはDAG\n(有向非巡回グラフ) が役立ちます。特定のジョブのステージ順序を変えるためには、ジョブの依存関係 (通常のステージの順序をスキップするもの)\nを定義します。\n\n\nGitLab には、ジョブ間の依存関係を作成する特殊キーワード `needs`\nがあります。これを使うことで、依存しているジョブが完了するとすぐにジョブを前倒しで実行できるようになります。\n\n\n次の例では、テストジョブが完了するとすぐにパックジョブが実行を開始します。そのため、将来誰かがテストをテストステージに追加した場合に、新しいテストジョブの完了を待たずにパッケージジョブが実行を開始します。\n\n\n```yaml\n\npack-gz:\n  stage: package\n  script: cat compiled.txt | gzip > packaged.gz\n  needs: [\"test\"]\n  artifacts:\n    paths:\n    - packaged.gz\n\npack-iso:\n  stage: package\n  before_script:\n  - echo \"ipv6\" >> /etc/modules\n  - apk update\n  - apk add xorriso\n  script:\n  - mkisofs -o ./packaged.iso ./compiled.txt\n  needs: [\"test\"]\n  artifacts:\n    paths:\n    - packaged.iso\n```\n\n\n`.gitlab-ci.yml` の最終バージョン:\n\n\n```yaml\n\nimage: alpine\n\n\nstages:\n  - compile\n  - test\n  - package\n\ncompile:\n  stage: compile\n  before_script:\n      - echo \"Hello  \" | tr -d \"\\n\" > file1.txt\n      - echo \"world\" > file2.txt\n  script: cat file1.txt file2.txt > compiled.txt\n  artifacts:\n    paths:\n    - compiled.txt\n    expire_in: 20 minutes\n\ntest:\n  stage: test\n  script: cat compiled.txt | grep -q 'Hello world'\n\npack-gz:\n  stage: package\n  script: cat compiled.txt | gzip > packaged.gz\n  needs: [\"test\"]\n  artifacts:\n    paths:\n    - packaged.gz\n\npack-iso:\n  stage: package\n  before_script:\n  - echo \"ipv6\" >> /etc/modules\n  - apk update\n  - apk add xorriso\n  script:\n  - mkisofs -o ./packaged.iso ./compiled.txt\n  needs: [\"test\"]\n  artifacts:\n    paths:\n    - packaged.iso\n```\n\n\nパイプラインが作成できました！ステージは 3 つの連続したステージで、ジョブ `pack-gz` と `pack-iso` が、`package`\nステージ内で並列実行されています。\n\n\n![パイプラインのイラスト](https://about.gitlab.com/images/blogimages/the-basics-of-gitlab-ci/pipeline.png)\n\n\n## 高度なパイプラインの構築\n\n\nここからは、高度なパイプラインを構築する方法を説明します。\n\n\n### CIパイプラインに自動テストを実装 \n\n\n[DevOps](https://about.gitlab.com/ja-jp/)\nにおいて、ソフトウェア開発戦略の重要なルールは、素晴らしいユーザーエクスペリエンスを備えた優れたアプリを作成する、というものです。ここでは、CI\nパイプラインにいくつかのテストを追加し、プロセス全体の早い段階でバグを検出、修正しましょう。この方法なら、問題が大きくなる前や新しいプロジェクトに移る前に問題を修正できます。\n\n\nGitLabにはさまざまな [テスト](https://docs.gitlab.com/ee/ci/testing/)\n用にすぐ使えるテンプレートがあり、これらを使用することで作業が簡単になります。必要な手順は、CI の構成にテンプレートを追加するだけです。\n\n\nこの例では、[アクセシビリティテスト\n(英語版)](https://docs.gitlab.com/ee/ci/testing/accessibility_testing.html)\nを追加します。\n\n\n```yaml\n\nstages:\n  - accessibility\n\nvariables:\n  a11y_urls: \"https://about.gitlab.com https://www.example.com\"\n\ninclude:\n  - template: \"Verify/Accessibility.gitlab-ci.yml\"\n```\n\n\n`a11y_urls` 変数をカスタム化し、Web ページの URL を挿入して、[Pa11y](https://pa11y.org/) と\n[コード品質](https://docs.gitlab.com/ee/ci/testing/code_quality.html) のテストを行います。\n\n\n```yaml\n   include:\n   - template: Jobs/Code-Quality.gitlab-ci.yml\n```\n\n\nGitLab\nを使うと、マージリクエストのウィジェットエリア内でテストレポートを簡単に確認できます。コードレビュー、パイプラインステータス、テスト結果を一か所にまとめることで、あらゆることがよりスムーズに効率よくできるようになります。\n\n\n![アクセシビリティレポート](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674096/Blog/Content%20Images/Screenshot_2024-04-02_at_10.56.41.png)\n\n\u003Ccenter>\u003Ci>アクセシビリティ・マージリクエスト・ウィジェット\u003C/i>\u003C/center>\u003Cp>\u003C/p>\n\n\n![MR\n内のコード品質ウィジェット](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674096/Blog/Content%20Images/Screenshot_2024-04-02_at_11.00.25.png)\n\n\u003Ccenter>\u003Ci>コード品質マージリクエストウィジェット\u003C/i>\u003C/center>\n\n\n### マトリックスビルド\n\n\n場合によっては、異なる構成、OS\nバージョン、プログラミング言語バージョンなどでアプリをテストする必要があります。そのような場合には、[parallel:matrix\n(英語版)](https://docs.gitlab.com/ee/ci/yaml/#parallelmatrix) ビルドを使って、1\nつのジョブ構成でさまざまな組み合わせでアプリケーションを並列にテストします。このブログでは、マトリックスキーワードを使用して、異なるバージョンの\nPython でコードのテストを行います。\n\n\n```yaml\n\npython-req:\n  image: python:$VERSION\n  stage: lint\n  script:\n    - pip install -r requirements_dev.txt\n    - chmod +x ./build_cpp.sh\n    - ./build_cpp.sh\n  parallel:\n    matrix:\n      - VERSION: ['3.8', '3.9', '3.10', '3.11']   # https://hub.docker.com/_/python\n```\n\n\nパイプライン実行中、このジョブは 4 通りの方法で並列実行されます。それぞれ以下のように異なる Python イメージを使用します。\n\n\n![実行中のマトリックスジョブ](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674096/Blog/Content%20Images/Screenshot_2024-04-02_at_11.12.48.png)\n\n\n### ユニットテスト  \n\n\n#### ユニットテストとは\n\n\nユニットテストとは、ソフトウェアの個々のコンポーネントや機能が期待通りに機能するかを確認する、対象を絞った単体テストです。ユニットテストは、ソフトウェア開発プロセスの早い段階でバグを検出して修正し、コードのそれぞれの部分が、独立した状態でも正しく機能することを確認するために必須です。\n\n\n例: 計算機アプリを開発しているとします。加算関数のユニットテストでは、2 + 2 が 4\nになるかどうかを確認します。このテストに合格すれば、加算関数が正しく機能していることが確認されます。\n\n\n#### ユニットテストのベストプラクティス\n\n\nテストに失敗すると、パイプラインは失敗し、ユーザーに通知が送られます。デベロッパーはジョブのログ (通常何千行もある)\nを確認し、どこでテストに失敗したのかを特定し、修正します。このチェックには時間がかかり、効率がよくありません。\n\n\nそこで、[ユニットテストレポート\n(英語版)](https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html)\nを使うようにジョブを構成することができます。GitLab\nはマージリクエストとパイプラインの詳細ページ上にレポートを表示することができるため、ログ全体を確認しなくてもエラーをより簡単に素早く特定できます。\n\n\n##### JUnitテストレポート\n\n\n以下はJUnit テストレポートの例です。\n\n\n![パイプラインの JUnit テストレポート v13\n10](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674097/Blog/Content%20Images/pipelines_junit_test_report_v13_10.png){:\n.shadow.center}\n\n\n### 統合テストおよびエンドツーエンドテスト戦略\n\n通常の開発ルーチンに加え、統合テストとエンドツーエンドテスト専用に指定したパイプラインをセットアップすることが非常に重要です。これらのテストでは、[マイクロサービス\n(英語版)](https://about.gitlab.com/topics/microservices/)、UI\nテスト、それ他のコンポーネントを含んだ、コードの異なる部位の連携がスムーズかどうかをチェックします。\n\n\nこれらのテストは [毎晩 (英語版)](https://docs.gitlab.com/ee/ci/pipelines/schedules.html)\n実行されます。[テスト結果を自動的に指定のスラックチャンネルに送るよう\n(英語版)](https://docs.gitlab.com/ee/user/project/integrations/gitlab_slack_application.html#notification-events)\nに設定することもできます。そうすることで、デベロッパーが翌日出社したときに迅速に問題を確認できます。こうした機能はすべて、問題を早期に特定して修正することを優先すべく設計されています。\n\n\n### テスト環境 \n\n\nテストの中には、アプリをしっかりテストするために、テスト環境を構築しなければならない場合があります。GitLab CI/CD\nを使用するとテスト環境のデプロイが自動化でき、時間を大幅に節約できます。本ブログは主に CI\nに着目したものとなっているため、詳細には触れません。アプリのデプロイとリリースについては、[GitLab ドキュメントのこのセクション\n(英語版)](https://docs.gitlab.com/ee/topics/release_your_application.html)\nを参照してください。\n\n\n## CI パイプラインへのセキュリティスキャンの実装\n\n\nCI パイプラインにセキュリティスキャンを実装する方法は次のとおりです。\n\n\n### SASTおよびDASTインテグレーション\n\n\nコードの安全性を守ることは非常に重要であり、最新の変更に脆弱性がある場合は、その内容を直ちに把握したいと考えます。したがって、パイプラインにセキュリティスキャンを追加するのが最適な対応といえるでしょう。セキュリティスキャンは、コミットごとにコードをチェックし、リスクがあれば警告してくれます。CI\nパイプラインに静的アプリケーションセキュリティテスト ([SAST\n(英語版)](https://docs.gitlab.com/ee/user/application_security/sast/))\nや動的アプリケーションセキュリティテスト ([DAST\n(英語版)](https://docs.gitlab.com/ee/user/application_security/dast/))\nなどの各種スキャンを追加する方法を説明する以下のナビゲーションをご確認ください。\n\n\nナビゲーションを開始するには、以下の画像を**クリック**してください。 \n\n\n[![スキャンの製品ツアー](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674096/Blog/Content%20Images/Screenshot_2024-04-14_at_13.44.42.png)](https://gitlab.navattic.com/gitlab-scans)\n\n\nさらに、AI を活用すれば、脆弱性をさらに深く掘り下げ、修正方法の提案が得られます。詳しくは以下のナビゲーションをご確認ください。\n\n\nナビゲーションを開始するには、以下の画像をクリックしてください。\n\n\n[![製品ツアーでの脆弱性の説明](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674096/Blog/Content%20Images/Screenshot_2024-04-14_at_13.50.24.png)](https://tech-marketing.gitlab.io/static-demos/pt-explain-vulnerability.html)\n\n\n## GitLab CI使い方まとめ\n\n\nまだまだお伝えしたいことはありますが、ここで一度終わりにしましょう。説明に使用した例はすべて意図的に単純なものにしました。これは、慣れない技術スタックの説明が続くことで内容が頭に入らないといった状況を避け、GitLab\nCIのコンセプトを理解してもらうためです。では、ここまで学んできたことを次にまとめます。\n\n\n1. GitLab CI に作業をまかせるには、`.gitlab-ci.yml` 内で 1 つ以上の[ジョブ\n(英語版)](https://docs.gitlab.com/ee/ci/jobs/)を定義する必要があります。\n\n2. ジョブには名前を付ける必要がありますが、その際は適切な名前を付けるようにしてください。\n\n3. それぞれのジョブには、指定のキーワードで定義された、 GitLab CI 用の一連のルールと指示が含まれます。\n\n4. ジョブは、順序どおりに、並列に、または [DAG\n(英語版)](https://docs.gitlab.com/ee/ci/directed_acyclic_graph/index.html)\nを使って順不同で実行できます。\n\n5. ジョブ間ではファイルを渡してビルドアーティファクトに保存し、インターフェイスからダウンロードできるようにすることも可能です。\n\n6. CI パイプラインに [テストとセキュリティスキャン\n(英語版)](https://docs.gitlab.com/ee/development/integrations/secure.html)\nを追加して、開発中のアプリの品質とセキュリティを確保します。\n\n\n本記事で使用した用語およびキーワードの説明と、関連するドキュメントのリンクを下表にまとめました。\n\n\n### キーワードの説明とドキュメント\n\n\n{: #keywords}\n\n\n| キーワード/用語       | 説明 |\n\n|---------------|--------------------|\n\n| [.gitlab-ci.yml](https://docs.gitlab.com/ee/ci/yaml/) |\nプロジェクトのビルド方法の定義をすべて含むファイル |\n\n| [script](https://docs.gitlab.com/ee/ci/yaml/#script)        |\n実行するシェルスクリプトを定義する |\n\n| [before_script](https://docs.gitlab.com/ee/ci/yaml/#before_script) | (全)\nジョブの前に実行するコマンドを定義するために使用する |\n\n|\n[image](https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-image)\n| 使用するDocker イメージを定義する |\n\n| [stages](https://docs.gitlab.com/ee/ci/yaml/#stages)         |\nパイプラインのステージを定義する (デフォルトは test) |\n\n| [artifacts](https://docs.gitlab.com/ee/ci/yaml/#artifacts)     |\nビルドアーティファクトのリストを定義する |\n\n|\n[artifacts:expire_in](https://docs.gitlab.com/ee/ci/yaml/#artifactsexpire_in)\n| 指定時間後にアップロードしたアーティファクトを削除するために使用する |\n\n| [needs](https://docs.gitlab.com/ee/ci/yaml/#needs) |\nジョブ間の依存関係を定義するときに使用し、ジョブを特定の順序で実行することを可能にする |\n\n| [pipelines](https://about.gitlab.com/topics/ci-cd/cicd-pipeline/) |\nいくつかのステージ (バッチ) で実行されるビルドのグループを指す |\n\n\n※ドキュメントはすべて英語版です。\n\n\n## CI/CDについてさらに詳しく\n\n\n- [GitLab’s guide to CI/CD for beginners (GitLab のビギナーのための CI/CD ガイド\n(英語版))](https://about.gitlab.com/blog/beginner-guide-ci-cd/)\n\n- [Get faster and more flexible pipelines with a Directed Acyclic Graph\n(有向非巡回グラフ（DAG）を使用して、より高速で柔軟なパイプラインを実現する(英語版))](https://about.gitlab.com/blog/directed-acyclic-graph/)\n\n- [Decrease build time with custom Docker image (カスタム化した Docker\nイメージでビルド時間を短縮する\n(英語版))](http://beenje.github.io/blog/posts/gitlab-ci-and-conda/)\n\n- [Introducing the GitLab CI/CD Catalog Beta (GitLab CI/CD カタログベータ版の紹介\n(英語版))](https://about.gitlab.com/blog/introducing-the-gitlab-ci-cd-catalog-beta/)\n\n\n## よくある質問 (FAQ)\n\n\n### CIジョブを順次実行するか、または並列実行するか、どのように選択すればいいですか？\n\n\nCI\nジョブを順次実行するか、並列実行するかを選択する際は、ジョブの依存関係、リソースの利用可能性、実行時間、潜在的な干渉、テストスイートの構造、コスト面を考慮します。たとえば、デプロイジョブが始まるまでに終わらせなければならないビルドジョブがあったとします。その場合、これらのジョブを順次実行して、正しい実行順序を確かめます。一方、ユニットテストや統合テストなどのタスクは独立しており、それぞれの完了には依存しないため、並列実行できます。\n\n\n### GitLab CIの DAG（有向非巡回グラフ）とは何ですか？また、DAG はパイプラインの柔軟性をどのように向上させますか？\n\n\nGitLab CI の有向非巡回グラフ (DAG) は、パイプラインステージの順序を並び替えます。DAG\nはジョブ間の依存関係を設定するため、前のステージにあるジョブが終わり次第、その後のステージのジョブが開始されます。これによりパイプライン全体の実行時間が短縮され、効率が向上し、一部のジョブは通常の順序より早く完了します。\n\n\n### GitLab の CI ジョブに最適なDockerイメージを選ぶ際に重要視しなければならないことは何ですか？\n\n\nGitLab はジョブの実行の際に Docker イメージを使用します。デフォルトのイメージは ruby:3.1\nです。ジョブの要件によって、最適なイメージを選ぶことがとても大切です。ジョブはまず指定された Docker\nイメージをダウンロードしますが、イメージに必要ではない追加パッケージが含まれていると、ダウンロードや実行に余分な時間がかかります。そのため、実行時に不必要な遅延が発生しないように、選択したイメージにはジョブに必要なパッケージだけが含まれていることを確認することが重要です。\n\n\n## 次のステップ\n\n\nソフトウェア開発プラクティスで後れを取らないためにも、次のステップとしてCI/CDコンポーネントの標準化と再利用方法を理解することをお勧めします。[GitLab\nCI/CD カタログ\n(英語版)](https://docs.gitlab.com/ee/architecture/blueprints/ci_pipeline_components/)\nもご確認ください。\n\n\n継続的インテグレーションとデリバリー入門は、[こちら](https://about.gitlab.com/ja-jp/solutions/continuous-integration/)をご覧ください。\n\n\n*監修：川瀬 洋平 [@ykawase](https://gitlab.com/ykawase)\u003Cbr>\n\n（GitLab合同会社 カスタマーサクセス本部 シニアカスタマーサクセスマネージャー）*\n",[936,681],"2025-02-20",{"slug":1049,"featured":6,"template":684},"basics-of-gitlab-ci-updated","content:ja-jp:blog:basics-of-gitlab-ci-updated.yml","Basics Of Gitlab Ci Updated","ja-jp/blog/basics-of-gitlab-ci-updated.yml","ja-jp/blog/basics-of-gitlab-ci-updated",{"_path":1055,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":1056,"content":1062,"config":1068,"_id":1070,"_type":16,"title":1071,"_source":18,"_file":1072,"_stem":1073,"_extension":21},"/ja-jp/blog/integrating-azure-devops-scm-and-gitlab",{"title":1057,"description":1058,"ogTitle":1057,"ogDescription":1058,"noIndex":6,"ogImage":1059,"ogUrl":1060,"ogSiteName":776,"ogType":802,"canonicalUrls":1060,"schema":1061},"Azure DevOpsリポジトリをGitLabと統合する方法","Azure DevOpsリポジトリのGitLabとの統合は簡単。やり方を学んで、Azure DevOpsからGitLab CI/CDへの移行をスムーズに行いましょう。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664363/Blog/Hero%20Images/aleksey-kuprikov.jpg","https://about.gitlab.com/blog/integrating-azure-devops-scm-and-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Azure DevOpsリポジトリをGitLabと統合する方法\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Itzik Gan Baruch\"}],\n        \"datePublished\": \"2020-07-09\",\n      }",{"title":1057,"description":1058,"authors":1063,"heroImage":1059,"date":1064,"body":1065,"category":14,"tags":1066,"updatedDate":1067},[1043],"2020-07-09","## 目次\n\n1. Azure DevOpsはGitLabに統合できるのか \n\n2. GitLabとAzure DevOpsの違い\n\n3. GitLabからAzureへの接続方法\n\n4. 推奨される開発フロー\n\n5. デプロイのワークフローのデモ動画\n\n6. 試みる価値のあるソリューション\n\n7. まとめ\n\n\nAzure\nDevOpsリポジトリ内にコードを置いたままで、GitLabのパイプラインでCI/CDを実行する方法をご説明します。リンクは特に断りのない限り、英語版ページへのリンクとなります。ご留意ください。\n\n\n最近、Azure DevOps/VSTS（Visual Studio Team\nServices）のソースコード管理（SCM）とGitLabを統合することは可能でしょうかと質問を受けることが続きました。こういった質問をしてきた方は、GitLabのような最新の[CI/CD\nソリューション](https://about.gitlab.com/topics/ci-cd/)を検討しているものの、段階移行で一時的に新旧のシステムが共存する間は、コードをAzure\nDevOps/VSTS内で管理する必要があるようです。\n\n\n## Azure DevOpsはGitLabに統合できるのか\n\n\nはい、Azure DevOpsはGitLabに統合できます。\n\n\nGitLabではGitLab CI/CDをGitLabの組み込みSCMと併せて使用することを推奨していますが、Azure\nDevOpsのソースコード管理とGitLabとを統合すると、コードをAzure\n[DevOps](https://about.gitlab.com/ja-jp/topics/devops/)リポジトリに残したままGitLab\nCI/CDも導入できるため、Azure\nDevOpsから徐々にGitLabに移行することが可能です。GitLabのセルフマネージドバージョンと、SaaSバージョンのどちらでも統合が可能です。しかし、統合可能なのは、Azure\nDevOps/VSTSの Gitバージョン管理のみです。TFVC（Team Foundation Version\nControl）はサポートされていませんのでご注意ください。\n\n\n### Azure DevOpsとの統合を可能にするGitLabの2つの機能\n\n\n[外部リポジトリ用GitLab\nCI/CD](https://docs.gitlab.com/ee/ci/ci_cd_for_external_repos/) ― GitLab\nCI/CDは外部リポジトリ（GitHub, Bitbucket Cloud など）のGitサーバーで利用できます。\n\n\n[リモートリポジトリのミラーリング](https://docs.gitlab.com/ee/user/project/repository/mirror/)\n―\nリポジトリは外部ソースとの間でミラーリングできます。どのリポジトリをソースとして使用するかも選択できます。ミラーリングを行なうと、ブランチ、タグ、コミットなどが自動的に同期されます。\n\n\n#### DevOps におけるリポジトリとは？\n\n\nGitLabやAzureのようなツールにおけるコードリポジトリは、あらゆるソースコードを格納するために存在します。こういったリポジトリはDevOpsの「リポ」と呼ばれたり、「ソースリポジトリ」と呼ばれたりします。名前がどうであれ、デベロッパーが高いコード品質を目指して作業するための場所をコードリポジトリが提供することに変わりありません。GitLabは、バージョン管理によるソースコード管理に[Gitベースのリポジトリ（日本語版）](https://about.gitlab.com/ja-jp/solutions/source-code-management/)を使用します。Gitベースのリポジトリを使用したバージョン管理により、GitLabユーザーがコードレビューを行い、開発面での問題を簡単に解決することができるのです。\n\n\n## GitLabとAzure DevOpsの違い\n\n\nAzure\nDevOpsには、開発ライフサイクルを管理するための幅広いサービスがあります。主要機能には、アジャイルプランニングボード、ソースコード管理用のプライベートGitリポ、そしてAzureパイプラインなどがあります。\n\nDevSecOpsライフサイクル全体に対応した単一プラットフォームとして提供されるGitLabには以下が含まれます。\n\n- プランニングとコラボレーション\n\n- ソースコード管理\n\n- コードレビュー\n\n- CI/CDパイプライン\n\n- 継続的なセキュリティスキャンと監視\n\n- 高度なデプロイ\n\n- 脆弱性の管理\n\n\u003Cbr>\n\n\u003Cbr>\n\nGitLabは、セキュリティとコンプライアンスを強化しながら、DevSecOpsのライフサイクル全体の管理をサポートしてソフトウェアを迅速かつ効率的に提供します。\n\n\n## GitLabからAzureへの接続方法\n\n\nソースコード管理をAzureからGitLabへ完全に移行するには時間がかかる場合があります。ここでは、スムーズな移行のために、GitLabからAzure統合に接続する手順を説明します。\n\n\n1. 「New Project（新規プロジェクト）」ボタンをクリックして、GitLab内に新規プロジェクトを作成します。\n![新規プロジェクトの作成](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado1.png){:\n.large.center}\n\n\n2. 「CI/CD for external repo（外部リポジトリ用 CI/CD）」タブを選択し、Repo by\nURL（リポジトリのURL）をクリックします。  ![外部リポジトリ用\nCI/CD](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado2.png){:\n.large.center}\n\n\n3. Azure DevOps 内でリポジトリを開き、「Clone（クローン）」をクリックします。\n  ![クローンURLを入手する](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado3.png){: .large.center}\n\n4. URLをコピーします。お使いのリポジトリがプライベートだった場合、Gitの認証情報を生成する必要があります。「Generate Git\nCredentials（Git認証情報を生成）」をクリックし、ユーザー名とパスワードをコピーしてください。\n![認証情報](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado4.png){:\n.large.center}\n\n\n5. 「Git repository URL（Gitリポジトリの URL）下の欄にURLを貼り付けます。\n\nプロジェクト名を付けます。\n\n可視性の表示レベルを設定します。\n\n「プロジェクトを作成」をクリックします。\n\nAzure DevOpsリポジトリがプライベートだった場合には、ユーザー名とパスワードを追加します。\n\n\n__注__:リポジトリは、http://、https:// または git:// でアクセスできなければなりません。http:// または\nhttps:// プロトコルを使用する場合は、リポジトリへの正確なURLを指定してください。HTTPリダイレクトは実行されません。\n\n  ![プロジェクトフォームの作成\"](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado5.png){: .large.center}\n\n6. プロジェクトはGitLabと正常にミラーリングされました。これで、ブランチ、タグ、コミットがGitLabと自動的に同期されるようになります。\n\n\n7. CI/CDパイプラインを構成するオプションは2つあります。\n  ![Auto DevOps 設定](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado6.png){: .shadow.large.center}\n\nAuto DevOpsを使わずにパイプライン構成をご自分で定義したい場合には、お使いのリポジトリのルートディレクトリに\n[.gitlab-ci.yml](https://docs.gitlab.com/ee/ci/yaml/)\nファイルを追加してください。このyamlコードには、[CI/CD定義](https://about.gitlab.com/blog/guide-to-ci-cd-pipelines/)\nを必ずインクルードしてください。\n\n\nこのファイルがルートディレクトリにインクルードされると、CI/CDパイプラインが各コミットごとにトリガーされます。.gitlab-ci.yml\nに不慣れな場合には、.gitlab-ci.yml\nという名前でファイルを作成し、以下のコードを貼り付けてください。このコードにはビルドステージとテストステージがあり、それぞれに、単一のジョブが含まれます。このジョブは各ステージでコンソールにテキストを表示します。\n\n\n後でそれぞれのジョブにスクリプトを追加できます。また、ジョブやステージの追加も可能です。より複雑なパイプラインを作成するときは、ゼロから着手するのではなく、[GitLabに付属の](https://gitlab.com/gitlab-org/gitlab/tree/master/lib/gitlab/ci/templates)[パイプラインテンプレートを使用する](https://docs.gitlab.com/ee/ci/yaml/#includetemplate)とよいでしょう。\n\n\n```\n\nstages:\n  - build\n  - test \n\nbuild:\n  stage: build\n  script:\n    - echo \"Build job\"\n\ntest:\n  stage: test\n  script:\n    - echo \"Test job\"\n```\n\n\n以上です。これで準備は済みました。\n\n\n## 推奨される開発フロー \n\n\n![開発フローの図](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado_7_2.png){:\n.shadow.large.center}\n\n\n1. コード（デベロッパーが選択したIDE）\u003Cbr>\n\nデベロッパーはお気に入りのIDEを使用してコードを開発し、リポジトリをワークステーションに複製し、ブランチを作成します。\n  ![Visual Studioのコード](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado8.png){: .shadow.large.center}\n\u003Cbr>\n\n\n2. コミット（GIT）\u003Cbr>\n\nフィーチャーの開発またはバグ修正が完了したあと、デベロッパーはワークをAzureリポジトリサーバーにプッシュします。  ![Azure\nDevOpsリポ](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado9.png){:\n.shadow.large.center}\n\n\u003Cbr>\n\n3. ビルド（GitLab）\u003Cbr>\n\nコミット履歴つきのブランチがGitLabにミラーリングされます。CI/CDパイプラインがトリガーされ、このパイプラインにより、コードがビルドされます。 \n![GitLabパイプライングラフ](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado10.png){:\n.shadow.large.center}\n\n    アーティファクトが作成され、ダウンロードできるようになります。\n  ![アーティファクト](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado11.png){: .shadow.large.center}\n\n    「Auto DevOps」が有効化されていれば、コンテナイメージが作成され、ビルトインのコンテナレジストリにプッシュされます。 \n![GitLabコンテナレジストリ](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado12.png){:\n.shadow.large.center}\n\n    プロジェクト内でパッケージレジストリが有効化されている場合には、パッケージが指定されたパッケージマネージャに公開されます。 \n![GitLabパッケージレジストリ](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado13.png){:\n.shadow.large.center}\n\n\u003Cbr>\n\n4. テスト (GitLab)\u003Cbr>\n\nCI パイプラインの一環として、セキュリティスキャン、ライセンススキャン、その他のテストが実行されます。 ![GitLab\nスキャン](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado14.png){:\n.shadow.large.center}\n\n\u003Cbr>\n\n5. レビューとプルリクエスト (GitLabおよびAzure DevOpsリポジトリ)\u003Cbr>\n\nGitLabでパイプラインの結果をレビューし、エラーなくパイプラインがパスした場合、かつ、新しい変更により新たな脆弱性が生じていなければ、Azure\nDevOpsでプルリクエストを作成します。コードレビューが始まったら、デベロッパーはメインにマージする前に、新しい変更を加える必要がある場合があります。各コミットは、\nGitLab内でCI/CDパイプラインをトリガーします。 ![Azure\nDevOpsプルリクエスト](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado15.png){:\n.shadow.large.center}\n\n\u003Cbr>\n\n6. マージ（Azure DevOpsリポジトリとGitLab）\u003Cbr>\n\nAzure DevOpsのプルリクエストが承認され、ブランチがAzure DevOpsリポジトリのメインブランチにマージされます。\n\n\nパイプラインの構成により異なりますが、メインブランチへのこのマージは\nGitLab内のCI/CDパイプラインをトリガーし、マージ結果が検証され、新しいパッケージとコンテナイメージがビルドされ、その後それらがデプロイされます。 \n![GitLab\nCI/CDパイプラインのグラフ](https://about.gitlab.com/images/blogimages/ado_and_gitlab/ado16.png){:\n.shadow.large.center}\n\n\u003Cbr>\n\n## デプロイのワークフローのデモ動画\n\n\n\u003Ciframe width=\"560\" height=\"315\"\nsrc=\"https://www.youtube.com/embed/HfpP2pEmkoM\" frameborder=\"0\"\nallow=\"accelerometer; autoplay; encrypted-media; gyroscope;\npicture-in-picture\" allowfullscreen>\u003C/iframe>\n\n\n## 試みる価値のあるソリューション\n\n\nGitLabは、トップクラスのソースコード管理（SCM）とCI/CDソリューションを単一のアプリケーションで提供し、多くの\n[GitLab顧客](https://about.gitlab.com/customers/)がこのパワフルな組み合わせを利用しています。しかし、チームがすぐにリポジトリをGitLab\nSCMに移行できないという制約があるケースがあることも理解しています。そのような場合のために、一時的に外部リポジトリ用GitLab\nCI/CDを提供しています。\n\n\n## まとめ\n\n\nソースコード管理（SCM）とGitLabのCI/CDソリューションは、簡単に統合ができます。「Azure\nDevOpsリポジトリをGitLabのCI/CDに統合することも**簡単にできる**ということを納得していただけたでしょうか。GitLabのCI/CDについてもっと詳しくお知りになりたい場合には、[こちらの記事（日本語版）](https://about.gitlab.com/ja-jp/solutions/continuous-integration/)をご覧ください。\n\n\n### GitLab CI/CDについてさらに詳しく\n\n\n[フォレスターのレポート:主要なCI/CDツールの比較（英語版）](https://about.gitlab.com/analysts/forrester-cloudci19/)\n\n\n[AWS Fargateを使用したGitLab\nCIのオートスケール（英語版）](/blog/introducing-autoscaling-gitlab-runners-on-aws-fargate/)\n\n\n[お客様事例:ゴールドマン・サックスはビルド頻度を2週間に1回から1日に1000回以上へ改善（日本語版）](https://about.gitlab.com/ja-jp/customers/goldman-sachs/)\n\n\n\u003Cbr>\n\n\u003Cbr>\n\n\u003Cbr>\n\n\nカバーイメージ出典：[Aleksey Kuprikov](https://unsplash.com/@alekskuprfilmz) on\n[Unsplash](https://unsplash.com/)\n\n{: .note}\n\n\n\u003Cbr>\n\n\u003Cbr>\n\n\n*監修：ソリス ジェレズ / Jerez Solis [@jerezs](https://gitlab.com/jerezs)\u003Cbr>\n\n（GitLab合同会社 ソリューションアーキテクト本部 ソリューションアーキテクト）*\n",[111,852,681],"2025-02-26",{"slug":1069,"featured":6,"template":684},"integrating-azure-devops-scm-and-gitlab","content:ja-jp:blog:integrating-azure-devops-scm-and-gitlab.yml","Integrating Azure Devops Scm And Gitlab","ja-jp/blog/integrating-azure-devops-scm-and-gitlab.yml","ja-jp/blog/integrating-azure-devops-scm-and-gitlab",{"_path":1075,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":1076,"content":1082,"config":1091,"_id":1093,"_type":16,"title":1094,"_source":18,"_file":1095,"_stem":1096,"_extension":21},"/ja-jp/blog/using-ansible-and-gitlab-as-infrastructure-for-code",{"title":1077,"description":1078,"ogTitle":1077,"ogDescription":1078,"noIndex":6,"ogImage":1079,"ogUrl":1080,"ogSiteName":776,"ogType":802,"canonicalUrls":1080,"schema":1081},"GitLabとAnsibleを使ってIaCを作成する方法","Ansible playbookを使ってIaCを作成します。GitLab CIが持つ力を探求してみてください。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749665322/Blog/Hero%20Images/gitlab-ansible-cover.png","https://about.gitlab.com/blog/using-ansible-and-gitlab-as-infrastructure-for-code","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLabとAnsibleを使ってIaCを作成する方法\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Brad Downey\"},{\"@type\":\"Person\",\"name\":\"Sara Kassabian\"}],\n        \"datePublished\": \"2019-07-01\",\n      }",{"title":1077,"description":1078,"authors":1083,"heroImage":1079,"date":1086,"body":1087,"category":14,"tags":1088,"updatedDate":1090},[1084,1085],"Brad Downey","Sara Kassabian","2019-07-01","IaCとして管理されるAnsible playbookを実行する際に力を発揮する、GitLab CIの機能を探求してみませんか。\n\n\nGitLab\nCIは、[IaC](https://about.gitlab.com/ja-jp/topics/gitops/infrastructure-as-code/)や[GitOps](https://about.gitlab.com/ja-jp/solutions/gitops/)など、さまざまな用途に使用できる強力なツールです。GitLabはツールに依存しないプラットフォームですが、AnsibleはIaCを管理するために、開発者によく使用される言語なので、今回はAnsibleを使用していきます。\n\n\n## Ansibleとは\n\n\nAnsibleはオープンソースであり、デプロイ、構成、そしてコンピュータシステムの管理を自動的に行なう際に使用し、構成管理ツールに分類されます。開発者やシステム管理者がAnsibleを使用すると、サーバーの構成やアプリケーションのデプロイ、またネットワークデバイスの管理といった、複雑な、繰り返しの多いプロセスを自動化できます。AnsibleはYAMLを使って、playbookとして知られている宣言型のタスク説明を作成します。作成された宣言型のタスク説明は、コマンドを実行するターゲットホストへのSSH接続を通じてAnsibleが行なう、望まれるシステム状態を説明してくれます。\n\n\n## デモ：GitLab CI と Ansible\n\n\n[GitLab\nCI](https://about.gitlab.com/ja-jp/solutions/continuous-integration/)の特に優れている機能のひとつは、ローカルの端末等に依存ライブラリをインストールしなくても\n[Ansible\nplaybook](https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html)（外部サイト）のコードを編集しデプロイできることです。デモでご紹介するプロジェクトは、セキュリティポリシーに従って毎月すべてのデバイスのSNMP文字列を更新する必要がありますが、これはGitLabがホストする\n[GitLab.com](https://about.gitlab.com/ja-jp/pricing/)で簡単に行なうことができます。  \n\n\nまずはじめに、Ansible playbookを開いてください。ここには次の4つのタスクがあります。\n\n\n* ルーターの情報を収集  \n\n* バージョンを表示  \n\n* シリアル番号を表示  \n\n* SNMPを構成\n\n\nこのデモでは、SNMPの文字列の構成方法に焦点を当てています。構成は簡単な一連のステップに従うことで完了できます。\n\n\n## はじめに：イシューボード\n\n\nGitLabではプロジェクトに関する計画はすべて同じやり方、[イシューの起票](https://handbook.gitlab.com/handbook/marketing/brand-and-product-marketing/product-and-solution-marketing/getting-started/101/#issue)から始まります。そのためGitLabのワークフローの最初のステップでは、[ansible-demoプロジェクト](https://gitlab.com/bdowney/ansible-demo)内のイシューボードを確認します。[ansible-demoイシューボード](https://gitlab.com/bdowney/ansible-demo/-/boards)を見ると、すでに\n[すべてのルーターのSNMP文字列の変更](https://gitlab.com/bdowney/ansible-demo/issues/4)に関連するイシューがあることがわかります。イシューの中に、SNMP文字列を毎月ローテーションさせ、読み取り専用と読み書き両方の場合には、異なる文字列を使用する必要があることを記述したGitLabセキュリティポリシーのWikiへのリンクがあります。\n\n\n![Security\npolicies](https://about.gitlab.com/images/blogimages/ansible_screenshots/security_policies_1A.png){:\n.shadow.medium.center}\n\nSNMP 文字列用の GitLab セキュリティポリシー\n\n{: .note.text-center}\n\n\nGitLabのセキュリティポリシーによると、SNMP文字列を毎月更新する必要があります。  \n\n\n次に、[2つのルーターのデモ](https://gitlab.com/bdowney/ansible-demo/blob/master/ci-cd-demo/ci.yml)でSNMP文字列を設定するコマンドが、イシューで概説されているGitLabのセキュリティポリシーに従っていることを確認します。\n\n\n![Ansible SNMP\nchange](https://about.gitlab.com/images/blogimages/ansible_screenshots/ansible_snmp_change_2.png){:\n.shadow.medium.center}\n\nSNMP 文字列設定のためのコマンド\n\n{: .note.text-center}\n\n\nSNMP文字列を設定するコマンドは、Ansible playbookに記載されています。\n\n\n次に、イシューに戻り、イシューをご自身にアサインしてください。右サイドバーのラベルを`to-do`から`doing`に切り替えるか、または、イシューボードの列をドラッグして移動することもできます。\n\n\n## マージリクエストを作成する\n\n\n次のステップでは、イシューからマージリクエスト (MR)\nを作成します。「Draft」のフラグがMRに付いていることを再度確認してください。これにより、準備ができていないうちにmasterブランチにマージされてしまうことが防止されます。ここでは、SNMP文字列への変更点が少ないので、ローカルの\nIDEでソースコードを編集するのではなく、GitLabの [Web\nIDE](https://docs.gitlab.com/ee/user/project/web_ide/) を使います。  \n\n\n* [CI/CD](https://about.gitlab.com/topics/ci-cd/)デモセクションを開きます。  \n\n* Ansible playbookに移動します。  \n\n* SNMPセクションを次のように編集します。\n\n\n```\n\n-snmp-server community New-SNMP-DEMO1 RO\n\n\n-snmp-server community Fun-SNMP-RW-STR RW\n\n```\n\n\n*  [イシュー](https://gitlab.com/bdowney/ansible-demo/issues/1)で説明されている[GitLab\nセキュリティポリシー](https://gitlab.com/bdowney/ansible-demo/wikis/Security-Policies)に従い、ROとRWが異なる文字列として設定されていることに注意してください。\n\n\n## 変更をコミットする\n\n\nSNMP文字列がガイドラインに沿って更新されましたので、変更をコミットします。最新のコミットでMRが更新されたことを確認するために、side-by-side比較機能を利用してください。\n\n\n![Commit\nchanges](https://about.gitlab.com/images/blogimages/ansible_screenshots/side-by-side_3.png){:\n.shadow.medium.center}\n\nGitLab Ansible 内でのマージリクエストのサイド・バイ・サイド比較\n\n{: .note.text-center}\n\n\n並べて比較できるツールにより、変更内容が一目でわかります。\n\n\n## マージリクエストの出力\n\n\n変更内容をコミットすると、GitLab CIパイプラインが自動的に起動されます。ここでは、次のようなタスクが実行されます。\n\n構文のチェック\n\nドライラン\n\nラボ/シミュレーション環境での変更点のテスト\n\nGitLab CIパイプラインの各ジョブの進捗状況と出力を表示して、SNMPの更新を実行します。\n\n\n![Job\nrunning](https://about.gitlab.com/images/blogimages/ansible_screenshots/job_running_4.png){:\n.shadow.medium.center}\n\nGitLabジョブの出力\n\n{: .note.text-center}\n\n\nジョブからの出力を確認して、シミュレーション環境でSNMPの更新が確実に行なわれたことを確認します。\n\nこのすべてのタスクは、マージリクエスト (MR) 内で実行され、記録されます。\n\n\n![Pipeline](https://about.gitlab.com/images/blogimages/ansible_screenshots/pipeline_5A.png){:\n.shadow.medium.center}\n\nGitLab CIパイプライン内のチェックマーク\n\n{: .note.text-center}\n\n\n緑色のチェックマークは、GitLab CIパイプラインで各タスクが正常に完了したことを示しています。\n\n次に、ラボのルーターにログインして、変更内容を確認します。\n\n\n![routers\nsnmp](https://about.gitlab.com/images/blogimages/ansible_screenshots/routersnmp_6.png){:\n.shadow.medium.center}\n\nルーターのSNMP\n\n{: .note.text-center}\n\n\n読み取り専用（RO）および読み書き（RW）のSNMP文字列の変更点がルーターに反映されています。\n\n\n## マージリクエストのレビュー\n\n\nオプションとして、[マージリクエスト（MR）の承認](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)をアクティブ化することもできます。これにより、変更が本番環境に送られる前に、より多くのユーザーが変更点をレビューできるようになります。\n\n\n![approvers](https://about.gitlab.com/images/blogimages/ansible_screenshots/approvers_7.png){:\n.shadow.medium.center}\n\nGitLabでのSNMP文字列の更新\n\n{: .note.text-center}\n\n\nマージリクエスト（MR）は、masterブランチへのマージを行なう前に、別のユーザーに作業内容をレビューしてもらうように設定することができます。\n\n\n## Masterブランチへのマージ\n\n\nテストが完了したら、変更点をmasterブランチにマージします。masterブランチには、本番環境コードが格納されています。\n\n準備ができたら、`Mark`ボタンをクリックし、次に`Merge`をクリックします。\n\n「Draft」のステータスを解決すると、MRがマージされ、イシューがクローズされます。\n\nすると、新しいパイプラインが実行され、追加のステップとして playbookを本番環境で実行する、すべてのテストが実行されます。\n\n「パイプライン」の画面では、その進捗とログが確認できます。このプロセスが完了したら、本番用ルーターにログインし、SNMPセキュリティ文字列が更新されたことを確認します。\n\n\n## GitLab CIの魔法\n\n\nこれまで説明してきたさまざまな機能を可能にした魔法は GitLab CIです。GitLab\nCIパイプラインとは、Ansibleコードをテストしてデプロイするために必要なあらゆることを実行する、一連の連続したタスクを意味します。\n\n\nGitLab CIは、リポジトリ内に存在する単一のシンプルな [YAML\nファイル](https://about.gitlab.com/blog/three-yaml-tips-better-pipelines/)である`.gitlab-ci.yml`で構成されています。\n\n\nこのデモでは`.gitlab-ci.yml`ファイルが3つのステージで構成されていることがご確認いただけます。\n\n1. Deploy：Ansibleを使用する AWSに 、２つのルーターのシミュレーションネットワークが作成されます。\n\n2. Demo：SNMP文字列を変更するplaybook が実行されます。\n\n3. Destory：２つのルーターのシミュレーションネットワークが破棄されます。\n\n\nGitLab CIは、ベースイメージで始まります。この場合、必要なすべての\nAnsibleバイナリと依存ライブラリを含むDockerイメージを使用しています。必要に応じて、それぞれのステージで実行するコマンドと、依存関係を指定します。\n\n\n![More\ncode](https://about.gitlab.com/images/blogimages/ansible_screenshots/more_code_9A.png){:\n.shadow.medium.center}\n\n単純なYAMLファイルには、GitLab CIの3つのフェーズが含まれます。\n\n{: .note.text-center}\n\n\n![More\nCode](https://about.gitlab.com/images/blogimages/ansible_screenshots/more_code_10A.png){:\n.shadow.medium.center}\n\nGitLab CIのデモレベル\n\n{: .note.text-center}\n\n\nGitLab CIのデモステージを覗いてみましょう。これはAnsible playbookを実行しているものです。\n\n\n今度はパイプラインを見てみましょう。GitLab\nCIを使用すれば、コンピュータにAnsibleの依存関係をインストールすることなく構成管理を実装できることがわかります。これは、IaCを実行するために\nGitLab CIを使用する方法の一例に過ぎません。以下のリンクは、完全版チュートリアルの動画ですので、ぜひご覧ください。\n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/M-SgRTKSeOg\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\n## FAQ - よくある質問\n\n\n### Q: Ansibleとは\n\n\nA:\nAnsibleとは、ITプロセスの自動化と構成管理を可能にするオープンソースのツールです。アプリケーションのデプロイ、構成管理、オーケストレーション、プロビジョニングなど、コンピュータシステムの管理を自動的に行なう際に使用します。\n\n\nAnsibleを使用すると、サーバーの構成やアプリケーションのデプロイ、またネットワークデバイスの管理といった、複雑な、繰り返しの多いワークフローのオーケストレーションが可能になります。AnsibleはYAMLを使って、playbookとして知られている宣言型のタスク説明を作成します。作成された宣言型のタスク説明は、コマンドを実行するターゲットホストへのSSH接続を通じてAnsibleが行なう、望まれるシステム状態を説明してくれます。詳しくは[こちら](#heading=h.llxgny6efk4z)をご覧ください。\n\n\n### Q: Ansible Playbookとは\n\n\nA: Ansible\nPlaybookはyamlで書かれたタスクのリストファイルのことで、指定したインベントリーやホストのグループに対して自動的に実行されます。ネットワークインフラ、WindowsサーバーなどITインフラに適用するタスクやコンフィグレーションをこのファイルで定義します。Ansibleタスクは、1つまたは複数タスクがplayとしてグループ化され、それぞれのplayが特定のホストやホストグループに対して実行されます。クラウド管理、ユーザー管理、ネットワーク、セキュリティ、構成管理などがAnsible\nPlaybookで管理できます。\n\n\n### Q: GitLab CIとは\n\n\nA: GitLab CI（継続的インテグレーション、Continuous\nIntegration）とは、GitLab上でコードの変更が行われた際に自動的にテストやビルドを実行するツールで、サードパーティのツールやライブラリを導入しなくても利用できます。GitLab\nCIは、すべてのコード変更を共有ソースコードリポジトリのmainブランチに早い段階で頻繁に統合し、コミットやマージ時に各変更を自動的にテストし、自動的にビルドを開始するプラクティスのことです。継続的インテグレーションを行うことで、エラーやセキュリティの問題をより簡単に、開発プロセスのかなり早い段階で特定し、修正することが可能になります。詳しくは[こちら](https://about.gitlab.com/ja-jp/topics/ci-cd/#what-is-continuous-integration-ci)をご覧ください。\n\n\n### Q: GitLab CIとAnsibleを使用するメリットは何ですか\n\n\nA: GitLab CIなら、ローカルの端末等に依存ライブラリをインストールしなくてもAnsible\nplaybookのコードを編集しデプロイできます。また、GitLab\nCIパイプラインは、Ansibleコードをテストしてデプロイするために必要なあらゆることを実行する、一連の連続したタスクです。つまり、GitLabでは、リポジトリの管理とCIおよびAnsible\nTowerのワークフロー実行が行なえます。加えられた変更の内容、たとえば、いつ、誰がどのファイルに対して変更を行なったのかも自動で記録されるうえ、マージリクエスト(MR)を使えば、理由や目的などのメモも残せるなど、いろいろなメリットがあります。\n\n\n*\\*監修：伊藤 俊廷 [@toshitakaito](https://gitlab.com/toshitakaito) \n\n（GitLab合同会社 ソリューションアーキテクト本部 スタッフソリューションアーキテクト）*\n",[1089,111],"demo","2024-10-21",{"slug":1092,"featured":6,"template":684},"using-ansible-and-gitlab-as-infrastructure-for-code","content:ja-jp:blog:using-ansible-and-gitlab-as-infrastructure-for-code.yml","Using Ansible And Gitlab As Infrastructure For Code","ja-jp/blog/using-ansible-and-gitlab-as-infrastructure-for-code.yml","ja-jp/blog/using-ansible-and-gitlab-as-infrastructure-for-code",{"_path":1098,"_dir":249,"_draft":6,"_partial":6,"_locale":7,"seo":1099,"content":1105,"config":1111,"_id":1113,"_type":16,"title":1114,"_source":18,"_file":1115,"_stem":1116,"_extension":21},"/ja-jp/blog/keeping-git-commit-history-clean",{"title":1100,"description":1101,"ogTitle":1100,"ogDescription":1101,"noIndex":6,"ogImage":1102,"ogUrl":1103,"ogSiteName":776,"ogType":802,"canonicalUrls":1103,"schema":1104}," git Commit（コミット）の履歴が重要な理由とその整理方法","git コミット履歴は、煩雑になりがち。gitコミットのメッセージ履歴をクリーンに保ち、変更内容を把握する方法とその重要性をご紹介します。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659457/Blog/Hero%20Images/keep-git-commit-history-clean.jpg","https://about.gitlab.com/blog/keeping-git-commit-history-clean","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \" git Commit（コミット）の履歴が重要な理由とその整理方法\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Kushal Pandya\"}],\n        \"datePublished\": \"2018-06-07\",\n      }",{"title":1100,"description":1101,"authors":1106,"heroImage":1102,"date":1108,"body":1109,"category":14,"tags":1110,"updatedDate":938},[1107],"Kushal Pandya","2018-06-07","## 目次\n\n\n- git コミットの履歴が重要な理由\n\n- 直前のgitコミットメッセージを変更する\n\n- ２つ以上前のgitコミットの内容を修正する\n\n- 修正用に作ったgitコマンドは元のコミットと組み合わせて履歴をクリーンに保つ\n\n- gitコミットのセーフティネット reflogs\n\n- gitコミットを整理して、未来の開発に備えよう\n\n\ngitコミットは、リポジトリの重要な要素のひとつであり、コミットメッセージはリポジトリの履歴ログでもあります。プロジェクトやリポジトリがチームメンバーに編集・更新（新機能の追加、バグ修正、アーキテクチャのリファクタリングなど）されていくなかで、コミットメッセージは何がどのように変更されたのかを知るための重要な手掛かりとなります。そのため、コミットメッセージは基本的な変更を、簡潔かつ正確に反映することが求められます。\n\n\n## git コミットの履歴が重要な理由\n\n\ngitコミットメッセージは、あなたが触れたコードに残す指紋のようなものです。あなたが今日コミットしたコードには、一年後に同じ変更を見たときにもすぐに理解できるよう、簡潔で正確なメッセージが添えてあるべきです。gitコミットがコンテキストに基づいて分割されていれば、該当のコミットで発生したバグを素早く見つけられ、バグの原因となるコミットを元通りに修正することができます。大規模なプロジェクトで作業していると、常に多数の更新、追加、削除が発生します。そのような場合に、適切なコミットメッセージの記載は不可欠になります。この記事では、gitリポジトリでの作業中に開発者がよく使うgitコミットについて解説していきます。\n\nこの記事では、git\nの基本的な知識、ブランチの仕組み、ブランチの未コミットの変更をステージングす方法、変更をコミットする方法について理解していることを前提としています。これらの流れがよくわからないという方は、こちらのGitLabドキュメントもご参照ください。\n\n\n- [Situation 1: I need to change the most recent\ncommit](#situation-1-i-need-to-change-the-most-recent-commit)\n\n- [Situation 2: I need to change a specific\ncommit](#situation-2-i-need-to-change-a-specific-commit)\n\n- [Situation 3: I need to add, remove, or combine\ncommits](#situation-3-i-need-to-add-remove-or-combine-commits)\n\n- [Situation 4: My commit history doesn't make sense, I need a fresh\nstart!](#situation-4-my-commit-history-doesnt-make-sense-i-need-a-fresh-start)\n\n\nBut before we dive in, let's quickly go through what a typical development\nworkflow looks like in our hypothetical Ruby application.\n\n\n**Note:** This article assumes that you are aware about basics of Git, how\nbranches work, how to add uncommitted changes of a branch to stage and how\nto commit the changes. If you're unsure of these flows, [our\ndocumentation](https://docs.gitlab.com/ee/topics/git/index.html) is a great\nstarting point.\n\n\n## A day in the life\n\n\nHere, we are working on a small Ruby on Rails project where we need to add a\nnavigation view on the homepage and that involves updating and adding\nseveral files. Following is a step by step breakdown of the entire flow:\n\n\n- You start working on a feature with updating a single file; let's call it\n`application_controller.rb`\n\n- This feature requires you to also update a view: `index.html.haml`\n\n- You added a partial which is used in index page: `_navigation.html.haml`\n\n- Styles for the page also need to be updated to reflect the partial we\nadded: `styles.css.scss`\n\n- Feature is now ready with the desired changes, time to also update tests;\nfiles to be updated are as follows:\n  - `application_controller_spec.rb`\n  - `navigation_spec.rb`\n- Tests are updated and passing as expected, now time to commit the changes!\n\n\nSince all the files belong to different territories of the architecture, we\ncommit the changes isolated of each other to ensure that each commit\nrepresents a certain context and is made in a certain order. I usually\nprefer backend -> frontend order where most backend-centric change is\ncommitted first, followed by the middle layer and then by frontend-centric\nchanges in the Git list commits.\n\n\n1.  `application_controller.rb` & `application_controller_spec.rb`; **Add\nroutes for navigation**.\n\n2.  `_navigation.html.haml` &  `navigation_spec.rb`; **Page Navigation\nView**.\n\n3.  `index.html.haml`; **Render navigation partial**.\n\n4.  `styles.css.scss`; **Add styles for navigation**.\n\n\nNow that we have our changes committed, we create a merge request with the\nbranch. Once you have merge request open, it typically gets reviewed by your\npeer before the changes are merged into repo's `master` branch. Now let's\nlearn what different situations we may end up with during code review.\n\n\n## Situation 1: How to change the most recent Git commit\n\n\nImagine a case where the reviewer looked at `styles.css.scss` and suggested\na change. In such a case, it is very simple to do the change as the\nstylesheet changes are part of **last** commit on your branch. Here's how we\ncan handle this;\n\n\n- You directly do the necessary changes to `styles.css.scss` in your current\nbranch.\n\n- Once you're done with the changes, add these changes to stage; run `git\nadd styles.css.scss`.\n\n- Once changes are staged, we need to _add_ these changes to our last\ncommit; run `git commit --amend`.\n  -  **Command breakdown**: Here, we're asking the `git commit` command to _amend_ whatever changes are present in stage to the most recent commit.\n- This will open your last commit in your Git-defined text editor which has\nthe commit message **Add styles for navigation**.\n\n- Since we only updated the CSS declaration, we don't need to alter the\ncommit message. At this point, you can just save and exit the text editor\nthat Git opened for you and your changes will be reflected in the commit.\n\n\nSince you modified an existing Git commit, these changes are required to be\n_force pushed_ to your remote repo using `git push --force-with-lease\n\u003Cremote_name> \u003Cbranch_name>`. This command will override the commit `Add\nstyles for navigation` on remote repo with updated commit that we just made\nin our local repo.\n\n\nOne thing to keep in mind while force pushing branches is that if you are\nworking on the same branch with multiple people, force pushing may cause\ntrouble for other users when they try to normally push their changes on a\nremote branch that has new commits force pushed. Hence, use this feature\nwisely. You can learn more about Git force push options\n[here](https://git-scm.com/docs/git-push#git-push---no-force-with-lease).\n\n\n## Situation 2: How to change a specific Git commit changes\n\n\nIn the previous situation, the Git commit change was rather simple as we had\nto modify only our last Git commit, but imagine if reviewer suggested to\nchange something in `_navigation.html.haml`. In this case, it is second\ncommit from the top, so changing it won't be as direct as it was in the\nfirst situation. Let's see how we can handle this:\n\n\nWhenever a commit is made in a branch, it is identified by a unique SHA-1\nhash string. Think of it as a unique ID that separates one commit from\nanother. You can view all the previous commits, along with their SHA-1\nhashes in a branch by running the `git log` command. With this, you would\nsee an output that looks somewhat as follows and is a list of commits, where\nthe most recent commits are at the top;\n\n\n```\n\ncommit aa0a35a867ed2094da60042062e8f3d6000e3952 (HEAD ->\nadd-page-navigation)\n\nAuthor: Kushal Pandya \u003Ckushal@gitlab.com>\n\nDate: Wed May 2 15:24:02 2018 +0530\n\n    Add styles for navigation\n\ncommit c22a3fa0c5cdc175f2b8232b9704079d27c619d0\n\nAuthor: Kushal Pandya \u003Ckushal@gitlab.com>\n\nDate: Wed May 2 08:42:52 2018 +0000\n\n    Render navigation partial\n\ncommit 4155df1cdc7be01c98b0773497ff65c22ba1549f\n\nAuthor: Kushal Pandya \u003Ckushal@gitlab.com>\n\nDate: Wed May 2 08:42:51 2018 +0000\n\n    Page Navigation View\n\ncommit 8d74af102941aa0b51e1a35b8ad731284e4b5a20\n\nAuthor: Kushal Pandya \u003Ckushal@gitlab.com>\n\nDate: Wed May 2 08:12:20 2018 +0000\n\n    Add routes for navigation\n```\n\n\nThis is where `git rebase` command comes into play. Whenever we wish to edit\na specific commit with `git rebase`, we need to first rebase our branch by\nmoving back HEAD to the point right _before_ the commit we wish to edit. In\nour case, we need to change the commit that reads `Page Navigation View`.\n\n\n![Commit\nLog](https://about.gitlab.com/images/blogimages/keeping-git-commit-history-clean/GitRebase.png){:\n.shadow.center.medium}\n\n\nHere, notice the hash of commit which is right before the commit we want to\nmodify; copy the hash and perform the following steps:\n\n\n- Rebase the branch to move to commit before our target commit; run `git\nrebase -i 8d74af102941aa0b51e1a35b8ad731284e4b5a20`\n  -  **Git command breakdown**: Here we're running Git's `rebase` command with _interactive_ mode with provided SHA-1 hash as commit to rebase to.\n- This will run rebase command for Git in interactive mode and will open\nyour text editor showing all of your commits that came _after_ the commit\nyou rebased to. It will look somewhat like this:\n\n\n```\n\npick 4155df1cdc7 Page Navigation View\n\npick c22a3fa0c5c Render navigation partial\n\npick aa0a35a867e Add styles for navigation\n\n\n# Rebase 8d74af10294..aa0a35a867e onto 8d74af10294 (3 commands)\n\n#\n\n# Commands:\n\n# p, pick = use commit\n\n# r, reword = use commit, but edit the commit message\n\n# e, edit = use commit, but stop for amending\n\n# s, squash = use commit, but meld into previous commit\n\n# f, fixup = like \"squash\", but discard this commit's log message\n\n# x, exec = run command (the rest of the line) using shell\n\n# d, drop = remove Git commit\n\n#\n\n# These lines can be re-ordered; they are executed from top to bottom.\n\n#\n\n# If you remove a line here THAT COMMIT WILL BE LOST.\n\n#\n\n# However, if you remove everything, the rebase will be aborted.\n\n#\n\n# Note that empty commits are commented out\n\n```\n\n\nNotice how each commit has a word `pick` in front of it, and in the contents\nbelow, there are all possible keywords we can use. Since we want to _edit_ a\ncommit, we need to change `pick 4155df1cdc7 Page Navigation View` to `edit\n4155df1cdc7 Page Navigation View`. Save the changes and exit editor.\n\n\nNow your branch is rebased to the point in time right before the commit you\nmade which included `_navigation.html.haml`. Open the file and perform\ndesired changes as per the review feedback. Once you're done with the\nchanges, stage them by running `git add _navigation.html.haml`.\n\n\nSince we have staged the changes, it is time to move branch HEAD back to the\ncommit we originally had (while also including the new changes we added),\nrun `git rebase --continue`, this will open your default editor in the\nterminal and show you the commit message that we edited during rebase; `Page\nNavigation View`. You can change this message if you wish, but we would\nleave it as it is for now, so save and exit the editor. At this point, Git\nwill replay all the commits that followed after the commit you just edited\nand now branch `HEAD` is back to the top commit we originally had, and it\nalso includes the new changes you made to one of the commits.\n\n\nSince we again modified a commit that's already present in remote repo, we\nneed force push this branch again using `git push --force-with-lease\n\u003Cremote_name> \u003Cbranch_name>`.\n\n\n## Situation 3: How to add, remove, or combine Git commits\n\n\nA common situation is when you've made several commits just to fix something\npreviously committed. Now let's reduce them as much as we can, combining\nthem with the original commits.\n\n\nAll you need to do is start the interactive rebase as you would in the other\nscenarios.\n\n\n```\n\npick 4155df1cdc7 Page Navigation View\n\npick c22a3fa0c5c Render navigation partial\n\npick aa0a35a867e Add styles for navigation\n\npick 62e858a322 Fix a typo\n\npick 5c25eb48c8 Ops another fix\n\npick 7f0718efe9 Fix 2\n\npick f0ffc19ef7 Argh Another fix!\n\n```\n\n\nNow imagine you want to combine all those fixes into `c22a3fa0c5c Render\nnavigation partial`. You just need to:\n\n\n1. Move the fixes up so that they are right below the commit you want to\nkeep in the end.\n\n2. Change `pick` to `squash` or `fixup` for each of the fixes.\n\n\n*Note:* `squash` keeps the git fix commit messages in the description.\n`fixup` will forget the commit messages of the fixes and keep the original.\n\n\nYou'll end up with something like this:\n\n\n```\n\npick 4155df1cdc7 Page Navigation View\n\npick c22a3fa0c5c Render navigation partial\n\nfixup 62e858a322 Fix a typo\n\nfixup 5c25eb48c8 Ops another fix\n\nfixup 7f0718efe9 Fix 2\n\nfixup f0ffc19ef7 Argh Another fix!\n\npick aa0a35a867e Add styles for navigation\n\n```\n\n\nSave the changes, exit the editor, and you're done! This is the resulting\nhistory:\n\n\n```\n\npick 4155df1cdc7 Page Navigation View\n\npick 96373c0bcf Render navigation partial\n\npick aa0a35a867e Add styles for navigation\n\n```\n\n\nAs before, all you need to do now is `git push --force-with-lease\n\u003Cremote_name> \u003Cbranch_name>` and the changes are up.\n\n\nIf you want to remove a Git commit from branch altogether, instead of\n`squash` or `fixup`, just write `drop` or simply delete that line.\n\n\n### How to avoid Git commit conflicts\n\n\nTo avoid conflicts, make sure the commits you're moving up the timeline\naren't touching the same files touched by the commits left after them.\n\n\n```\n\npick 4155df1cdc7 Page Navigation View\n\npick c22a3fa0c5c Render navigation partial\n\nfixup 62e858a322 Fix a typo                 # this changes styles.css\n\nfixup 5c25eb48c8 Ops another fix            # this changes image/logo.svg\n\nfixup 7f0718efe9 Fix 2                      # this changes styles.css\n\nfixup f0ffc19ef7 Argh Another fix!          # this changes styles.css\n\npick aa0a35a867e Add styles for navigation  # this changes index.html (no\nconflict)\n\n```\n\n\n### Pro-tip: Quick Git commit `fixup`s\n\n\nIf you know exactly which commit you want to fixup, when committing you\ndon't have to waste brain cycles thinking of good temporary names for \"Fix\n1\", \"Fix 2\", ..., \"Fix 42\".\n\n\n**Step 1: Meet `--fixup`**\n\n\nAfter you've staged the changes fixing whatever it is that needs fixing,\njust Git commit all the changes like this:\n\n\n```\n\ngit commit --fixup c22a3fa0c5c\n\n```\n\n(Note that this is the hash for the commit `c22a3fa0c5c Render navigation\npartial`)\n\n\nThis will generate this commit message: `fixup! Render navigation partial`.\n\n\n**Step 2: And the sidekick `--autosquash`**\n\n\nEasy interactive rebase. You can have `git` place the `fixup`s automatically\nin the right place.\n\n\n`git rebase -i 4155df1cdc7 --autosquash`\n\n\nHistory will be shown like so:\n\n```\n\npick 4155df1cdc7 Page Navigation View\n\npick c22a3fa0c5c Render navigation partial\n\nfixup 62e858a322 Fix a typo\n\nfixup 5c25eb48c8 Ops another fix\n\nfixup 7f0718efe9 Fix 2\n\nfixup f0ffc19ef7 Argh Another fix!\n\npick aa0a35a867e Add styles for navigation\n\n```\n\n\nReady for you to just review and proceed.\n\n\nIf you're feeling adventurous you can do a non-interactive rebase `git\nrebase --autosquash`, but only if you like living dangerously, as you'll\nhave no opportunity to review the squashes being made before they're\napplied.\n\n\n## Situation 4: My Git commit history doesn't make sense, I need a fresh\nstart!\n\n\nIf we're working on a large feature, it is common to have several fixup and\nreview-feedback changes that are being committed frequently. Instead of\nconstantly rebasing the branch, we can leave the cleaning up of Git commits\nuntil the end of development.\n\n\nThis is where creating patch files is extremely handy. In fact, patch files\nwere the primary way of sharing code over email while collaborating on large\nopen source projects before Git-based services like GitLab were available to\ndevelopers. Imagine you have one such branch (eg; `add-page-navigation`)\nwhere there are tons of commits that don't convey the underlying changes\nclearly. Here's how you can create a patch file for all the changes you made\nin this branch:\n\n\n- The first step to create the patch file is to make sure that your branch\nhas all the changes present from `master` branch and has no conflicts with\nthe same.\n\n- You can run `git rebase master` or `git merge master` while you're checked\nout in `add-page-navigation` branch to get all the changes from `master` on\nto your branch.\n\n- Now create the patch file; run `git diff master add-page-navigation >\n~/add_page_navigation.patch`.\n  -  **Command breakdown**: Here we're using Git's _diff_ feature, and asking for a diff between `master` branch and `add-page-navigation` branch, and _redirecting_ the output (via `>` symbol) to a file named `add_page_navigation.patch` in our user home directory (typically `~/` in *nix operating systems).\n- You can specify any path you wish to keep this file in and the file name\nand extension could be anything you want.\n\n- Once the command is run and you don't see any errors, the patch file is\ngenerated.\n\n- Now checkout `master` branch; run `git checkout master`.\n\n- Delete the branch `add-page-navigation` from local repo; run `git branch\n-D add-page-navigation`. Remember, we already have changes of this branch in\na created patch file.\n\n- Now create a new branch with the same name (while `master` is checked\nout); run `git checkout -b add-page-navigation`.\n\n- At this point, this is a fresh branch and doesn't have any of your\nchanges.\n\n- Finally, apply your changes from the patch file; `git apply\n~/add_page_navigation.patch`.\n\n- Here, all of your changes are applied in a branch and they will appear as\nuncommitted, as if all your modification where done, but none of the\nmodifications were actually committed in the branch.\n\n- Now you can go ahead and commit individual files or files grouped by area\nof impact in the order you want with concise commit messages.\n\n\nAs with previous situations, we basically modified the whole branch, so it\nis time to force push!\n\n\n## Git commit history: Conclusion\n\n\nWhile we have covered most common and basic situations that arise in a\nday-to-day workflow with Git, rewriting Git history is a vast topic and as\nyou get familiar with above tips, you can learn more advanced concepts\naround the subject in the [Git Official\nDocumentation](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History).\nHappy git'ing!\n\n\nPhoto by [pan\nxiaozhen](https://unsplash.com/photos/pj-BrFZ9eAA?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)\non\n[Unsplash](https://unsplash.com/search/photos/clean?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)\n\n{: .note}\n\n> \n\n\n\u003Cbr>\u003Cbr>\n\n*監修：知念 梨果 [@rikachinen](https://gitlab.com/rikachinen)* \u003Cbr>\n\n*（GitLab合同会社 カスタマーサクセス本部 カスタマーサクセスエンジニア）*\n",[832,682],{"slug":1112,"featured":6,"template":684},"keeping-git-commit-history-clean","content:ja-jp:blog:keeping-git-commit-history-clean.yml","Keeping Git Commit History Clean","ja-jp/blog/keeping-git-commit-history-clean.yml","ja-jp/blog/keeping-git-commit-history-clean",3,[691,710,730,749,769,795,819,839,859],1758662371096]