hoge-hogeoのひきこもごも

インフラエンジニアだけど形を持ったインフラを触ったことがない人の徒然

terraformでaws access_key, secret_keyの指定方法

個人的備忘録。本家のドキュメントが英語なので。

IAMの指定の仕方はいくつかある

  1. tfファイルに直書きする
  2. コマンド実行時にオプションで渡す
  3. ファイルに書いておく

1. tfファイルに直書きする

本家のexampleに一番最初に出てくる書き方。

どやーってgithubとかに上げたら後悔するやつ。

$ cat example.tf
provider "aws" {
  access_key = "hogeo"
  secret_key = "hogeo_secret"
  region     = "ap-northeast-1"
}

2. コマンド実行時にオプションで渡す

variables.tfをつくる

$ cat variables.tf
variable "access_key" {}
variable "secret_key" {}
variable "region" {
  default = "ap-northeast-1"
}

example.tfは変数に置き換える。

$ cat example.tf
provider "aws" {
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
  region     = "${var.region}"
}

apply実行時に-varオプションで渡す。

$ terraform apply -var 'access_key=hogeo' -var 'secret_key=hogeo_secret'

オプション忘れても、入力待ちになる

$ terraform apply
var.access_key
  Enter a value:

3. ファイルに書いておく

variables.tf書くのと、example.tfの変数化までは一緒だけど、コマンドラインのオプションで渡すんじゃなくて、ファイルに書くパターン。

terraform.tfvarsというファイル名をカレントにおいて、中にaccess_key, secret_keyを書くことで、IAMをレシピ?に書かずに済む。

$ cat terraform.tfvars
access_key = "hogeo"
secret_key = "hogeo_secret"

terraform.tfvarsというファイル名じゃないと、勝手に読んでくれないので、別のファイル名にしたいときは-var-fileオプションで指定してあげる。

↓はファイル名に「_org」とかつけちゃったのd、-var-fileオプションで指定したとき。

$ terraform destroy -var-file="terraform.tfvars_org"

今日はここまで。全然進まない。。。

本日の一言

勉強してると、部屋の片づけ始めて、カメラのSDカードとか見つかっちゃって、いつの間にか昔の写真見返して時間が過ぎてるよね。

beanstalk触ってる話

概要

さわってみた系の話

検証

.ebextensitonを使ってみる

プロジェクトのソースコードの最上位に.ebextensionsを掘れ?

掘って、ファイル置いてデプロイしたら変わるのだろうか。

f:id:hoge-hogeo:20180928172355p:plain

healthcheckurl.configを置いてみる

f:id:hoge-hogeo:20180928172413p:plain

hello/.ebextensions配下に上記ファイルを置いてzip化する

マネコンからアップロードして、beanstalkにデプロイさせる

エラーが出る

/healthというパスはないからね

つらい

とりあえず1台に適当な静的ファイルを置いてみる

$ sudo sh -c "echo ok >> /var/www/html/hello/public/health"

f:id:hoge-hogeo:20180928172626p:plain

直った。(実は直ってなかった)

とにかく、この使い方でいいということが分かった。

2台目にも手動でhealthファイルを配置した、がエラーが解けない。

f:id:hoge-hogeo:20180928174843p:plain

アプリケーションのバージョンが合わないと。これはもしかしてデプロイ諦めた結果?

もたついてる間にローリングデプロイがAbortされたらしい。

During an aborted deployment, some instances may have deployed the new application version. To ensure all instances are running the same version, re-deploy the appropriate application version.

f:id:hoge-hogeo:20180928172646p:plain

ちなみに、.ebextensions/healthcheckurl.configの内容も切り戻されていたので、現象としては

  • .ebextensions/healthcheckurl.configに/healthがヘルスチェックパスだと指定してアプリをデプロイ
  • 1台目に最新アプリをデプロイしたが、/healthのパスがなかったため、ヘルスチェックに失敗
  • もたもたとhealthファイルを作ったが、操作はAbortされた  →.ebextensions等の変更内容も切り戻された。(ヘルスチェックパスが/healthから/に戻っていた)
  • 最新のアプリが1台目にデプロイ済みのため、その1台目の状態が「低下」になった
  • 少し↑で直ったと思ったのは、デプロイをAbortされて古いままになっていた2台目の状態が「Ok」になっているだけだった

healthの静的ファイルもアプリ内に配置して、再デプロイしてみる。

