JenkinsからCFnのスタックを作成してみた。

## はじめに
Jenkinsを利用してCFnのテンプレートのスタックを実行するジョブを作成してみました。
使用するCFnのテンプレートは[前回記事]
(https://qiita.com/President_Taka/items/8384110f259b31abdc1b)で作成した3つのテンプレートです。

![スクリーンショット 2020-03-15 16.53.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/e8690ca1-fdb1-e81e-0f8a-14732f216231.png)


##Jenkinsサーバー作成
AWSのEC2を利用してJenkinsサーバーを作成します。
EC2その他の環境は以下のとおりです。

 - インスタンスタイプ : t2.medium
 - サブネット : パブリックサブネット
 - 自動割り当てパブリックIP : 有効
 - セキュリティグループ : SSH(22) カスタムTCP(8080)
    ※Jenkinsサーバーとの接続に8080番ポートが必要


#### SSH接続
作成したEC2にSSH接続を行います。

```
$ ssh -i ~/.ssh/aws-test.pem ec2-user@[パブリックIP]
```

#### javaのインストール
Jenkinsを動作させるためにはJavaが必要となりますので、Javaをインストールします。

```
$ sudo yum install -y java-1.8.0-openjdk
$ java -version
openjdk version "1.8.0_242"
OpenJDK Runtime Environment (build 1.8.0_242-b08)
OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)
```

#### Jenkinsをyumリポジトリに追加
Jenkinsのインストールを行うために、Jenkinsのyumリポジトリを追加します。今回JenkinsはLTS版を使用します。

```
$ cd /etc/yum.repos.d     #yum.repos.dフォルダーへ移動
$ sudo curl -O http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo     #curlコマンドでyumリポジトリを取得
$ sudo rpm --import http://pkg.jenkins.io/redhat-stable/jenkins.io.key    #RPMパッケージの公開鍵をrpmコマンドでインポート
```

#### Jenkinsのインストール
```
$ sudo yum install jenkins -y
$ rpm -qa | grep jenkins    #インストール確認
jenkins-2.204.5-1.1.noarch
```

#### gitのインストール
GitリポジトリからCFnのテンプレートコードを参照するためgitが必要になります。

```
$ sudo yum install git -y
$ git --version
git version 2.23.1
```

#### Jenkinsの起動
```
$ sudo systemctl start jenkins
```
ブラウザから`http://パブリックIPアドレス:8080`でアクセスするとJenkinsのトップページが表示されます。
<img width="1006" alt="スクリーンショット 2020-03-03 20.15.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/317ee45f-fd78-9944-0bae-be11991a6ee0.png">

## Jenkinsサーバー初期設定

トップページはアクセスがロックされていますので、`Administrator password`を入力が必要となります。指示どおり`/var/lib/jenkins/secrets/initialAdminPassword`で確認できるパスワードを入力します。

```
$ sudo cat /var/lib/jenkins/secrets/initialAdminPassword
133d8a2572-------------------
```
次に`Customize Jenkins`画面が表示され、2つのカスタマイズ方法のうち一つを選択します。違いはプラグインを自分で選択するか推奨されるものにするか、になりますので、今回は推奨プラグイン`Install suggested plugins`を選択します。

<img width="1006" alt="スクリーンショット 2020-03-03 20.19.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/6591f7be-ba58-bc84-7194-aed6fc23800e.png">

そうすると次のように自動的にインストールが開始されます。
![スクリーンショット 2020-03-15 11.59.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/42f5baaf-05d5-5238-3897-eb663840cf58.png)

次に、Adminユーザーの設定を行います。メールアドレスは実在しないものでも設定は可能です。

![スクリーンショット 2020-03-15 12.03.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/c7711f74-a555-1b13-c1bd-a045010c80ec.png)

最後に`Save and Finish`をクリックしてセットアップは完了です。

![スクリーンショット 2020-03-15 12.06.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/7987fe3d-0029-e6be-dea7-60b79c710f3a.png)
<img width="1017" alt="スクリーンショット 2020-03-03 20.27.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/2a9617c8-5def-63e9-cf79-3bd4c6d0eb97.png">

`Start using Jenkins`をクリックして利用開始です。
<img width="1431" alt="スクリーンショット 2020-03-03 20.28.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/f9cd2d92-cabc-c003-fa5f-8e04bb4c4b97.png">

## ジョブの作成
CloudFormationのテンプレートを実行させるジョブを作成します。

<img width="1431" alt="スクリーンショット 2020-03-03 20.28.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/01980038-25bc-414c-f45d-ee3e2c28427c.png">

![スクリーンショット 2020-03-15 12.35.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/3681b78f-c033-b399-b195-c6c6590e7d6d.png)

説明欄に実行内容の概要を入力し、ソースコード管理のGitを選択します。GitHubから取得した対象リポジトリのURLを貼り付けて保存します。
![スクリーンショット 2020-03-15 12.51.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/50262f9d-694b-7fa0-bf6c-a881f3e057d8.png)

作成したジョブのビルドを実行し、下図の②のように青が表示されたらgitcloneのビルドが成功です。

![スクリーンショット 2020-03-15 13.04.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/d8771bff-8dc7-884a-39b6-a4dc400f15ae.png)

ターミナルで確認すると、workspaceのディレクトリが新たに追加されているのがわかります。その中には作成したジョブ名のディレクトリが入っており、中身はGitHubからcloneしたソースコードが格納されています。

```
$ ls /var/lib/jenkins/workspace
CloudFormation
```

続いて、ジョブの実行で実際にCFnのスタックが作成されるように設定します。現状、サーバーにログインしているのがec2-userでジョブを実行しているのはjenkinsユーザーとなるため、次の処理の実行が必要になります。

##### ①AWS CLIにAWSのアカウント情報を紐付ける
AWSのマネジメントコンソール画面でIAMユーザーの認証情報(アクセスキーID、シークレットアクセスキー)を確認し以下のように入力します。

```
$ aws configure
AWS Access Key ID: AKI-------------
AWS Secret Access Key: iiYg-------------
Default region name: ap-northeast-1
Default output format: json

$ aws s3 ls    #上記のキーが正しければS3のバケット情報が確認できます。
```

#####② 実行権限を付与し、Jenkinsを再起動
```
$ sudo visudo
Defaults visiblepwの下に以下の2行を追加

root    ALL=(ALL:ALL) ALL
jenkins ALL=(ALL) NOPASSWD:ALL

$ sudo systemctl restart jenkins  #jenkinsの再起動 jenkins画面が再起動される
```

#### ビルドの設定
ジョブの設定画面からビルドの設定を行います。
![スクリーンショット 2020-03-15 13.44.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/5ed0cfe8-e705-5f07-7d44-bff8eac6aeed.png)

シェルスクリプトに実行内容を入力して編集内容を保存します。

![スクリーンショット 2020-03-15 14.16.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/7732f658-e507-ece5-fa02-bdf6f0a6bc2f.png)

実際に入力した内容は以下になります。Application_LayerのスタックにはParameterを設定していたので各値の指定が必要になります。今回シェルスクリプト内に直に入力しましたが、もっとスマートな方法があると思います。Pluginとかいれたら変わるのかな？また勉強しておきます。

```
sudo -u ec2-user aws cloudformation create-stack --stack-name Network-Layer --template-body file://$WORKSPACE/Network_Layer.yml
sudo -u ec2-user aws cloudformation wait stack-create-complete --stack-name Network-Layer

sudo -u ec2-user aws cloudformation create-stack --stack-name Security-Layer --template-body file://$WORKSPACE/Network_Layer.yml
sudo -u ec2-user aws cloudformation wait stack-create-complete --stack-name Security-Layer

sudo -u ec2-user aws cloudformation create-stack --stack-name Application-Layer --template-body file://$WORKSPACE/Network_Layer.yml --parameters ParameterKey=KeyPair,ParameterValue="aws-test"  ParameterKey=DBInstanceIdentifier,ParameterValue="sample-rds" ParameterKey=DBSubnetGroupDescription,ParameterValue="sample-rds-sg" ParameterKey=S3BucketName,ParameterValue="samples3bucketfromjenkins"
sudo -u ec2-user aws cloudformation wait stack-create-complete --stack-name Application-Layer
```
## ビルドの実行
![スクリーンショット 2020-03-15 17.13.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/4c649920-7329-5988-a9d8-aab3d431d7c2.png)

ビルドの実行結果が青になったことを確認して、AWSのマネジメントコンソールで実際にスタックが作成されたかを確認します。途中に何度か赤で失敗したのは、Parameterの値の設定がうまくできておらず、次のように怒られていました。

```
An error occurred (ValidationError) when calling the CreateStack operation: Parameters: [KeyPair, S3BucketName, DBSubnetGroupDescription, DBInstanceIdentifier] do not exist in the template
Build step 'Execute shell' marked build as failure
Finished: FAILURE
```
最後は、なんとか無事に作成できました。

![スクリーンショット 2020-03-15 18.16.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/fe058d50-d142-931a-1816-17c11eba8990.png)




## 参考記事
https://wiki.jenkins.io/display/JENKINS/Installing+Jenkins+on+Red+Hat+distributions

https://www.magata.net/memo/index.php?AWS%A4%CE%A5%B5%A1%BC%A5%D3%A5%B9%A4%F2Jenkins%A4%C7%A5%C7%A5%D7%A5%ED%A5%A4%A4%B9%A4%EB