Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
20190705_CloudNativeKansai__4.pdf
Search
nezumisannn
July 05, 2019
Technology
3
500
20190705_CloudNativeKansai__4.pdf
nezumisannn
July 05, 2019
Tweet
Share
More Decks by nezumisannn
See All by nezumisannn
20250930_Conohaウェビナー_生成AI_Terraform_ConoHa_VPSサーバー_セットアップ入門編
nezumisannn
1
13
20250723_Conohaウェビナー_高騰する海外クラウド費用を劇的カット_サーバーコスト最適化のポイント解説と成功事例のご紹介.pdf
nezumisannn
0
27
20241204_ビヨンド勉強会_44_AWS_Service_Catalogを利用したIaCのテンプレート化とTerraformによるデプロイ.pdf
nezumisannn
0
280
20240828_ビヨンド勉強会_42_EKS_on_FargateでWebサービスを公開するために覚えておきたいこと.pdf
nezumisannn
0
88
20240530_ビヨンド勉強会#41_ビヨンドのエンジニア新卒研修における取り組み
nezumisannn
0
120
20230511_AWSにおけるコンテナサービスの選択とIaC実装例.pdf
nezumisannn
0
1.3k
リーダーになって1年経過して_取り組んできたことと大事にしている考え方_の裏側_.pdf
nezumisannn
0
66
20211118_GKEにおける高負荷時のPodとWorker_Nodeの挙動について.pdf
nezumisannn
0
150
20211014_Alibaba_Cloud_Container_Service_for_KubernetesにおけるServerless_Kubernetesの概要とManaged_Kubernetesとの違い.pdf
nezumisannn
0
84
Other Decks in Technology
See All in Technology
「使い方教えて」「事例教えて」じゃもう遅い! Microsoft 365 Copilot を触り倒そう!
taichinakamura
0
420
incident_commander_demaecan__1_.pdf
demaecan
0
160
ビズリーチ求職者検索におけるPLMとLLMの活用 / Search Engineering MEET UP_2-1
visional_engineering_and_design
1
140
【Kaigi on Rails 事後勉強会LT】MeはどうしてGirlsに? 私とRubyを繋いだRail(s)
joyfrommasara
0
270
20251010_HCCJP_AdaptiveCloudUpdates
sdosamut
0
140
「れきちず」のこれまでとこれから - 誰にでもわかりやすい歴史地図を目指して / FOSS4G 2025 Japan
hjmkth
1
320
能登半島災害現場エンジニアクロストーク 【JAWS FESTA 2025 in 金沢】
ditccsugii
0
890
Digitization部 紹介資料
sansan33
PRO
1
5.6k
Bill One 開発エンジニア 紹介資料
sansan33
PRO
4
14k
Dylib Hijacking on macOS: Dead or Alive?
patrickwardle
0
230
Node.js 2025: What's new and what's next
ruyadorno
0
400
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
930
Featured
See All Featured
Raft: Consensus for Rubyists
vanstee
140
7.1k
The World Runs on Bad Software
bkeepers
PRO
72
11k
A Modern Web Designer's Workflow
chriscoyier
697
190k
Mobile First: as difficult as doing things right
swwweet
225
10k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
115
20k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
31
2.7k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.2k
Scaling GitHub
holman
463
140k
jQuery: Nuts, Bolts and Bling
dougneiner
65
7.9k
Fireside Chat
paigeccino
40
3.7k
Reflections from 52 weeks, 52 projects
jeffersonlam
353
21k
Transcript
Packer/Ansible/Terraformを使った AWS Fargateへのデプロイ Cloud Native Kansai #4 株式会社ビヨンド 寺岡 佑樹
はじめに ・本資料は後日公開します ・資料中に記載されているコードGitHubに公開しています https://github.com/nezumisannn/aws-fargate-pipeline-example ・資料公開したらTwitterでハッシュタグ付きでつぶやきます
Agenda ・自己紹介 ・利用するツール/サービスの紹介 ・このスライドで作れる環境の構成図 ・環境の作り方 ・まとめ
自己紹介 resource “my_profile” “nezumisannn” { name = “Yuki.Teraoka” nickname =
“ねずみさん家。” company = “beyond” job = “Site Reliability Engineer” twitter = “@yktr_sre” skills = [“terraform”,”packer”] }
利用するツール
利用するツール Terraform Packer Ansible
利用するサービス
利用するサービス Elastic Container Registry Fargate Code Build Code Deploy Code
Pipeline
構成図
構成図 Pipeline git push im age build deploy source
出来ること ・fargateへのデプロイの自動化(CI/CD) ・GitへのPushをトリガーに、Pull ⇒ Build ⇒ Deployまで処理できる
デモ
今回のゴール ・CodePipelineの一連の処理を実行できる ・実行した結果、ブラウザの画面に「hello world」と表示されるようにする
実装
コンテナのビルド Pipeline git push im age build deploy source
コンテナのビルド ・CodeBuildを利用 ・プロジェクトはTerraformで作成 ・ソースプロバイダにGitHubを設定 ・buildspec.ymlにビルド時の処理を記述 ・CodeBuildのビルド用コンテナにPacker/Ansibleをインストール ・Packerのbuildersにdockerを指定 ・provisionersでAnsibleを実行してpost-processorsでECRにpush
resource "aws_codebuild_project" "codebuild" { name = "example" service_role = "${aws_iam_role.role-codebuild.arn}"
source { type = "GITHUB" location = "https://github.com/nezumisannn/aws-pipeline-example.git" git_clone_depth = 1 } environment { compute_type = "BUILD_GENERAL1_SMALL" image = "aws/codebuild/standard:1.0-1.8.0" image_pull_credentials_type = "CODEBUILD" privileged_mode = true type = "LINUX_CONTAINER" } artifacts { type = "NO_ARTIFACTS" } }
--- version: 0.2 phases: pre_build: commands: - curl -qL -o
packer.zip https://releases.hashicorp.com/packer/0.12.3/packer_0.12.3_linux_amd64.zip && unzip packer.zip - curl -qL -o jq https://stedolan.github.io/jq/download/linux64/jq && chmod +x ./jq - apt-get install software-properties-common -y - apt-add-repository ppa:ansible/ansible -y - apt-get install ansible -y - apt-get install openssh-client -y - apt-get update - ansible --version - ./packer validate ./packer-build/build.json
build: commands: - echo "Setting AWS credentials" - curl -qL
-o aws_credentials.json http://169.254.170.2/$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI > aws_credentials.json - aws configure set region ap-northeast-1 - aws configure set aws_access_key_id `./jq -r '.AccessKeyId' aws_credentials.json` - aws configure set aws_secret_access_key `./jq -r '.SecretAccessKey' aws_credentials.json` - aws configure set aws_session_token `./jq -r '.Token' aws_credentials.json` - echo "Build Packer" - ./packer build -debug ./packer-build/build.json - printf '{"Version":"1.0","ImageURI":"%s"}' XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/example-repo:latest > imageDetail.json artifacts: files: imageDetail.json
{ "variables": { "ecr_registry_url": "XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com", "ecr_repository": "XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/example-repo" }, "builders": [
{ "type": "docker", "image": "alpine:latest", "commit": true, "run_command": [ "-d", "-t", "-i", "{{.Image}}", "/bin/sh" ], "changes": [ "VOLUME /data", "WORKDIR /data", "EXPOSE 80 443", "ENTRYPOINT [\"docker-entrypoint.sh\"]" ] } ],
"provisioners": [ { "type": "ansible", "user": "root", "playbook_file": "./ansible/operation.yml" }
], "post-processors": [ [ { "type": "docker-tag", "repository": "{{user `ecr_repository`}}", "tag": "latest" }, { "type": "docker-push", "ecr_login": true, "login_server": "{{user `ecr_registry_url`}}" } ] ] }
- name: Starting building... hosts: all tasks: - name: Installing
nginx package: name: nginx state: present - name: Putting nginx config file copy: src: config/nginx/default.conf dest: /etc/nginx/conf.d/default.conf mode: 0755 owner: root group: root - name: Putting index.html copy: src: ../application/index.html dest: /usr/share/nginx/html/index.html mode: 0755 owner: root group: root
- name: Putting entrypoints copy: src: config/{{ item }} dest:
/usr/local/bin/{{ item }} mode: 0755 owner: root group: root with_items: - docker-entrypoint.sh #!/bin/sh exec nginx -g 'pid /tmp/nginx.pid; daemon off;'
Fargateへのデプロイ Pipeline git push im age build deploy source
Fargateへのデプロイ ・CodeDeployを利用 ・Fargateとデプロイに必要なALB/ターゲットグループはTerraformで作成 ・ローリングアップデートではなくBlue/Greenデプロイを行う
Blue/Greenデプロイ Target 1 Target 2
resource "aws_alb" "alb" { name = "example" security_groups = ["${aws_security_group.alb-sg.id}"]
subnets = "${var.subnets}" }
## Target Group resource "aws_alb_target_group" "target_group1" { name = "example-tg1"
port = 80 protocol = "HTTP" target_type = "ip" vpc_id = "${var.vpc_id}" } resource "aws_alb_target_group" "target_group2" { name = "example-tg2" port = 80 protocol = "HTTP" target_type = "ip" vpc_id = "${var.vpc_id}" }
## ECS Service resource "aws_ecs_service" "ecs-service" { name = "service-nginx"
cluster = "${aws_ecs_cluster.ecs-cluster.id}" task_definition = "${aws_ecs_task_definition.ecs-task.arn}" launch_type = "FARGATE" desired_count = 3 health_check_grace_period_seconds = 0 deployment_controller { type = "CODE_DEPLOY" } load_balancer { container_name = "nginx-web" container_port = "80" target_group_arn = "${aws_alb_target_group.target_group1.arn}" } network_configuration { assign_public_ip = true security_groups = [ "${aws_security_group.fargate-sg.id}" ] subnets = "${var.subnets}" } }
## CodeDeploy APP resource "aws_codedeploy_app" "codedeploy-app" { compute_platform = "ECS"
name = "AppECS-cluster-example-service-nginx" }
resource "aws_codedeploy_deployment_group" "codedeploy-group" { app_name = "${aws_codedeploy_app.codedeploy-app.name}" service_role_arn = "${aws_iam_role.role-codedeploy.arn}"
deployment_group_name = "DgpECS-cluster-example-service-nginx" deployment_config_name = "CodeDeployDefault.OneAtATime" ecs_service { cluster_name = "${aws_ecs_cluster.ecs-cluster.name}" service_name = "${aws_ecs_service.ecs-service.name}" } blue_green_deployment_config { deployment_ready_option { action_on_timeout = "CONTINUE_DEPLOYMENT" wait_time_in_minutes = 0 } terminate_blue_instances_on_deployment_success { action = "TERMINATE" termination_wait_time_in_minutes = 0 } }
load_balancer_info { target_group_pair_info { prod_traffic_route { listener_arns = [ "${aws_alb_listener.listener.arn}"
] } target_group { name = "${aws_alb_target_group.target_group1.arn}" } target_group { name = "${aws_alb_target_group.target_group2.arn}" } } }
resource "aws_codedeploy_deployment_group" "codedeploy-group" { app_name = "${aws_codedeploy_app.codedeploy-app.name}" service_role_arn = "${aws_iam_role.role-codedeploy.arn}"
deployment_group_name = "DgpECS-cluster-example-service-nginx" deployment_config_name = "CodeDeployDefault.OneAtATime" ecs_service { cluster_name = "${aws_ecs_cluster.ecs-cluster.name}" service_name = "${aws_ecs_service.ecs-service.name}" } blue_green_deployment_config { deployment_ready_option { action_on_timeout = "CONTINUE_DEPLOYMENT" wait_time_in_minutes = 0 } terminate_blue_instances_on_deployment_success { action = "TERMINATE" termination_wait_time_in_minutes = 0 } }
Pipelineの作成 Pipeline git push im age build deploy source
Pipelineの作成 ・パイプラインのステージをそれぞれ追加する ・ソースステージ:Github ・ビルドステージ:CodeBuild ・デプロイステージ:ECS(ブルー/グリーン) ・git pushをするとPull ⇒ Build ⇒
Deployが自動実行されるようになる ・パイプラインの設定はTerraformで行う
resource "aws_codepipeline" "codepipeline" { name = "example-pipeline" stage { name
= "Source" action { category = "Source" configuration = { "Branch" = "master" "Owner" = "XXXXXXXXXX" "PollForSourceChanges" = "false" "Repo" = "XXXXXXXXXX" } name = "Source" output_artifacts = [ "SourceArtifact", ] owner = "ThirdParty" provider = "GitHub" run_order = 1 version = "1" } }
stage { name = "Build" action { category = "Build"
configuration = { "ProjectName" = "${aws_codebuild_project.codebuild.name}" } input_artifacts = [ "SourceArtifact", ] name = "Build" output_artifacts = [ "BuildArtifact", ] owner = "AWS" provider = "CodeBuild" run_order = 1 version = "1" } }
stage { name = "Deploy" action { category = "Deploy"
configuration = { "AppSpecTemplateArtifact" = "SourceArtifact" "ApplicationName" = "${aws_codedeploy_app.codedeploy-app.name}" "DeploymentGroupName" = "${aws_codedeploy_deployment_group.codedeploy-group.name}" "Image1ArtifactName" = "BuildArtifact" "Image1ContainerName" = "IMAGE1_NAME" "TaskDefinitionTemplateArtifact" = "SourceArtifact" } input_artifacts = [ "BuildArtifact", "SourceArtifact", ] name = "Deploy" owner = "AWS" provider = "CodeDeployToECS" run_order = 1 version = "1" } } }
## Webhook Secret locals { webhook_secret = "XXXXXXXXXXXXXXXXXXXXXX" } ##
CodePipeline Webhook resource "aws_codepipeline_webhook" "codepipeline-webhook" { name = "webhook-github" authentication = "GITHUB_HMAC" target_action = "Source" target_pipeline = "${aws_codepipeline.codepipeline.name}" authentication_configuration { secret_token = "${local.webhook_secret}" } filter { json_path = "$.ref" match_equals = "refs/heads/{Branch}" } }
## Github Webhook resource "github_repository_webhook" "repository-webhook" { repository = "aws-pipeline-example"
name = "codepipeline-webhook" configuration { url = "${aws_codepipeline_webhook.codepipeline-webhook.url}" content_type = "json" insecure_ssl = true secret = "${local.webhook_secret}" } events = ["push"] }
まとめ ・FargateへのデプロイはAWSのデプロイ3兄弟を利用しよう ・OSSと組み合わせるとさらに便利に! ・デプロイ基盤を整えておくとリリース作業を省力化できる ・皆様のデプロイ基盤構築に役立てれば幸いです
END