Tocyukiのブログ

ギターと柔術とプログラミングが好き!

2020年の振り返りと2021年の目標

コロナに主役を完全に奪われた2020年でしたが、思い返してみるとそこそこ色々あったな〜と感じますなぁ

トピックとしては

  • 長女が小学生になる
  • 在宅勤務による生活スタイルの変化
  • 仕事でいくつかの大きめのPJTを独力で完走
  • AWS SysOps取得
  • 転職
  • 柔術再開

という感じかな

2020年の振り返り

とりあえず去年の振り返りと目標で照らし合わせてみると全然達成できてなくて笑えてくる感じだなぁw blog.tocyuki.com

勉強

目標 実績 達成率
TOEIC700点以上 470点 60%
AWS資格5冠達成
(残りSysOps/DVA/SAP/DOPの4つを取得)
SysOpsのみ取得 30%
今積まれている技術書やUdemyを消化する
※主にPython系を
すこーしだけ消化できた 30%

去年に1ヶ月セブ留学したけどそこで得られる英語力はたかが知れてるもので、帰国後にノー勉強で受けたTOEICの結果がそれを表している

資格も結局SysOpsの一つのみのしか取得できずもとりあえず一つは取得したということで自分を褒めてあげよう

積読になっていた技術書やUdemyも少しだけ消化できたのでそれもやっただけよしということで

仕事

目標 実績 達成率
監視基盤の再構築 Datadogを導入 100%
CI/CDパイプライン構築&運用にのせる 一部運用開始するまでできた 20%
GitHub、Slackの導入 Slackのみ導入(GitHub導入自体がなくなった) 30%
定期的な勉強会の実施 まったくなにもせず 0%

仕事では監視基盤にDatadogを提案&導入し、すごくスムーズにいき開発者の運用参加のきっかけと伴う品質の向上に大きく貢献できたかなと

あとは完全にブラックボックスとなっていたシステムのリプレースも一人で担当し、短納期&トラブルなしで完了することができた

やったこととしては以下

  • Ansible化&Terraform化
  • PHP5系&MySQL5.5のバージョンアップ
  • AmazonLinux1からAmazonLinux2へのバージョンアップ
  • ルートアカウントから別サービスアカウントへの移行

GitHubの導入は当初PJ化して進める予定だったけど色々あってPJ自体が頓挫し、Slackに関してはチーム内利用&通知に留まってしまった

勉強会の開催も色々思うところもありまったくやらず個人的に外部の勉強会に参加するに留まってしまった

とりあえずはそんなこんなもあり12月に転職して心機一転SREチームの立ち上げからインフラのグランドデザインから担当できるのでとても楽しみである!

健康

目標 実績 達成率
6月までの間最低週2回は追い込む コロナのため2月からまったくジムに行けずも年末から柔術開始 20%
体脂肪率15%を切る まったく目標におよばずも柔術を始め光が見え始める 10%
月から柔術再開し最低週2回稽古を行う コロナのため12月ぐらいから開始 50%

ゴールドジムを半年契約したものの結局コロナで12月と1月の2ヶ月しか通えず、筋力の向上もかなり中途半端なもので終わってしまったが、ジムに行ったのは初めてだったので器具を使ったトレーニングがどういうものなのか等がわかりそこはひとつの収穫だったのかなと思える

また12月から柔術も再開し、約1年半ぶりということでびっくりするぐらい動けず、紫帯をつけているのが恥ずかしい感じだけどこちらは引き続き継続していこう

その他

目標 実績 達成率
ブログを週に一度は書く 22記事 40%

アウトプットのルーティン化も必要だなとも思いつつ、アウトプット駆動で物事にとりかかるのも必要なのかなとも思ったので、質より量でやっていこうと思いました

総括

とりあえず、全然達成はできずとも足掻くように前進することはできているのかなという一点のみで自分を褒めよう

  • Datadogの提案・検証・導入まですべて一人で素早くできた
  • 結構大きめのプロジェクトを一人でトラブルなく実施できた
  • TOEIC受けた
  • SysOps取得した
  • Udemyや技術書を少しだけど消化できた
  • 柔術再開した
  • 転職した