バージョン情報が分かりにくかったので文字列にしてみる。

f:id:hoge-hogeo:20180928172903p:plain

なんとかなった。実行バージョンも更新された。

f:id:hoge-hogeo:20180928172920p:plain

td-agentを入れてみる

インストール

$ cat hello/.ebextensions/requirement.config
commands:
  command block:
    command: |
      curl -L "https://toolbelt.treasuredata.com/sh/install-amazon1-td-agent3.sh" > td-agent_install.sh
      sh td-agent_install.sh
      td-agent-gem install fluent-plugin-forest

デプロイされたEC2で確認

$ rpm -qa|grep td-a
td-agent-3.2.0-0.el2018.x86_64


$ td-agent-gem list|grep forest
fluent-plugin-forest (0.3.3)

td-agent.confを配布する

$ cat hello/.ebextensions/td-agent_conf.config
files:
    "/etc/td-agent/td-agent.conf" :
        mode: "000644"
        owner: root
        group: root
        content: |
            <source>
              @type tail
              format ltsv
              path /var/www/html/hello/storage/logs/monolog-%Y-%m-%d
              tag local.laravel.log
              pos_file /var/log/td-agent/laravel.log.pos
            </source>
            <filter local.**>
              @type record_transformer
              <record>
                host ${hostname}
              </record>
            </filter>
            <match local.**>
              @type forest
              subtype s3
              <template>
                aws_key_id アイディー
                aws_sec_key キー
                s3_bucket at.test.bucket
                s3_region ap-northeast-1
                path laravel/dt=%Y-%m-%d-%H/
                buffer_path /var/log/td-agent/buffer/laravel.buf
                time_slice_format %Y-%m-%d
                time_slice_wait 10s
                flush_interval 10s
                format ltsv
              </template>
            </match>

ebコマンドを用いたデプロイ

https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/eb-cli3-configuration.html#eb-cli3-artifact

ざっくりイメージ

  • jenkinsでビルド
  • S3アップロード
  • ebコマンドでローリングデプロイ
ebコマンド使ってみる

ebコマンドインストール

本家にあるので省略

使ってみる

eb init

[centos@ip-172-31-10-238 ~]$ eb init

Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-south-1 : Asia Pacific (Mumbai)
7) ap-southeast-1 : Asia Pacific (Singapore)
8) ap-southeast-2 : Asia Pacific (Sydney)
9) ap-northeast-1 : Asia Pacific (Tokyo)
10) ap-northeast-2 : Asia Pacific (Seoul)
11) sa-east-1 : South America (Sao Paulo)
12) cn-north-1 : China (Beijing)
13) cn-northwest-1 : China (Ningxia)
14) us-east-2 : US East (Ohio)
15) ca-central-1 : Canada (Central)
16) eu-west-2 : EU (London)
17) eu-west-3 : EU (Paris)
(default is 3): 9

Select an application to use
1) BGDeploy
2) sample-laravel
3) [ Create new Application ]
(default is 3): 2

Select a platform.
1) Node.js
2) PHP
3) Python
4) Ruby
5) Tomcat
6) IIS
7) Docker
8) Multi-container Docker
9) GlassFish
10) Go
11) Java
12) Packer
(default is 1): 2

Select a platform version.
1) PHP 7.1
2) PHP 7.0
3) PHP 5.6
4) PHP 5.5
5) PHP 5.4
6) PHP 5.3
(default is 1): 1
Cannot setup CodeCommit because there is no Source Control setup, continuing wit                                                           h initialization
Do you want to set up SSH for your instances?
(Y/n): Y

Select a keypair.
1) hoge-hogeo
2) [ Create new KeyPair ]
(default is 1): 1

eb health  →マネコンでみているようなリストが出力された f:id:hoge-hogeo:20180928173243p:plain

memo

aws elasticbeanstalk describe-application-versions

マネコンの「アプリケーションバージョン」で見れるやつ

