0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

技術検証:ローカルで作成したGoアプリケーションを、CloudFormationテンプレートを使用してECRからECSへ自動デプロイ

Last updated at Posted at 2025-01-21

はじめに

この記事では、ローカルで作成したGoアプリケーションをCloudFormationを用いてインフラをコード化し、ECSがECRからDockerイメージを自動的にプルして本番環境にデプロイする手順を紹介します。

この記事は、過去の技術検証内容を組み合わせた実践的な応用例です。

自分用の備忘録も兼ねて、手順や実施内容を詳しくまとめていきます。少しでも参考になれば幸いです。

補足:過去記事の組み合わせによる検証

※注意点
本記事では、以下の記事で取り上げた技術検証を組み合わせて進めています。

1. Go言語用のDockerfileをシェルスクリプトで一括作成する方法👇

2. Dockerfileをローカルで実行し、ブラウザから『Hello, World!』を表示する方法👇

3. DockerイメージをAWS CLIを使ってECRにプッシュする方法👇

CloudFormationテンプレートの準備

以下は、今回使用したCloudFormationテンプレートです。このテンプレートには、ECSクラスター、タスク定義、IAMロールなど、必要なリソース設定が含まれています。

注意点として、デプロイするアプリケーションは「ポート1323」で動作するため、ContainerPort を正しく指定する必要があります。

test.yaml
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  # VPCの作成
  VPC:
    Type: "AWS::EC2::VPC"
    Properties:
      CidrBlock: "10.0.0.0/16"
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: "Name"
          Value: "honda-vpc"

  # サブネットの作成
  PublicSubnet1:
    Type: "AWS::EC2::Subnet"
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.0.0/20"
      AvailabilityZone: "ap-northeast-1a"
      Tags:
        - Key: "Name"
          Value: "honda-subnet-public1-ap-northeast-1a"

  # インターネットゲートウェイの設定
  InternetGateway:
    Type: "AWS::EC2::InternetGateway"
    Properties:
      Tags:
        - Key: "Name"
          Value: "honda-igw"

  AttachInternetGateway:
    Type: "AWS::EC2::VPCGatewayAttachment"
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC

  # ルートテーブルの設定
  PublicRouteTable:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: "Name"
          Value: "honda-rtb-public"

  PublicRoute:
    Type: "AWS::EC2::Route"
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway

  SubnetRouteTableAssociation:
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  # ECS用セキュリティグループ
  SecurityGroup:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      GroupDescription: "Allow HTTP traffic"
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: "tcp"
          FromPort: 80
          ToPort: 80
          CidrIp: "0.0.0.0/0"
        - IpProtocol: "tcp"
          FromPort: 1323
          ToPort: 1323
          CidrIp: "0.0.0.0/0"

  # ECSクラスターの作成
  ECSCluster:
    Type: "AWS::ECS::Cluster"
    Properties:
      ClusterName: "my-ecs-cluster"

  # ECSタスク定義
  ECSTaskDefinition:
    Type: "AWS::ECS::TaskDefinition"
    Properties:
      Family: "my-app-task"
      RequiresCompatibilities:
        - FARGATE
      NetworkMode: "awsvpc"
      Cpu: "256"
      Memory: "512"
      ExecutionRoleArn: !GetAtt ECSTaskExecutionRole.Arn
      ContainerDefinitions:
        - Name: "my-app-repo"
          Image: "xxx.dkr.ecr.ap-northeast-1.amazonaws.com/xxx"
          PortMappings:
            - ContainerPort: 1323
              HostPort: 1323
              Protocol: "tcp"

  # ECSタスク実行ロール
  ECSTaskExecutionRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service: "ecs-tasks.amazonaws.com"
            Action: "sts:AssumeRole"
      Policies:
        - PolicyName: "ecsTaskExecutionPolicy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: "Allow"
                Action:
                  - "ecr:GetAuthorizationToken"
                  - "ecr:GetDownloadUrlForLayer"
                  - "ecr:BatchGetImage"
                  - "logs:CreateLogStream"
                  - "logs:PutLogEvents"
                  - "s3:GetObject"
                Resource: "*"

  # ECSサービスの作成
  ECSService:
    Type: "AWS::ECS::Service"
    Properties:
      Cluster: !Ref ECSCluster
      TaskDefinition: !Ref ECSTaskDefinition
      DesiredCount: 1
      LaunchType: "FARGATE"
      NetworkConfiguration:
        AwsvpcConfiguration:
          Subnets:
            - !Ref PublicSubnet1
          SecurityGroups:
            - !Ref SecurityGroup
          AssignPublicIp: "ENABLED"

今回は、過去の記事で作成したテンプレートを基に、コンテナとホストのポート設定、およびセキュリティグループ周りの設定を修正しました。

実際にやってみた

上記のCloudFormationテンプレートを使って、ECSクラスターを作成し、タスク定義とサービスを設定しました。

CloudFormationのサービス画面からスタックの作成に進み、作成したyamlファイルをアップロードします。

スクリーンショット 2024-12-08 12.12.25.png

スタック名は任意で設定できます。ここでは私の名前「honda」としています。

スクリーンショット 2024-12-08 12.12.47.png

画面遷移後のスタックオプション設定については、個々の設定に依存するため、私は設定せずに進めていきます。

ただ、スタックの中でIAMを使う場合は、以下のように確認が求められますでの、✅を入れて進んでください。

スクリーンショット 2024-11-13 20.19.18.png

最後に確認を行い、問題がなければ最下部までスクロールし、「送信」をクリックして完了です。

スクリーンショット 2024-12-08 12.13.30.png

スタックを実行後、イベントタブで成功したことが確認できました(しばらく時間がかかります)。

スクリーンショット 2024-12-08 12.15.29.png

デプロイ後の動作確認

デプロイが完了したら、タスクが正常に実行されていることを確認します。ここでは、ECRのイメージコンテナからプルされていることも合わせて確認しました。

スクリーンショット 2024-12-08 12.16.37.png

ECSページの「クラスター」→「タスク」タブから、実行中のタスクを選択し、タスクのパブリックIPを確認します。

http://52.192.243.113:1323/

ここで、タスクが使用しているパブリックIP(例:52.192.243.113)を確認したら、ブラウザでアクセスしてみます。

Screenshot 2025-01-21 at 14.35.02.png

想定通り、Goアプリが正常に動作し、Hello, World! と表示されることを確認できました!

技術検証そのものはスムーズに進められましたが、複雑な内容を1つの記事として整理するのは、かなり大変でした!笑

まとめ

ここまでお読みいただき、ありがとうございました。今回の記事は、過去の複雑な技術検証を組み合わせた内容となりましたが、無事にまとめることができて本当によかったです。

また、GitHub Actionsの設定も問題なく完了しましたので、時間があるときにその内容も別の記事としてまとめていきたいと思っています。

この記事がどなたかの技術的な参考になれば幸いです!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?