GitLab Runner を EC2 インスタンスで立てるときの CloudFormation テンプレ

# 概要
・GitLab をセルフホスティングしている場合、CI・CD 用の GitLab Runner も自前で構築しなければならない人
・プロジェクトごとに GitLab Runner を毎回立てるのがめんどくさくなった人
向けに GitLab Runner を EC2 インスタンスで立てる場合の CloudFormation を用意しました。

# 環境
利用するイメージは AmazonLinux2 用イメージを指定してます。それ以外のイメージを利用するとユーザデータのコマンドが失敗するので適宜変更してください。

# GitLab Runner とは

GitLab のブランチに対して**コミット**や**マージ**を**検知**し、**ビルド**や**静的解析**、**テスト**などの**ジョブを実行&結果**を GitLab/CI・CD から**確認**することができる仕組みです。
GitLab Runner 自体はそれ単体のサービスとして動かすことができるので GitLab 本体がインストールされているサーバでも別サーバにでもどちらからでも利用することができます。
一般的には、色々なプロジェクトのジョブが実行され負荷がかかる可能性があるため、GitLab 本体サーバとは別のサーバで起動させることが多いです。

## EC２ インスタンス作成用 CloudFormation
EC2 インスタンスの CloudFormation です。ユーザデータに GitLab Runner をインストールするコマンドを書いています。

またこの例では、デプロイ先を S3 とした CloudFormation になっております。HTML や CSS、Javascript など静的ファイルのデプロイのみにしか対応してませんので適宜カスタマイズしてください。 

**実行コマンド**
作成の場合 : 
`aws cloudformation create-stack --capabilities CAPABILITY_IAM --template-body file://instance.yml --stack-name gitlabrunner-stack -
-parameters ParameterKey=InstanceType,ParameterValue=t2.micro --region ap-northeast-1 --profile <アカウントプロファイル>`
アップデートの場合 :
`aws cloudformation update-stack --capabilities CAPABILITY_IAM --template-body file://instance.yml --stack-name gitlabrunner-stack -
-parameters ParameterKey=InstanceType,ParameterValue=t2.micro --region ap-northeast-1 --profile <アカウントプロファイル>`
削除の場合 : 
`aws cloudformation delete-stack --stack-name gitlabrunner-stack --region ap-northeast-1 --profile <アカウントプロファイル>`

```yml:instance.yml
---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'gitlub runner'
Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: must be the name of an existing EC2 KeyPair.
    Default: gitlab-runner
  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.micro
    AllowedValues:
    - t1.micro
    - t2.nano
    - t2.micro
    - t2.small
    - t2.medium
    - t2.large
    ConstraintDescription: must be a valid EC2 instance type.

Resources:
  # gitLab runner 用 Ec2 インスタンスの作成
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      SubnetId: <サブネットID>
      ImageId: ami-00d101850e971728d
      IamInstanceProfile:
        Ref: GitLabRunnerIAMInstanceProfile
      SecurityGroupIds:
        - Ref: InstanceSecurityGroup
      InstanceType:
        Ref: InstanceType
      KeyName: 
        Ref: KeyName
      UserData:
        Fn::Base64: |
          #!/bin/bash
          yum -y update
          amazon-linux-extras install python3
          yum install -y docker
          systemctl enable docker
          systemctl start docker
          wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
          chmod +x /usr/local/bin/gitlab-runner
          useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
          /usr/local/bin/gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
          systemctl enable gitlab-runner
          systemctl start gitlab-runner
      Tags: 
        - 
          Key: "Name"
          Value: "インスタンス名"
        - 
          Key: "Step"
          Value: "環境名"
        - 
          Key: "Billing"
          Value: "サービス名"
        - 
          Key: "Author"
          Value: "作成者名"
        - 
          Key: "role"
          Value: "インスタンスの役割"
  # デプロイ先の S3 を許可する role 
  GitLabRunnerIAMRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - ec2.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
  GitLabRunnerIAMPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: S3FullAccessByGitLabRunner
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action: "s3:*"
          Resource: 
              - "arn:aws:s3:::dev-front-バケット名"
              - "arn:aws:s3:::dev-front-バケット名/*"
        - Effect: Allow
          Action: "s3:*"
          Resource: 
              - "arn:aws:s3:::stg-front-バケット名"
              - "arn:aws:s3:::stg-front-バケット名/*"
        - Effect: Allow
          Action: "s3:*"
          Resource: 
              - "arn:aws:s3:::front-バケット名"
              - "arn:aws:s3:::front-バケット名/*"
      Roles:
      - Ref: GitLabRunnerIAMRole
  GitLabRunnerIAMInstanceProfile:
    Type: "AWS::IAM::InstanceProfile"
    Properties:
      Path: "/"
      Roles:
        - Ref: GitLabRunnerIAMRole
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow SSH Client
      VpcId: <VPC-ID>
      SecurityGroupIngress:
      - IpProtocol: TCP
        FromPort: 22
        ToPort: 22
        CidrIp: <接続IP>

Outputs:
  InstanceId:
    Description: InstanceId of the newly created EC2 instance
    Value:
      Ref: EC2Instance
  AZ:
    Description: Availability Zone of the newly created EC2 instance
    Value:
      Fn::GetAtt:
      - EC2Instance
      - AvailabilityZone
  PublicDNS:
    Description: Public DNSName of the newly created EC2 instance
    Value:
      Fn::GetAtt:
      - EC2Instance
      - PublicDnsName
  PublicIP:
    Description: Public IP address of the newly created EC2 instance
    Value:
      Fn::GetAtt:
      - EC2Instance
      - PublicIp
```

開発、ステージ、本場 3つのステージの S3 バケットに対してデプロイできるようにポリシーとロールを作成し EC2 インスタンスにアタッチするようにしております。
適宜 S3 バケット名を変更してあげてください。
# Gitlab Runner の登録

EC2 インスタンス構築が完了したら SSH でサーバ内に接続し GitLabRunner の設定を行います。
## gitlab runner の登録

下記の gitlab-runner をレポジトリに登録するコマンドを実行します。
`sudo /usr/local/bin/gitlab-runner register`
GitLab Runner の設定項目が対話式で聞かれるのでそれに沿って必要項目を入力してください。
入力が完了したら GitLab の管理画面を開いて GitLab Runner が登録しているか確認してください。

作った yml ファイルは GitHub においておきます。
https://github.com/syoimin/serverless-cfn/blob/master/cfn/gitlabrunner-stack/instance.yml