3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Jenkins pipelineでAWS CloudFormationを利用しVPCを構築する

Last updated at Posted at 2019-08-29

はじめに

JenkinsからAWS CloudFormationを利用しVPCを構築するサンプルです。JenkinsからAWS CLIを利用するやり方はたくさんあります。これはあくまでひとつの例です。

検証環境

OS: CentOS7
Jenkinsのバージョン: 2.1以降
必要なプラグイン: Jenkinsの初期設定画面でインストールされるプラグイン + Pipeline: AWS Steps

Jenkinsの設定

必要なパッケージ

Jenkinsサーバに以下のパッケージがインストールされている必要があります。

  • Git
  • AWS CLI

こちらのAnsible PlaybookでJenkinsを構築することも可能です。

Pipeline: AWS Stepsをインストールする

「Jenkinsの管理」→「プラグインの管理」→「利用可能タブ」から AWS CodePipeline を選択しインストールする(Jenkinsサーバ側ではプラグイン名が「Pipeline: AWS Steps」ではないので注意!)

このプラグインをインストールすると他の依存関係にあるプラグインもインストールされる

スクリーンショット 2019-08-29 20.49.03.png

AWS Credentialsを登録する

  • AWSのIAMのコンソールでEC2とCloudFormationの実行権限を付与したアクセスキーを作成する

  • 「認証情報」→「システム」→「 認証情報の追加」→「種類」から「AWS Credentials」を選択し「Access Key ID」と「Secret Access Key」を入力する

  • IDの部分は入力しない

スクリーンショット 2019-08-29 20.24.29.png

JenkinsへPipelineファイルを登録する

こちらのPipelineファイルを登録していきます。

create-stack/Jenkinsfile
# !groovy

pipeline {

  agent any

  parameters {
    string(
      name: 'AWS_CREDENTIALS_ID',
      defaultValue: '',
      description: 'AWS credentials id, stored in Jenkins credentials'
    )
    string(
      name: 'EXTRA_ARGS',
      defaultValue: '',
      description: 'aws cloudformation create-stack command extra arguments'
    )
    string(
      name: 'GIT_BRANCHES_CFN',
      defaultValue: '*/master',
      description: "Git branch or tag name or commit id to retrieve of GIT_URL of CloudFormation template file"
    )
    string(
      name: 'GIT_URL',
      defaultValue: '',
      description: "GitHub URL to retrieve CloudFormation template"
    )
    string(
      name: 'REGION',
      defaultValue: '',
      description: 'AWS CLI region name'
    )
    string(
      name: 'STACK_NAME',
      defaultValue: '',
      description: 'CloudFormation stack name'
    )
    string(
      name: 'TEMPLATE_FILE_PATH',
      defaultValue: '',
      description: 'CloudFormation template file path'
    )
    string(
      name: 'WORKING_DIR',
      defaultValue: 'cfn',
      description: 'Job working directory'
    )
  }

  stages {
    stage('Initialize wokring directory') {
      steps {
        dir ("${params.WORKING_DIR}") {
          cleanWs()
        }
      }
    }

    stage('Retrieve CloudFormation template file from Github') {
      steps {
        checkout(
          [
            $class: 'GitSCM',
            branches: [
              [
                name: "${params.GIT_BRANCHES_CFN}"
              ]
            ],
            extensions: [
              [
                $class: 'RelativeTargetDirectory',
                relativeTargetDir: "${params.WORKING_DIR}"
              ]
            ],
            doGenerateSubmoduleConfigurations: false,
            submoduleCfg: [],
            userRemoteConfigs: [
              [
                url: "${params.GIT_URL}"
              ]
            ]
          ]
        )
      }
    }

    stage('Create Stack') {
      steps {
        withAWS(credentials:"${params.AWS_CREDENTIALS_ID}", region:"${params.REGION}") {
          dir ("${params.WORKING_DIR}") {
             // Create Stack
             sh "aws cloudformation create-stack \
                --stack-name ${params.STACK_NAME} \
                --template-body file://${params.TEMPLATE_FILE_PATH} \
                ${params.EXTRA_ARGS}"
  
             // Wait until Stack is created completely
             sh "aws cloudformation wait stack-create-complete \
                --stack-name ${params.STACK_NAME}" 
  
             // Print CloudFormation create command resutls
             sh "aws cloudformation describe-stacks \
                --stack-name ${params.STACK_NAME}"
          }
        }
      }
    }
  }
}
  • 「新規ジョブ作成」→パイプライン名を入力して「パイプライン」をクリック