$ aws --profile eb-cli --region ap-northeast-1 elasticbeanstalk describe-application-versions
{
    "ApplicationVersions": [
        {
            "ApplicationName": "sample-laravel",
            "Status": "UNPROCESSED",
            "VersionLabel": "modify_healthcheck_path",
            "Description": "",
            "ApplicationVersionArn": "arn:aws:elasticbeanstalk:ap-northeast-1:57142996XXXX:applicationversion/sample-laravel/modify_healthcheck_path",
            "DateCreated": "2018-07-19T03:16:14.455Z",
            "DateUpdated": "2018-07-19T03:16:14.455Z",
            "SourceBundle": {
                "S3Bucket": "elasticbeanstalk-ap-northeast-1-57142996XXXX",
                "S3Key": "2018200EjT-hello.zip"
            }
        },

コマンドラインでデプロイしたい

アプリケーションのバージョンを作成
$ aws --profile eb-cli --region ap-northeast-1 elasticbeanstalk create-application-version \
--application-name sample-laravel --version-label 201807201700 \
--source-bundle S3Bucket="__bucket_name__",S3Key="hello.zip" --auto-create-application
{
    "ApplicationVersion": {
        "ApplicationName": "sample-laravel",
        "Status": "UNPROCESSED",
        "VersionLabel": "201807201700",
        "ApplicationVersionArn": "arn:aws:elasticbeanstalk:ap-northeast-1:571429965935:applicationversion/sample-laravel/201807201700",
        "DateCreated": "2018-07-20T08:19:43.496Z",
        "DateUpdated": "2018-07-20T08:19:43.496Z",
        "SourceBundle": {
            "S3Bucket": "__bucket_name__",
            "S3Key": "hello.zip"
        }
    }
}

無事登録された。

f:id:hoge-hogeo:20180928173404p:plain

環境へのデプロイ

201807251600をデプロイする

$ aws --profile eb-cli --region ap-northeast-1 elasticbeanstalk update-environment --environment-name Laravel-env --version-label 201807251600
{
    "ApplicationName": "laravel",
    "EnvironmentName": "Laravel-env",
    "VersionLabel": "201807251600",
    "Status": "Updating",
    "EnvironmentArn": "arn:aws:elasticbeanstalk:ap-northeast-1:571429965935:environment/laravel/Laravel-env",
    "PlatformArn": "arn:aws:elasticbeanstalk:ap-northeast-1::platform/PHP 7.1 running on 64bit Amazon Linux/2.7.1",
    "EndpointURL": "awseb-AWSEB-6T78TTLA31X-XXXXXXXXX.ap-northeast-1.elb.amazonaws.com",
    "SolutionStackName": "64bit Amazon Linux 2018.03 v2.7.1 running PHP 7.1",
    "EnvironmentId": "e-axab792pcj",
    "CNAME": "Laravel-env.XXXXXXXXXX.ap-northeast-1.elasticbeanstalk.com",
    "AbortableOperationInProgress": true,
    "Tier": {
        "Version": "1.0",
        "Type": "Standard",
        "Name": "WebServer"
    },
    "Health": "Grey",
    "DateUpdated": "2018-07-25T06:53:38.215Z",
    "DateCreated": "2018-07-25T02:01:56.666Z"
}

f:id:hoge-hogeo:20180928173934p:plain

アプリケーションバージョンについて

いくらバージョンラベルを切っても、ソースの「アプリ.zip」のパスが一緒だと最新のものが参照されるらしい。(当然といえば当然か)

下記の画像だと、20180725hhmmのバージョンラベルが3つあるが、ソースのパスはS3上で同じパスなので、

最古のバージョンラベルに紐づくソースは最新のバージョンラベルのものと同じになる。

f:id:hoge-hogeo:20180928174026p:plain

requirement.txtってどこで実行されてるの?

command:にtouch hogeとか入れてみる

$cat /var/www/html/hello/requirement.txt
commands:
  command block:
    command: |
      touch hoge
      "curl -L \"https://toolbelt.treasuredata.com/sh/install-amazon1-td-agent3.sh\" > td-agent_install.sh"
      sh td-agent_install.sh


ここがrequirement.txtが読み込まれ、実行されるpwdらしい

$ sudo find / -type f -name hoge
/opt/elasticbeanstalk/eb_infra/hoge

jenkins ジョブの排他実行したい話

概要

アプリケーションのデプロイに3つのジョブを使っている。

  • PHPアプリをビルドする@ビルドサーバ
  • ビルドしたアプリを対象サーバのDocumentRootへscpする
  • 対象サーバのDocumentRootを切り替えてリリースする

資源

資源 モノ 備考
EC2 amzn2-ami-hvm-2.0.20180810-x86_64-gp2 (ami-08847abae18baa040)
MW Jenkins ver. 2.140

検証

ノードを1つにしてみる

とりあえず、1ジョブだけ実行させられるのか確認してみよう。

これを採用すると、常に1ジョブしか実行できないとても使いづらいjenkinsになるけど。

jenkinsの管理→ノードの管理→ノードの歯車 f:id:hoge-hogeo:20180926123110p:plain

これを1にしてみる。 f:id:hoge-hogeo:20180926123146p:plain

実行してみるジョブはこんな感じ


PipelineのBulk-Deploy-API-for-WhiteがJob3つを実行するだけ

Job種
Pipeline Bulk-Deploy-API-for-White
Job Deploy-API-for-White
Job Release-API-to-Server-from-HUB-for-White
Job Change_SymbolicLink_API_for_White

待てど暮らせど始まらない、pipeline中の下流ジョブ f:id:hoge-hogeo:20180926124800p:plain

利用可能なエグゼキューターとは。。。

とりあえず思い当たるのは、ノード実行数を1つだけにしたやつ、戻してみる。 f:id:hoge-hogeo:20180926124926p:plain

動いた。pipelineと下流ジョブで、それぞれエグゼキューターが必要になるらしい。

f:id:hoge-hogeo:20180926130158p:plain

ということは、下流ジョブを複数起動したい場合は、pipline分 + 下流ジョブ並列実行分必要になるのか。。。


Pluginに頼ってみる

kyon-mm.hatenablog.com

Jenkins上からプラグインを探してみたけどなかった、ので変わりに下記のプラグインを入れてみた。

f:id:hoge-hogeo:20180926150335p:plain


パターンマッチで実行中のジョブがあったら、自分をブロックするようなので、雑に「.*」で試してみよう。 f:id:hoge-hogeo:20180926150603p:plain

Bulk-Deploy-Account-for-WhiteとBulk-Deploy-API-for-Whiteを同時実行してみる。

キューに片方が入って、もう片方はビルドが実行中になった。

f:id:hoge-hogeo:20180926151003p:plain

オンマウスで待ってるぜコメントが見れた。

f:id:hoge-hogeo:20180926151009p:plain

詰まることなく、2つのパイプラインジョブが完了した。

f:id:hoge-hogeo:20180926151240p:plain

一旦、これで排他的な動きは実現できた。。。

SonarqubeでCoverage出したい話

備忘録。

忘れている何かがあるかもしれない。

資源

  • CentOS Linux release 7.2.1511 (Core)
  • Jenkins ver. 2.73.1
  • Java 1.8.0_111 Oracle Corporation (64-bit)
  • SonarQube Scanner 2.8

手順

  • 必要なソースをgit clone
  • ログDIRとか作る
  • Composer updateする
  • php unitをかける

f:id:hoge-hogeo:20180928111938p:plain

Excludeするソースとか指定はしておいた方がいい。(Coverageに影響が出る) f:id:hoge-hogeo:20180928111432p:plain

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="vendor/autoload.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false">
    <testsuites>
        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>

        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./app</directory>
        </whitelist>
    </filter>
    <logging>
        <log type="junit" target="result.xml" logIncompleteSkipped="false"/>
        <log type="coverage-clover" target="./index.xml"/>
    </logging>
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="QUEUE_DRIVER" value="sync"/>
        <env name="DB_DATABASE" value="test_database_hoge"/>
    </php>
</phpunit>

Sonarに結果が出力されていればOK f:id:hoge-hogeo:20180928113328p:plain

Sonarに結果が出ないときは、jenkinsのワークスペースにそれぞれの結果ファイルが出力されているか確認する。

$ head /var/lib/jenkins/workspace/SonarScanner_hogehogeAPI/index.xml 
<?xml version="1.0" encoding="UTF-8"?>
<coverage generated="1538102369">
  <project timestamp="1538102369">
    <package name="App\Console">
      <file name="/var/lib/jenkins/workspace/SonarScanner_hogehogeAPI/app/Console/Kernel.php">
        <class name="App\Console\Kernel" namespace="App\Console">
          <metrics complexity="2" methods="2" coveredmethods="2" conditionals="0" coveredconditionals="0" statements="4" coveredstatements="4" elements="6" coveredelements="6"/>
        </class>
        <line num="25" type="method" name="schedule" visibility="protected" complexity="1" crap="1" count="23"/>
        <line num="29" type="stmt" count="23"/>
$ head /var/lib/jenkins/workspace/SonarScanner_hogehogeAPI/result.xml 
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
  <testsuite name="tests/Feature/Api/" tests="23" assertions="85" errors="0" failures="0" skipped="0" time="4.553398">
    <testsuite name="Tests\Feature\CreateChildTest" file="/var/lib/jenkins/workspace/SonarScanner_hogehogeAPI/tests/Feature/Api/Child/CreateChildTest.php" tests="9" assertions="17" errors="0" failures="0" skipped="0" time="1.940765">
      <testsuite name="Tests\Feature\CreateChildTest::testValidation" tests="4" assertions="8" errors="0" failures="0" skipped="0" time="0.628133">
        <testcase name="testValidation with data set &quot;0&quot;" class="Tests\Feature\CreateChildTest" classname="Tests.Feature.CreateChildTest" file="/var/lib/jenkins/workspace/SonarScanner_hogehogeAPI/tests/Feature/Api/Child/CreateChildTest.php" line="79" assertions="2" time="0.230536"/>
        <testcase name="testValidation with data set &quot;1&quot;" class="Tests\Feature\CreateChildTest" classname="Tests.Feature.CreateChildTest" file="/var/lib/jenkins/workspace/SonarScanner_hogehogeAPI/tests/Feature/Api/Child/CreateChildTest.php" line="79" assertions="2" time="0.134350"/>
        <testcase name="testValidation with data set &quot;2&quot;" class="Tests\Feature\CreateChildTest" classname="Tests.Feature.CreateChildTest" file="/var/lib/jenkins/workspace/SonarScanner_hogehogeAPI/tests/Feature/Api/Child/CreateChildTest.php" line="79" assertions="2" time="0.131509"/>
        <testcase name="testValidation with data set &quot;3&quot;" class="Tests\Feature\CreateChildTest" classname="Tests.Feature.CreateChildTest" file="/var/lib/jenkins/workspace/SonarScanner_hogehogeAPI/tests/Feature/Api/Child/CreateChildTest.php" line="79" assertions="2" time="0.131738"/>
      </testsuite>

Systemctlのサービスを作る

参考

enakai00.hatenablog.com

enakai00.hatenablog.com

■serviceファイル作成

vim /usr/lib/systemd/system/nginx.service
############################################
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIFfile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/bin/kill -s HUP $MAINPID
ExecStop=/usr/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
  
############################################

  
■list-unit-filesに認識されているか確認
$ sudo systemctl list-unit-files --type=service|grep nginx
nginx.service                     disabled
  
■有効化する
$ sudo systemctl enable nginx.service
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.

確認

■起動確認
$ sudo systemctl start nginx.service
$ ps -ef|grep ngin
root      9887     1  0 16:29 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx     9888  9887  0 16:29 ?        00:00:00 nginx: worker process
root      9971 32341  0 16:29 pts/1    00:00:00 grep --color=auto ngin
  
■systemctl statusで確認
□確認項目
・PIDがpsで引いたものと合致しているか
・ExecStart, ExecStartPreがそれぞれ動いたか
  
$ sudo systemctl status nginx.service
● nginx.service - nginx - high performance web server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since Mon 2018-04-16 16:29:35 JST; 42s ago
     Docs: http://nginx.org/en/docs/
  Process: 9886 ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf (code=exited, status=0/SUCCESS)
  Process: 9883 ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf (code=exited, status=0/SUCCESS)
 Main PID: 9887 (nginx)
   CGroup: /system.slice/nginx.service
       ├─9887 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
       └─9888 nginx: worker process
Apr 16 16:29:35 ip-10-56-79-94.ap-northeast-1.compute.internal systemd[1]: Starting nginx - high performance web server...
Apr 16 16:29:35 ip-10-56-79-94.ap-northeast-1.compute.internal nginx[9883]: nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
Apr 16 16:29:35 ip-10-56-79-94.ap-northeast-1.compute.internal nginx[9883]: nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
Apr 16 16:29:35 ip-10-56-79-94.ap-northeast-1.compute.internal systemd[1]: Started nginx - high performance web server.
Hint: Some lines were ellipsized, use -l to show in full.
  
■停止確認
$ sudo systemctl stop nginx.service
$ ps -ef|grep ngin
root     14815 32341  0 16:34 pts/1    00:00:00 grep --color=auto ngin