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
480
20190705_CloudNativeKansai__4.pdf
nezumisannn
July 05, 2019
Tweet
Share
More Decks by nezumisannn
See All by nezumisannn
20241204_ビヨンド勉強会_44_AWS_Service_Catalogを利用したIaCのテンプレート化とTerraformによるデプロイ.pdf
nezumisannn
0
140
20240828_ビヨンド勉強会_42_EKS_on_FargateでWebサービスを公開するために覚えておきたいこと.pdf
nezumisannn
0
73
20240530_ビヨンド勉強会#41_ビヨンドのエンジニア新卒研修における取り組み
nezumisannn
0
89
20230511_AWSにおけるコンテナサービスの選択とIaC実装例.pdf
nezumisannn
0
1.1k
リーダーになって1年経過して_取り組んできたことと大事にしている考え方_の裏側_.pdf
nezumisannn
0
59
20211118_GKEにおける高負荷時のPodとWorker_Nodeの挙動について.pdf
nezumisannn
0
120
20211014_Alibaba_Cloud_Container_Service_for_KubernetesにおけるServerless_Kubernetesの概要とManaged_Kubernetesとの違い.pdf
nezumisannn
0
64
20211008_ApsaraDB_for_PolarDBとAWS_Auroraの機能比較.pdf
nezumisannn
1
110
20210122_AlibabaCloudパートナーサミット_Terraform_Cloudを活用するマルチクラウドオートメーション.pdf
nezumisannn
0
50
Other Decks in Technology
See All in Technology
管理者しか知らないOutlookの裏側のAIを覗く#AzureTravelers
hirotomotaguchi
2
240
技術的負債解消の取り組みと専門チームのお話 #技術的負債_Findy
bengo4com
1
1.2k
現場の種を事業の芽にする - エンジニア主導のイノベーションを事業戦略に装着する方法 -
kzkmaeda
2
1.5k
Kubernetes x k6 で負荷試験基盤を開発して 負荷試験を民主化した話 / Kubernetes x k6
sansan_randd
2
730
エンジニアのためのドキュメント力基礎講座〜構造化思考から始めよう〜(2025/02/15jbug広島#15発表資料)
yasuoyasuo
15
5.5k
Ask! NIKKEI RAG検索技術の深層
hotchpotch
13
2.8k
SCSAから学ぶセキュリティ管理
masakamayama
0
140
[2025-02-07]生成AIで変える問い合わせの未来 〜チームグローバル化の香りを添えて〜
tosite
1
290
株式会社EventHub・エンジニア採用資料
eventhub
0
4.2k
室長と気ままに学ぶマイクロソフトのビジネスアプリケーションとビジネスプロセス
ryoheig0405
0
320
Larkご案内資料
customercloud
PRO
0
600
ビジネスと現場活動をつなぐソフトウェアエンジニアリング~とあるスタートアッププロダクトの成長記録より~
mizunori
0
210
Featured
See All Featured
Designing for humans not robots
tammielis
250
25k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
132
33k
The Power of CSS Pseudo Elements
geoffreycrofte
75
5.5k
Unsuck your backbone
ammeep
669
57k
Typedesign – Prime Four
hannesfritz
40
2.5k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
BBQ
matthewcrist
86
9.5k
Faster Mobile Websites
deanohume
306
31k
A Philosophy of Restraint
colly
203
16k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
How to train your dragon (web standard)
notwaldorf
90
5.8k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.6k
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