スクリーンショット 2019-08-29 21.20.39.png
  • パイプラインで以下を設定

リポジトリURL

https://github.com/jenkinsfiles-aws/cloudformation.git

Script Path

create-stack/Jenkinsfile

スクリーンショット 2019-08-29 21.17.47.png

Jobを実行する

作成したJobを一回空実行します。一度実行するとパラメータが指定できる様になります。

スクリーンショット 2019-08-29 21.25.34.png

パラメータ設定例です。

AWS_CREDENTIALS_IDはJenkinsで発行される一意のIDです。

利用したCloudFormationテンプレートはこちらです。

centos7-hvm.yaml
AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  InstanceType:
    Description: EC2 instance type
    Type: String
    Default: t2.micro
    ConstraintDescription: must be a valid EC2 instance type.
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instances
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: must be the name of an existing EC2 KeyPair.

Mappings:
  StackConfigs:
    VPC:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
    PublicSubnet:
      AvailabilityZone: "ap-northeast-1a"
      CidrBlock: 10.0.1.0/24
      Name: "10.0.1.0 - ap-northeast-1a"

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !FindInMap [StackConfigs, VPC, CidrBlock]
      EnableDnsSupport: !FindInMap [StackConfigs, VPC, EnableDnsSupport]
      EnableDnsHostnames: !FindInMap [StackConfigs, VPC, EnableDnsHostnames]
      Tags:
      - Key: Name
        Value: !Ref AWS::StackName

  GatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId:
        Ref: VPC
      InternetGatewayId:
        Ref: InternetGateway

  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !FindInMap [StackConfigs, PublicSubnet, AvailabilityZone]
      CidrBlock: !FindInMap [StackConfigs, PublicSubnet, CidrBlock]
      MapPublicIpOnLaunch: 'true'
      VpcId:
        Ref: VPC
      Tags:
      - Key: Name
        Value: !FindInMap [StackConfigs, PublicSubnet, Name]

  centos7:
    Type: AWS::EC2::Instance
    DependsOn: InternetGateway
    Properties:
      BlockDeviceMappings:
        - DeviceName: /dev/sda1
          Ebs:
            DeleteOnTermination: true
            VolumeType: gp2
      ImageId: ami-045f38c93733dd48d
      InstanceType: !Ref 'InstanceType'
      KeyName: !Ref 'KeyName'
      SecurityGroupIds:
        - !Ref sshSG
        - !Ref httpSG
      SubnetId:
        Ref: PublicSubnet
      Tags:
      - Key: Name
        Value: !Ref AWS::StackName
      - Key: ansible_inventory_group_name
        Value: centos7
      - Key: ansible_user
        Value: centos
      - Key: ansible_port
        Value: 22

  sshSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: ssh
      GroupDescription: SSH access rule
      SecurityGroupIngress:
      - CidrIp: 0.0.0.0/0
        FromPort: 22
        IpProtocol: tcp
        ToPort: 22
      VpcId:
        Ref: VPC

  httpSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: http
      GroupDescription: http access rule
      SecurityGroupIngress:
      - CidrIp: 0.0.0.0/0
        FromPort: 80
        IpProtocol: tcp
        ToPort: 80
      VpcId:
        Ref: VPC

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
      - Key: Name
        Value: InternetGateway

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:
        Ref: VPC
      Tags:
      - Key: Name
        Value: public

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

  PublicSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId:
        Ref: PublicSubnet
      RouteTableId:
        Ref: PublicRouteTable

Outputs:
  VpcId:
    Value: !Ref VPC

Jobを実行するとスタックが作成されます。

スクリーンショット 2019-08-29 21.30.08.png
3
4
3

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
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?