12月から転職もして、より大きな裁量でSREとして働くことができているし、完全在宅になったことで家族との時間も確保できて、無駄な飲み会(自分は飲むのが好きなので出勤すると高確率で飲みに行ってしまう)も減らせて伴って出費も減り、柔術もコンスタントに行けて、とてもポジティブな要素はたくさんつくることができたという2020年ではあったので2021年も良い部分はそのままに頑張りたい

課題としてはルーティン化と継続が弱かったのでそこも強化していきたい

2021年の目標

今年も勉強、仕事、健康を軸に目標を立てて達成していきたい

勉強

TOEIC600点

  • 毎日iKnow!とスタディサプリをやる
  • TOEIC2回受験する

iknow.jp

app.eigosapuri.jp

AWS資格6冠達成

  • 2月にSAP取得
  • 4月にDVA取得
  • 7月にDOP取得
  • 8月にCloudPractitoner取得

という感じで取得できて行ったら良いなという感じで!

その他

  • 毎週Atcoder参戦
  • 今積まれている技術書やUdemyを消化する(主にPython系を)
  • 学んだことは必ずブログにアウトプットする

atcoder.jp

仕事

  • SREチーム立ち上げ
  • 新規インフラのグランドデザイン

健康

体脂肪率15%を切る

  • 柔術稽古を最低週2回死守
  • 暴飲暴食をなくす
  • お酒を控える

おわりに

とりあえず振り返りと目標の確認をしてみて、こりゃやばいなという危機感が持てたので粛々と頑張ろうと思ったのでした
そして一時期やっていた振り返りのアウトプットもするようにしよう

ヒアドキュメントでインデントを含めた文字列を使う方法

ヒアドキュメントでインデントを含めたものを使いたいときには<<だけではだめで- <<とすると行頭のタブを無視してくれるので、この書き方だと以下のような用途の際にスクリプトできれいに書けるので便利

# configuration of td-agent
cat - << 'EOM' > /etc/td-agent/td-agent.conf
@include conf.d/*.conf

<match fluent.**>
  @type file
  path /var/log/td-agent/fluent.log
</match>
EOM

参考

qiita.com

qiita.com

【AWS】 instance profileを削除する方法

instance profileはCLIからしか削除できないっぽかったのでメモ

状況

Terraformでapply処理が途中でコケてしまいその影響なのか以下のエラーが表示され先に進めなくなってしまった

Error: Error creating IAM instance profile example-app-iam-instance-profile: EntityAlreadyExists: Instance Profile example-app-iam-instance-profile already exists.
        status code: 409, request id: 7e7d16b7-4ca2-4737-8210-b42c0a8620bb

削除方法

管理コンソールから削除しようとしたけど、どこからも削除ができなさそうだったが、CLIで削除ができそうだったので以下コマンドで無事削除できた

aws iam delete-instance-profile --instance-profile-name example-app-iam-instance-profile

参考情報

awscli.amazonaws.com

【Terraform】 skip_final_snapshot を設定しないでRDSを作成したらterraform destroyできなくなった

というわけで、これちょいちょいやってしまうんですが、Terraformでskip_final_snapshot = trueを設定しないでRDSリソースを作成して、その後削除しようとすると以下のエラーが出るようになってしまったんですよ

Error: RDS Cluster FinalSnapshotIdentifier is required when a final snapshot is required

というわけで対応手順をメモして行こうと思います

再現方法

以下のような感じでRDSのリソースを作成する

resource "aws_rds_cluster" "db" {
  cluster_identifier      = "${var.name}-${var.env}-db"
  engine                  = local.engine
  engine_version          = local.engine_version
  engine_mode             = local.engine_mode
  availability_zones      = values(var.azs)
  master_username         = aws_ssm_parameter.db_username.value
  master_password         = aws_ssm_parameter.db_password.value
  backup_retention_period = var.backup_retention_period
  preferred_backup_window = local.preferred_backup_window

  tags = merge(var.common_tags, {
    Name = "${var.name}-${var.env}-db"
    Role = "RDS"
  })
}

で、applyはうまくいくのでその後、destroyを実行すると・・・

Error: RDS Cluster FinalSnapshotIdentifier is required when a final snapshot is required

というエラーが出てしまい、Terraformでのこのリソースの削除ができなくなってしまいました

修正方法

stackoverflowの回答を参考に以下を実施したところ解決した

  • backup_retention_periodの値を0にする
  • preferred_backup_windowのパラメータを削除する
  • skip_final_snapshot = trueapply_immediately = trueを追加する

以下が修正後のコード

resource "aws_rds_cluster" "db" {
  cluster_identifier      = "${var.name}-${var.env}-db"
  engine                  = local.engine
  engine_version          = local.engine_version
  engine_mode             = local.engine_mode
  availability_zones      = values(var.azs)
  master_username         = aws_ssm_parameter.db_username.value
  master_password         = aws_ssm_parameter.db_password.value
  backup_retention_period = 0
  skip_final_snapshot     = true
  apply_immediately       = true

  tags = merge(var.common_tags, {
    Name = "${var.name}-${var.env}-db"
    Role = "RDS"
  })
}

そしてapplyを実施後、destroyで正常にリソースが削除されるようになりました〜!

参考情報

stackoverflow.com

【Terraform】 countからfor_eachへ書き換えたらスプラット演算子の動きが変わった

いままでcountで記述していたものをfor_eachに直してみたところスプラット演算子の動きが変わったのでメモ

状況

いままではVPCのサブネットリソースをcountで複数作ってそれをoutputで他のモジュールに渡して利用しておりました

resource "aws_subnet" "private_data" {
  count                   = length(var.azs)
  vpc_id                  = aws_vpc.vpc.id
  cidr_block              = cidrsubnet(aws_vpc.vpc.cidr_block, 8, 11 + count.index)
  availability_zone       = element(var.azs, count.index)
  map_public_ip_on_launch = false
}

output "data_private_subnets" {
  value = aws_subnet.private_data
}

他のモジュールで使うときはこんな感じで使ってた

resource "aws_db_subnet_group" "db" {
  name        = "${var.name}-${terraform.workspace}-db-subnet"
  description = "Database Subnet Group for ${var.name}-${terraform.workspace}"
  subnet_ids  = var.data_private_subnets[*].id # この部分
}

そんでもって、for_eachを使って書き直したのがこちら

resource "aws_subnet" "private_db" {
  for_each          = var.azs
  cidr_block        = cidrsubnet(aws_vpc.vpc.cidr_block, 8, index(values(var.azs), each.value) + 11)
  availability_zone = each.value
  vpc_id            = aws_vpc.vpc.id
  map_public_ip_on_launch = false
}

すると以下のようなエラーが出るようになった

Error: Unsupported attribute

  on modules/aws/database/subnet_group.tf line 4, in resource "aws_db_subnet_group" "db":
   4:   subnet_ids  = var.data_private_subnets[*].id

This object does not have an attribute named "id".

Issue

とりあえずIssueを漁ってみたら以下が見つかった

github.com

github.com

Issueを読んでみると以下のように修正すれば大丈夫っぽいことがわかった

The short answer is that if you were to modify your code to values(aws_route53_record.record)[*].fqdn it will work as you're expecting it to.

修正

Issueに書いてあるとおり、aws_db_subnet_groupのリソース作成部分を以下のように修正したら問題なく動くようになった

resource "aws_db_subnet_group" "db" {
  name        = "${var.name}-${terraform.workspace}-db-subnet"
  description = "Database Subnet Group for ${var.name}-${terraform.workspace}"
  subnet_ids  = values(var.private_subnets_db)[*].id # この部分
}

おわりに

for_each便利だけど思わぬ落とし穴?にハマってしまいました

Intellij IDEA の ideavim で h,j,k,l で連続移動できない場合の修正方法

自宅のMacでIntellij IDEAにideavimのプラグインを入れて使っているんですが、なぜか、h,j,k,lのキーバインドで移動ができず困っていたらこちらにソリューションが記載されていて、試してみたら解消できたのでメモ

t.co

実行したコマンド

defaults write -g ApplePressAndHoldEnabled -bool false

Bashの変数で大文字、小文字の変換をsedを使わないでやる方法

mattnさんの以下ツイートが流れてきてめちゃ便利じゃんと感動したのでメモ

まとめ

最初の文字だけ大文字にする

$ os=linux; echo ${os^}
Linux

全部大文字にする

$ os=linux; echo ${os^^}
LINUX

最初の文字だけ小文字にする

$ os=LinuX; echo ${os,}
linuX

最初と最後の文字だけ小文字にする

$ os=LinuX; echo ${os,,}
linux

大文字小文字を入れ替える

$ os=LiNuX; echo ${os~~}
lInUx

指定文字置換

$ os=Linux; echo ${os//inu/umi}
Lumix

おわりに

これらの記法はbash v4以降で使えるものなので、MacとかのBashだと動きません\(^o^)/
Bash Tipsすきだわ〜\(^o^)/

php-fpm + apache環境での環境変数の持たせ方

php-fpm環境下でApache httpdのSetEnvで設定された環境変数は、PHPのenv()等では取得できるが、
execで実行されるコマンドには、SetEnvで設定された環境変数が反映されなかったので(php-fpmの仕様?)実施した回避策を書く!

要約

  • ApacheのSetEnvは使わず/etc/environmentに環境変数を記載して利用する

/etc/environmentの環境変数利用手順

/etc/systemd/system/httpd.serviceを作成

  • 以下内容で作成する
.include /lib/systemd/system/httpd.service

[Unit]
After=network.target remote-fs.target nss-lookup.target httpd-init.service cloud-config.service

[Service]
UMask=002
EnvironmentFile=/etc/environment

/etc/systemd/system/php-fpm.serviceを作成

  • 以下内容で作成する
.include /lib/systemd/system/php-fpm.service

[Unit]
After=syslog.target network.target cloud-config.service

[Service]
UMask=002
EnvironmentFile=/etc/environment
PrivateTmp=false

/etc/php-fpm.d/www.confに1行追加

  • 以下を追記
clear_env = no

あとは/etc/environmentに環境変数を記載していくだけ!

mysqldumpをするときによく使うオプションとリストア方法

概要

手順

事前準備

  • --default-character-setでどの文字コードで mysqldump を取得するか、対象 DB の現在の文字コードを確認する
$ mysql -u${DB_USERNAME} -p${DB_PASSWORD} -h${DB_HOST} -e 'show variables like "character_set_database";'

mysqldump取得

圧縮しない時

  • テーブル単位の取得の場合
$ mysqldump -u${DB_USERNAME} -p${DB_PASSWORD} -h${DB_HOST} --single-transaction --default-character-set=${CHARASET} --routines ${DB_NAME} ${TABLE_NAME_1} ${TABLE_NAME_2} > hogehoge_`date +%Y%m%d`.sql
  • DBスキーマ単位で取得の場合
$ mysqldump -u${DB_USERNAME} -p${DB_PASSWORD} -h${DB_HOST} --single-transaction --default-character-set=${CHARASET} --routines --add-drop-database --databases ${DB_NAME} > hogehoge_`date +%Y%m%d`.sql

圧縮する時

  • テーブル単位の取得の場合
$ mysqldump  -u${DB_USERNAME} -p${DB_PASSWORD} -h${DB_HOST} --single-transaction --default-character-set=${CHARASET} --routines ${DB_NAME} ${TABLE_NAME_1} ${TABLE_NAME_2} | gzip > hogehoge_`date +%Y%m%d`.sql.gz
  • DBスキーマ単位で取得の場合
$ mysqldump -u${DB_USERNAME} -p${DB_PASSWORD} -h${DB_HOST} --single-transaction --default-character-set=${CHARASET} --routines --add-drop-database --databases ${DB_NAME} | gzip > hogehoge_`date +%Y%m%d`.sql.gz

各オプションの内容

single-transaction

  • 対象がinnodbのときのみ有効(myIsamでは効果がない)
  • dump取得時にテーブルロックをしないため、更新時の待ちが発生しない。

default-character-set

  • dump時の文字コードを指定する。
  • 指定した文字列に変換してdumpを作成する。
  • 指定しない場合、サーバー側で指定されているデフォルト文字コードが自動指定されるため、取得側とリストア側で文字コードのデフォルトが違う場合には、文字化けが起きる可能性が高まる。

routines

  • ストアドルーチン (プロシージャーおよび関数) も一緒にdumpに含める。

add-drop-database

  • 指定したDBスキーマをdrop database(削除)するクエリをdumpに含める。

リストア方法

TABLEのリストア

$ mysql -u${DB_USERNAME} -p${DB_PASSWORD} -h${DB_HOST}  -D ${DB_NAME} < hogehoge_`date +%Y%m%d`.sql

DBのリストア

$ mysql -u${DB_USERNAME} -p${DB_PASSWORD} -h${DB_HOST} < hogehoge_`date +%Y%m%d`.sql

SQLを勉強したい時に活用できる無料サイト

基本的なSQLを学びたい場合、以下のサイトで事足りるなと思ったのでメモ

SQL Lab

sqlab.net

超初心者向けなのでまずはここから。

SQLZoo

sqlzoo.net

用意されているテーブルから指定された結果を取得するSQL文を書いて回答していく。

日本語対応されている。

SQL bolt

sqlbolt.com

英語だけど問題もシンプルなのでそんなに理解に苦しむことなく、サクサクと進めることができ、一通りのSQL構文を身につけることができるので、オススメです

ただし、なぜかChromeでは文字入力がずれてしまっているのでサファリ等他のブラウザでの実行をオススメします!

HackerRank

www.hackerrank.com

SQL Topic Contest

AtCoder的なコンテスト形式で定期的にコンテストが開催されたり、過去問を解くこともできる

topsic-contest.jp

まとめ

以下の順で進めると良さそうなのでSQL初心者の方は是非チャレンジしてみてください〜\(^o^)/

  • SQL Lab
  • SQLZoo
  • SQL bolt
  • SQL Topic Contest
  • HackerRank

Pythonでインストールされているはずのpipモジュールが読み込みできない場合の対処

boto3を使ってデプロイスクリプトを作成していたら、インストールされているはずのboto3が読み込みできないというエラーが発生

$ python3 test.py
Traceback (most recent call last):
  File "test.py", line 1, in <module>
    import boto3
ModuleNotFoundError: No module named 'boto3'

確認してみると、やはりしっかりとインストールされている

$ pip3 show boto3
Name: boto3
Version: 1.14.34
Summary: The AWS SDK for Python
Home-page: https://github.com/boto/boto3
Author: Amazon Web Services
Author-email: UNKNOWN
License: Apache License 2.0
Location: /usr/local/lib/python3.7/site-packages
Requires: botocore, jmespath, s3transfer
Required-by: 

モジュール読み込みパスが足りていないじゃないのかと疑い、以下のスクリプトを作成し確認

import sys
import pprint
pprint.pprint(sys.path)

やはりLocation: /usr/local/lib/python3.7/site-packagesがないことが判明

['/Users/{USERNAME}/.ghq/repository_path',
 '/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python37.zip',
 '/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7',
 '/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/lib-dynload',
 '/Users/{USERNAME}/Library/Python/3.7/lib/python/site-packages',
 '/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/site-packages']

なんでこんなことが起こるのかまでは調べられてないけど、とりあえず、環境変数PYTHONPATHにLocationで表示されたパスを追加したらエラーは出なくなったのでよしとしようw

export PYTHONPATH='/usr/local/lib/python3.7/site-packages:$PYTHONPATH'  

後日談

python2系を動かすとエラーとなってしまったので、やはり根本解決にはなっていない模様

Your PYTHONPATH points to a site-packages dir for Python 3.x but you are running Python 2.x!
     PYTHONPATH is currently: "/usr/local/lib/python3.7/site-packages:$PYTHONPATH"
     You should `unset PYTHONPATH` to fix this.

GitでAuthorを間違えてしまった場合の対応方法

何度もプライベートのリポジトリに会社のAuthor情報でCommit&Pushしてしまいその度にAuthor情報を修正する日々を過ごしているのでメモとして残しておきます。

前提

  • git config --globalで会社のAuthor情報を登録している
  • プライベートで利用しているリポジトリに会社のAuthor情報でCommit&Pushしてしまった

対応手順

対象リポジトリのAuthor情報を正しいものに修正

git config --local user.email "プライベート用のアドレス"
git config --local user.name "プライベート用のアカウント名"

修正対象のコミットへrebaseする

git rebase -i HEAD^

以下の要領でAuthor情報の修正を実施する

git commit --amend --reset-author 
git rebase --continue
git push -f 

rebase後に修正を破棄したくなった場合、は以下のコマンドを実施する

git rebase --abort

SSHの秘密鍵をAWS Secret Managerで管理する

要点

  • 秘密鍵をバイナリ形式でSecretManagerに登録
  • バイナリ形式でSecretManagerへ登録するにはCLIで実行する必要がある
  • AWS CLIで呼び出してBase64でデコードして使う

AWS CLIによるSecretManagerへ秘密鍵をバイナリ形式で登録する

$ aws secretsmanager create-secret \
   --name ${KEYPAIR_NAME} \
   --secret-binary file://~/.ssh/${KEYPAIR_NAME}.pem

AWS CLIで呼び出してBase64でデコード

$ aws secretsmanager get-secret-value \
    --secret-id ${KEYPAIR_NAME} \
    --query 'SecretBinary' \
    --output text \
    | base64 -d > ${KEYPAIR_NAME}.pem

参考

dev.classmethod.jp

PHP7.3環境でmecabを使えるようにする

とある業務でPHP5.5からPHP7.3へバージョンアップする必要が発生しまして、その環境ではphp-mecabをつかっているんですが、どうもPHP7系だとパッケージマネージャーでインストールできないっぽいので、ソースからコンパイルしてインストールする必要がありそうだ、ということで手順をメモとして残しておこうという次第でございま。

目次

環境情報

項目 詳細
OS Amazon Linux 2
PHPバージョン 7.3

mecabのインストール

以下からmecabのソースファイルとなるmecab-0.996.tar.gzをダウンロード

taku910.github.io

以下の手順でコンパイルおよびインストールを実施

tar -xvf mecab-0.996.tar.gz
cd mecab-0.996
./configure --enable-utf8-only
make
make install

mecab-ipadicのインストール

以下からmecab-ipadicのソースファイルとなるmecab-ipadic-2.7.0-20070801.tar.gzをダウンロード

taku910.github.io

以下の手順でコンパイルおよびインストールを実施

tar -xvf mecab-ipadic-2.7.0-20070801.tar.gz
cd mecab-ipadic-2.7.0-20070801
./configure --with-mecab-config=/usr/local/bin/mecab-config --with-charset=utf8
make
make install

php-mecabのインストール

以下のリポジトリからソースをクローンする

github.com

以下の手順でコンパイルおよびインストールを実施

cd php-mecab/mecab
phpize
./configure --with-mecab=/usr/local/bin/mecab-config
make
make install

動作確認

動作確認用PHPプログラム

<?php
$str = "すもももももももものうち";
$mecab = new \MeCab\Tagger(array('-O' => 'chasen'));
echo $mecab->parse($str) . PHP_EOL;

実行結果

$ php test.php 
すもも  スモモ  すもも  名詞-一般
も      モ      も      助詞-係助詞
もも    モモ    もも    名詞-一般
も      モ      も      助詞-係助詞
もも    モモ    もも    名詞-一般
の      ノ      の      助詞-連体化
うち    ウチ    うち    名詞-非自立-副詞可能
EOS