2023年5月8日月曜日

ubuntu22 のasdf install python でエラーになる

 

WSL2(ubuntu22.04)で asdf install python をすると下記のエラーになりました。

$ asdf install python 3.9.16
python-build 3.9.16 /home/blue21/.asdf/installs/python/3.9.16
Downloading Python-3.9.16.tar.xz...
-> https://www.python.org/ftp/python/3.9.16/Python-3.9.16.tar.xz
Installing Python-3.9.16...
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/blue21/.asdf/installs/python/3.9.16/lib/python3.9/ssl.py", line 99, in <module>
    import _ssl             # if we can't import it, let the error propagate
ModuleNotFoundError: No module named '_ssl'
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

Please consult to the Wiki page to fix the problem.
https://github.com/pyenv/pyenv/wiki/Common-build-problems


BUILD FAILED (Ubuntu 22.04 using python-build 2.3.17-9-g528d10e9)

Inspect or clean up the working tree at /tmp/python-build.20230508095140.208920
Results logged to /tmp/python-build.20230508095140.208920.log

Last 10 log lines:
        LD_LIBRARY_PATH=/tmp/python-build.20230508095140.208920/Python-3.9.16 ./python -E -m ensurepip \
                $ensurepip --root=/ ; \
fi
Looking in links: /tmp/tmpecek77jj
Processing /tmp/tmpecek77jj/setuptools-58.1.0-py3-none-any.whl
Processing /tmp/tmpecek77jj/pip-22.0.4-py3-none-any.whl
Installing collected packages: setuptools, pip
  WARNING: The scripts pip3 and pip3.9 are installed in '/home/blue21/.asdf/installs/python/3.9.16/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-22.0.4 setuptools-58.1.0


下記URLを参考に依存パッケージはインストール済です。

brew を使ってる影響だろうか?

ネットで調べて、いろいろ試しましたが、下記のようにしたらinstallに成功しました。

$ PYTHON_CONFIGURE_OPTS="--with-openssl=/usr --with-openssl-rpath=/usr/lib64 --enable-optimizations" asdf install python 3.9.16
python-build 3.9.16 /home/blue21/.asdf/installs/python/3.9.16
Downloading Python-3.9.16.tar.xz...
-> https://www.python.org/ftp/python/3.9.16/Python-3.9.16.tar.xz
Installing Python-3.9.16...
Installed Python-3.9.16 to /home/blue21/.asdf/installs/python/3.9.16

list で見ると以下のとおり。

$ asdf list python
 *3.11.3
  3.9.16


2023年4月21日金曜日

ssh鍵を別マシンで使ったらgit cloneでrepository not found になった

 

いつもはLinuxマシン(debian)で開発している。

Linuxマシン(debian)で使用していたSSH鍵を使いまわそうとして、WindowsマシンのWSL2(ubuntu)にコピーしてgit clone したら、下記のエラーになった。

$ git clone git@github.com:user/demo.git
Cloning into 'demo'...
Warning: Permanently added 'github.com,20.27.177.113' (ECDSA) to the list of known hosts.
ERROR: Repository not found.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.


Linuxマシン(debian)のSSH鍵を使いまわすことは、できないみたい。

WindowsのWSL2(ubuntu)でSSH鍵を作ってGithubに登録したら、git cloneできました。


2023年3月25日土曜日

EKSのkubeconfigを作らずに、kubectlとhelm コマンドを動かす

 

こんなかんじでEKSから情報を取ります。

EKS_CLUSTER_NAME=main-cluster
EKS_TOKEN=$(aws eks get-token \
			--cluster-name ${EKS_CLUSTER_NAME} \
			| jq -r '.status.token')
EKS_ENDPOINT=$(aws eks describe-cluster \
			--name ${EKS_CLUSTER_NAME} \
			--query 'cluster.endpoint' \
			--output text)
aws eks describe-cluster \
		--name ${EKS_CLUSTER_NAME} \
		--query 'cluster.certificateAuthority.data' \
		--output text \
		| base64 -d > /tmp/ca.crt


上記の情報を kubectl に渡して実行します。

s kubectl get pods -A \
	--server="${EKS_ENDPOINT}" \
	--certificate_authority=/tmp/ca.crt \
	--token="${EKS_TOKEN}"


helm は、こんなかんじ

helm repo add eks https://aws.github.io/eks-charts \
		--kube-apiserver "${EKS_ENDPOINT}" \
		--kube-token "${EKS_TOKEN}" \
		--kube-ca-file "/tmp/ca.crt"


EKSを構築したヒト以外は、下記URLの作業が必要かもしれない。

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/add-user-role.html



2023年3月18日土曜日

awscliのSSM(AWS-RunShellScript)でコマンドにシングルクォーテーションを使うとエラーになる

 

こんな感じで、シングルクォーテーションを含んだコマンドを実行するとエラーになります。

$ CMD="sudo su - ec2-user -c 'ls -l /'"
$ aws ssm send-command \
--document-name "AWS-RunShellScript" \
--comment "test" \
--instance-ids i-0f70020feb5f861ce \
--parameters commands="$CMD"

Error parsing parameter '--parameters': Expected: ',', received: ''' for input:
commands=sudo su - ec2-user -c 'ls -l /'

これを、下記のように --parameters の引数をjson形式にすると実行できました。

$ aws ssm send-command \
--document-name "AWS-RunShellScript" \
--comment "test" \
--instance-ids i-0f70020feb5f861ce \
--parameters "{\"commands\":[\"$CMD\"]}"

 

 

2023年3月11日土曜日

私のtmux (2023年バージョン)

 

私の環境

- SparkyLinux6.6

- bash5.1.4

- tmux3.3a

- Terminal: xfce terminal

- Terminal font: DroidSansMono Nerd Font 10


私のtmuxの見た目です。

左右に画面を分割し、右側を上下に分割しています。


ターミナルは、xfce terminal を使用しています。

私が試した他のターミナルは、画面分割したときに罫線が崩れてしまったのですが、xfce terminal は問題ありませんでした。

ターミナルフォントは、DroidSansMono Nerd Font 10を使用しています。

下記から入手しました。

xfce terminal のフォント設定以下のとおり。

ターミナル右クリックでメニューを表示し、「設定」を選択すると設定画面が開きます。


tmuxの設定(tmux.conf)は以下のとおり。

###############################################################
# シェルの設定
###############################################################

# tmux 起動時のシェルを /bin/zsh にする
#set -g default-shell /bin/zsh

# /usr/local/bin/zsh を使っている場合
# set -g default-shell /usr/local/bin/zsh

###############################################################
# prefix キーバインド変更 ※デフォルトは C-b
###############################################################

# prefix を C-z に変更する
#set -g prefix C-z
#bind-key C-z send-prefix
#unbind-key C-b

# prefix C-b を解除
#unbind C-b

###############################################################
# Emacs 風キーバインド
###############################################################

# setw -g mode-keys vi
setw -g mode-keys emacs

# prefix C-z でコピーモードに入る
bind-key C-z copy-mode
# prefix C-y でペーストする
bind-key C-y paste-buffer
# PageUp => 1ページ遡ってコピーモードに入る: ログを見る時など便利
bind -n Pageup copy-mode -u

unbind 1
unbind ^C
unbind &

# prefix 0 現在のペインを削除
bind 0 kill-pane
# prefix 1 ウインドウ内の現在のペインを残し、他のペインをウインドウにする
bind 1 break-pane
# prefix 2 ウインドウを横に分割
bind 2 split-window -v
# prefix 3 ウインドウを縦に分割
bind 3 split-window -h
# prefix o ペインをローテート
bind o select-pane -t :.+
# prefix k ウインドウを削除
bind k kill-window
# prefix C-k ペインを削除
bind C-k kill-pane
# prefix i
bind i display-panes
# prefix C-t
bind C-t next-window
# prefix c
bind c  new-window

###############################################################
# vim 風キーバインド
###############################################################

# vim のキーバインドでペインを移動する
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

# vim のキーバインドでペインをリサイズする

bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5

###### Vim コピーモード ######

# 'v' で選択を始める
# bind -T copy-mode-vi v send -X begin-selection

# 'V' で行選択
# bind -T copy-mode-vi V send -X select-line

# 'C-v' で矩形選択
# bind -T copy-mode-vi C-v send -X rectangle-toggle

# 'y' でヤンク
# bind -T copy-mode-vi y send -X copy-selection

# 'Y' で行ヤンク
# bind -T copy-mode-vi Y send -X copy-line

###############################################################
# キーバインド
###############################################################

# 番号基準値を変更
set -g base-index 1

# マウス操作を有効にする
set -g mouse on
bind -n WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'copy-mode -e'"

# マウスアップ時に選択完了せず、選択状態を維持し、Ctrl-cでクリップボードにコピーする
unbind -T copy-mode MouseDragEnd1Pane
unbind -T copy-mode-vi MouseDragEnd1Pane
bind-key -T copy-mode C-c send-keys -X copy-pipe-and-cancel "xsel -bi"
bind-key -T copy-mode-vi C-c send-keys -X copy-pipe-and-cancel "xsel -bi"

###############################################################
# 色・見た目
###############################################################

# ステータスバーを 1 秒毎に描画し直す
set -g status-interval 1

# センタライズ (主にウインドウ番号など)
set -g status-justify centre

# ステータスバーをトップに配置する
set -g status-position top

# 左右のステータスバーの長さを決定する
set -g status-left-length 90
set -g status-right-length 90

# ステータスバー(左側)
#set -g status-left '#H:[#P]'
#set -g status-left 'Session:#S W:#I P:#P'
set-option -g status-left  "\
#[bg=colour148]#[fg=colour234] Session:#S W:#I P:#P \
#[bg=colour054]#[fg=colour255] #h \
#[bg=colour024] #(~/workspace/toolbin/ip.sh)\
#[fg=colour024]#[bg=colour234]"

# ステータスバー(中央)
setw -g window-status-current-format '\
#[fg=colour239]#[bg=colour234]#[bg=colour239]#[fg=colour119]\
#I#[fg=colour249]:#[fg=colour255]#W#[fg=colour249]\
#F#[fg=colour239]#[bg=colour234]'

# ステータスバー(右側)
#set -g status-right '[%y-%m-%d(%a) %H:%M]'
set-option -g status-right "\
#[fg=colour237]#[fg=colour254]#[bg=colour237]\
#[bg=colour237] #(~/workspace/toolbin/uname.sh)\
#[fg=colour240]#[fg=colour255]#[bg=colour240]\
%Y-%m-%d(%a) %H:%M "

# ステータスバーの色を設定する
set -g status-bg "colour234"
set -g status-fg "colour255"

# pane border
set -g pane-border-style fg="colour236"
set -g pane-active-border-style fg="colour106"
#setw -g window-status-activity-style bg="colour16","underscore",fg="colour45"

# pane status bottom
set-option -g pane-border-status bottom

# tmuxを 24bit color 表示できるようにする
set -g default-terminal xterm-256color
set -ga terminal-overrides ',xterm-256color:Tc'

###############################################################
# iTerm2 設定
###############################################################

# tmux ウインドウタイトルを iTerm2 タブ/ウインドウのタイトルに表示する
#set-option -g set-titles on
#set-option -g set-titles-string '#T'

###############################################################
# Plugin for windows
###############################################################

# https://github.com/equalsraf/win32yank/releases/download/v0.0.4/win32yank-x86.zip
#bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "win32yank.exe -i"
#bind p run-shell 'win32yank.exe -o | xargs -0 -I{} tmux set-buffer -- {} && tmux paste-buffer'

emacsライクなキーバインドにしています。

- CTL-b,2 で上下2列に分割

- CTL-b,3 で左右2列に分割


コピー&ペーストは、デフォルト設定だとブラウザにペーストできなかったので変更しています。

- マウスで選択後、CTL-cでコピーします。

- CTL-SHIFT,vでペーストします。


~/workspace/toolbin/ip.sh で画面左上に自分のIPアドレスを表示します。

#!/bin/bash 
ip=$(ip a | grep inet | grep wlan0 | awk '{print $2}')
echo "$(echo -e '\uf817') ${ip}"

~/workspace/toolbin/uname.sh で画面右上に自分のOSを表示します。

#!/bin/bash
os=$(cat /etc/os-release | tr -d '"' | awk -F'=' '($0~/^NAME/){printf("%s ",$2)}')
echo "$(echo -e '\uf83c') ${os}"




2023年2月26日日曜日

ログイン画面を通らずにAWSコンソールをコマンド一撃で開いてみる


私のPC環境

- SparkyLinux6.5

- aws-cli2.x

- jq


私のAWS環境

- AWSアカウントが2つあります。

- 認証用と検証用です。

 

私がAWSコンソールを使用するときは、サインインするときにMFAの認証コードを入力しています。

また、認証用アカウントにサインインしてから検証用アカウントにスイッチロールする手順にしています。


ちょっと見たいだけのときは、これがめんどくさいので、コマンド一撃で検証用アカウントのAWSコンソールを開くようにしました。

下記URLの情報を参考にしています。


下記のコードを ~/awsc_open.sh のPATHで保存します。

ROLE には、スイッチロールで使用するIAM Role名を設定します。

AUTH_PROFILE には、認証アカウントのprofile名(aws-cli)を設定します。

#!/bin/bash

AWS_FED_URL=https://signin.aws.amazon.com/federation
AWS_CONSOLE_URL=https://console.aws.amazon.com/
ROLE=<IamRole>
AUTH_PROFILE=<prfoile>

function urlencode
{
    echo $1 | jq -Rr '@uri'
}


arn=$(aws iam list-roles \
    --query "Roles[?RoleName == '${ROLE}'].Arn" \
    --output text)

if [ "${arn}" == "" ]; then
    echo "${ROLE} is not found."
    exit 1
fi

key=$(aws sts assume-role \
    --profile ${AUTH_PROFILE} \
    --role-arn "${arn}" \
    --role-session-name OneTimeSession \
    --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \
    --output text)

access_key=$(echo "${key}" | awk -F"\t" '{printf("%s",$1)}')
secret_access_key=$(echo "${key}" | awk -F"\t" '{printf("%s",$2)}')
session_token=$(echo "${key}" | awk -F"\t" '{printf("%s",$3)}')

if [ "${access_key}" == "" ]; then
    echo "assume-role failed."
    exit 1
fi

json="{\"sessionId\":\"${access_key}\",\"sessionKey\":\"${secret_access_key}\",\"sessionToken\":\"${session_token}\"}"

token=$(curl -s "${AWS_FED_URL}?Action=getSigninToken&Session=$(urlencode ${json})" \
    | jq -r .SigninToken)

if [ "${token}" == "" ]; then
    echo "get signin token failed."
    exit 1
fi

url="${AWS_FED_URL}?Action=login&Issuer=&Destination=$(urlencode ${AWS_CONSOLE_URL})&SigninToken=$(urlencode ${token})"

#echo ${url}
google-chrome --incognito ${url}

exit 0

このファイルを bash aliasに登録します。

~/.bashrc などに下記のように記載します。

alias awsc='~/awsc_open.sh'


ターミナルで awsc と入力してENTERすると、

下図のようなかんじでAWSコンソールを開けます。

ログイン画面は通らずに、いきなりホーム画面にいけます。



環境変数のAWS_PROFILEに設定したAWSアカウントのAWSコンソールが開きます。

Chromeのシークレットモードで開きます。

セッションの有効期限は1時間です。



2023年2月23日木曜日

EKS(fargate)でargocdを試す環境をCloudformationで作ってみた

 

下記の別記事で書いた、terraformで構築したEKS環境をCloudformationで構築してみました。

ただ、k8sの設定は、Cloudformationで出来ないので、kubectl, helmなどのコマンドを使用しています。


私の環境
  • SparkyLinux6.5(Debian系)
  • Bitbucket
    • ssh秘密鍵(レポジトリアクセス用)
  • k8s
    • kubectl1.25.4
    • helm3.10.2
  • aws
    • aws-cli2.9.4
    • eksctl0.13.0
    • rain1.3.0
    • cfn-lint0.73.2
    • ssh秘密鍵(EC2用キーペア)
  • os command
    • make
    • bash
    • jq
    • envsubst

サンプルコード


https://github.com/blue21jp/aws-sample-cfn-eks


構成


.
├── README.md
├── demo_todo.org
├── global/
│   └── variables.mk
├── stacks_base/
│   ├── 01_network/
│   │   ├── Makefile
│   │   └── cfn_vpc.yml
│   ├── 02_prefix_list/
│   │   ├── Makefile
│   │   └── cfn_prefix_list.yml
│   ├── 03_nat/
│   │   ├── Makefile
│   │   └── cfn_nat.yml
│   ├── Makefile
│   ├── variables_all.mk
│   └── variables_prd.mk
└── stacks_eks/
    ├── 01_vpc/
    │   └── Makefile
    ├── 02_ssm/
    │   └── Makefile
    ├── 10_eks_cluster/
    │   ├── Makefile
    │   ├── cfn_eks_cluster.yml
    │   ├── cfn_eks_fargate_profile.yml
    │   └── cfn_eks_oidc.yml
    ├── 11_k8s_init/
    │   └── Makefile
    ├── 20_k8s_alb_controller/
    │   ├── Makefile
    │   └── aws_alb_policy.json
    ├── 20_k8s_eso/
    │   ├── Makefile
    │   ├── aws_eso_policy.json
    │   └── k8s_eso_cluster_secret.yml
    ├── 20_k8s_metric_server/
    │   └── Makefile
    ├── 21_k8s_argocd/
    │   ├── Makefile
    │   └── k8s_argocd_ingress.yml
    ├── 21_k8s_dashboard/
    │   ├── Makefile
    │   └── k8s_dashboard_ingress.yml
    ├── 40_app_argocd/
    │   ├── Makefile
    │   ├── argocd_apps.json
    │   ├── argocd_apps.sh
    │   ├── argocd_git_repositorys.json
    │   ├── argocd_git_repositorys.sh
    │   ├── k8s_argocd_app.yml
    │   ├── k8s_argocd_repo.yml
    │   ├── k8s_external_secret.yaml
    │   └── k8s_ingress_app.yml
    ├── Makefile
    ├── variables_all.mk
    └── variables_prd.mk

この構成の説明と基本操作方法は、下記の別記事を参照。
下記の記事はterraform用なので、多少、本記事のCloudformation用とは使用方法(オプションとか)が異なりますが、考え方は同じです。
今回のEKS環境は、前述の別記事(terraform版)と比較して、下記を変えてます。
  • appは、tf-sample-eks レポジトリを使用します。
  • SecurityGrpoupの設定に、マネージドプレフィックスリストを使用しています。
  • argocd画面のexecを有効にしています。(GUIからpodに入れる)
  • argocd用の設定情報(レポジトリ、アプリケーション)は、40_app_argocdのjsonファイルに記述しています。


構築


準備


bitbucket
レポジトリアクセス用のSSH秘密鍵は下記のPATHを使用します。
~/.ssh/id_rsa

awscli 
AWS用のprofile名は "sandbox" を使用します。us-east-1で動作確認しています。

ec2キーペア
NATインスタンスで使用するキーペアです。"sandbox"を使用します。
節約のためにNATゲートウェイでなくNATインスタンスを使ってます。

Cloudformation実行


下記コマンドを実行すると、rain deployやawscli,kubeclt,helm,eksctlが実行されます。
これで、AWS環境にリソース一式(vpc, eks, ssm, argocd, dashbord, etc)が構築されます。
$ make -C stacks_base deploy
$ make -C stacks_eks deploy


破棄


下記コマンドを実行するとリソースを全部、破棄します。
$ make -C stacks_eks remove
$ make -C stacks_base remove







2023年2月19日日曜日

Linuxデスクトップで画面操作を録画して編集するときに使ってるツール

 

こんなかんじで、録画した画面操作をGIFアニメーションにしてブログに貼り付けることができます。


私のPC環境は SparkyLinux(Debian系)です。

私が録画と映像編集に使用しているツールは以下です。

上の画像も、これで作成しました。


■録画

vokoscreenNG


■映像編集

shutcut




2023年2月18日土曜日

fig は aws-cli のオプション(S3バケット名など)も補完してくれる


fig については下記URL参照


fig はコマンドの補完などしてくれる、超便利なツールです。

aws-cli も補完してくれますが、AWS_PROFILEを認識してAWSを参照し、バケット名なども補完してくれます。







2023年2月12日日曜日

pecoとrainでCloudFormationのスタックを削除してみる


rain については、下記URLを参照


~/.bashrc などに下記を記載します。

 

rmstack() {
  local stack=$(aws cloudformation describe-stacks \
  --query "Stacks[?contains(StackName,\`$1\`)].[StackName,StackStatus,Description]" \
  --output text | peco | cut -f1)
  rain rm $stack
}

こんなかんじで使います。







2023年2月6日月曜日

よく使うaws-cliは bash のalias とか function にしている

 

aws-cliを、~/.bashrcとか~/.bash_aliases などに書いて使ってます。

--profile は指定せず、環境変数(AWS_PROFILE)でプロファイルを切り替えて使ってます。


EC2関連


# instance
lsec2() {
  local filter=""
  if [ "$1" == "" ]; then
    aws ec2 describe-instances \
    --query 'Reservations[].Instances[].{name:Tags[?Key==`Name`]|[0].Value,instanceId:InstanceId,privateIp:PrivateIpAddress,publicIp:PublicIpAddress,image:ImageId,state:State.Name,sg:SecurityGroups[].GroupName|sort(@)|join(`,`,@)}' \
    --output table
  else
    aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=$1" \
    --query 'sort_by(Reservations[].Instances[].{name:Tags[?Key==`Name`]|[0].Value,instanceId:InstanceId,privateIp:PrivateIpAddress,publicIp:PublicIpAddress,image:ImageId,state:State.Name,sg:SecurityGroups[].GroupName|sort(@)|join(`,`,@)},&name)' \
    --output table
  fi
}

# tag
lsec2-tag() {
  if [ "$1" == "" ]; then
    echo "lsec2-tag <resource-id>"
    return
  fi
  aws ec2 describe-tags --filters "Name=resource-id,Values=$1" --output table
}

# security group
lssg() {
  local key='*'
  if [ "$1" != "" ]; then
    key=$1
  fi
  aws ec2 describe-security-groups \
  --filters "Name=group-name,Values=$key" \
  --query 'sort_by(SecurityGroups[].{id:GroupId, name:GroupName, vpc:VpcId, desc:Description},&name)' \
  --output table
}
lssg-rule() {
  if [ "$1" == "" ]; then
    echo "lssg-rule <security-group-id>"
    return
  fi
  local key="$1"
  aws ec2 describe-security-group-rules \
  --filters "Name=group-id,Values=$key" \
  --output table
}

# elb
alias lselb="aws elbv2 describe-load-balancers --query 'LoadBalancers[].{schme:Scheme,dns:DNSName,state:State.Code}' --output table"

lselb-tg() {
  local cond=""
  if [ "$1" != "" ]; then
    cond=$(printf '?contains(TargetGroupName,`%s`)' $1)
  fi
  aws elbv2 describe-target-groups \
  --query "TargetGroups[$cond].[TargetGroupArn,TargetGroupName]" \
  --output table
}
lselb-health() {
  while read key
  do
    state=$(aws elbv2 describe-target-health \
    --target-group-arn "$key" \
    --query 'TargetHealthDescriptions[].[TargetHealth.State]' \
    --output text)
    echo "$key $state"
  done< <(aws elbv2 describe-target-groups --query "TargetGroups[].[TargetGroupArn]" --output text)
}

# ami
rmami() {
  local ami_ids=$@

  for ami_id in $ami_ids;do
    snapshot_ids=`aws ec2 describe-images --image-ids=$ami_id \
    --query "Images[].BlockDeviceMappings[].Ebs.[SnapshotId]" \
    --output text`

    echo "deregister image $ami_id"
    aws ec2 deregister-image --image-id=$ami_id
    for snapshot_id in $snapshot_ids;do
        echo "delete snapshot $snapshot_id"
        aws ec2 delete-snapshot --snapshot-id=$snapshot_id
    done
  done
}
lsami() {
  local  key='*'
  if [ "$1" != "" ]; then
    key=$1
  fi
  aws ec2 describe-images --owner self \
  --filter "Name=name,Values=$key" \
  --query "sort_by(Images[].{name:Name,image:ImageId,date:CreationDate,state:State},&name)" \
  --output table
}

# network
lseni()
{
    aws ec2 describe-network-interfaces --query 'NetworkInterfaces[].[PrivateIpAddress,Association.PublicIp]' --output text
}

lsvpc() {
  aws ec2 describe-vpcs \
  --output text \
  --query 'Vpcs[].[CidrBlock,VpcId]'
}

lsvpc-sub() {
  aws ec2 describe-subnets \
  --output text \
  --query 'Subnets[].[AvailabilityZone,CidrBlock,SubnetId,VpcId,Tags[?Key==`Name`].Value|[0]]'
}

lsvpc-pl() {
  aws ec2 describe-managed-prefix-lists \
  --output text \
  --query 'PrefixLists[].[PrefixListId,PrefixListName]'
}



CloudWatchLogs関連


lslog(){
  local cond=""
  if [ "$1" != "" ]; then
    cond=$(printf '?contains(logGroupName,`%s`)' $1)
  fi
  aws logs describe-log-groups --query "sort_by(logGroups[$cond].{name:logGroupName,bytes:storedBytes},&name)" --output table
}
rmlog(){
  if [ $# -eq 0 ]; then
    echo "usage: rmlog <log group name>"
    return
  fi
  aws logs delete-log-group --log-group-name $1
}
taillog(){
  if [ $# -eq 0 ]; then
    echo "usage: taillog <log group name>"
    return
  fi
  aws logs tail $1 --follow --since 1h
}

CloudFormation


lsstack() {
  aws cloudformation describe-stacks \
  --query "Stacks[?contains(StackName,\`$1\`)].{StackName:StackName,StackStatus:StackStatus,Desc:Description}" \
  --output table
}
rmstack() {
  rain rm $1
}


ECS/EKS/ECR


# ecr
lsecr-repo() {
  aws ecr describe-repositories --query 'repositories[].repositoryName' --output text | tr "\t" "\n"
}

lsecr-img() {
  if [ $# -eq 0 ]; then
    echo "usage: lsecr-img <repository name>"
    return
  fi
  aws ecr list-images --repository-name $1 --query 'imageIds[].imageTag' --output text
}

rmecr-img() {
  if [ $# -eq 0 ]; then
    echo "usage: rmecr-img <repository name> <tag>"
    return
  fi
  aws ecr batch-delete-image --repository-name $1 --image-ids imageTag=$2
}

# ecs
lsecs() {
  local keyword=.
  if [ $# -ne 0 ]; then
    keyword=$1
  fi
  aws ecs list-clusters | jq -r '.clusterArns[]' | cut -d/ -f2 | grep -i $keyword | sort
}
lsecs-task() {
  if [ $# -eq 0 ]; then
    echo "usage: lsecs-task <cluster name>"
    return
  fi
  local cluster=$1
  local tasks=$(aws ecs list-tasks --cluster $cluster --query 'taskArns[]' --output text | tr "\t" " ")
  aws ecs describe-tasks --tasks $tasks --output table \
    --cluster $cluster \
    --query 'tasks[].[group,taskArn, attachments[0].details[?name==`privateIPv4Address`]|[0].value, capacityProviderName, lastStatus]'
}

# eks
lseks() {
  local keyword=.
  if [ $# -ne 0 ]; then
    keyword=$1
  fi
  aws eks list-clusters | jq -r '.clusters[]'| grep -i $keyword | sort
}


SSM


 alias lsssm='aws ssm describe-parameters --query 'Parameters[].[Name]' --output text | sort'


おまけ


上記コマンドを使用して作業している様子です。(動画)

terraformでAWS環境を構築しながら上記コマンドで構築結果を確認しています。


 

2023年2月5日日曜日

EKS(fargate)でargocdを試す環境をterraformで作ってみた

 

やりたかったこと

  • EKS(fargate)の環境でk8sを試したい。
  • 試したいk8sパッケージ
    • eso
    • metric server
    • AWS Load Balancer Controller
    • argocd
    • kubernetes dashboard
  • argocd はBitbucketと連携させてnginxをdeploy
  • AWS SSM ParameterStoreに、Bitbuket接続に使用するSSH秘密鍵を登録し、esoでk8sのsecretとして参照できるようにしたい。
  • AWS Load Balancer Controllerを使って、ALBを構築し、argocd, dashboardのGUIを見たい。
  • metric serverのhpaでpodをスケールアウトしたい。
  • 個人の学習目的なので、セキュリティはゆるくていい。


私の環境

  • SparkyLinux6.5(Debian系)
    • ssh秘密鍵(レポジトリアクセス用)
  • k8s
    • kubectl1.25.4
    • helm3.10.2
  • aws
    • aws-cli2.9.4
    • ssh秘密鍵(EC2用キーペア)
  • terraform
    • tfenv3.0.0
    • tflint0.43.0
    • terraform1.3.7


主に、下記のサイトを参考にしました。


サンプルコード


https://github.com/blue21jp/aws-sample-terraform-eks


構成


.
├── Makefile
├── README.md
├── app/
│   ├── nginx/
│   │   ├── README.md
│   │   ├── deployment.yml
│   │   ├── hpa.yaml
│   │   └── service.yml
│   └── php/
│       ├── README.md
│       ├── deployment.yml
│       ├── hpa.yaml
│       └── service.yml
├── demo_todo_k8s.org
├── global/
│   ├── backend.tf
│   ├── ip.sh
│   ├── ip_pub.sh
│   ├── locals.tf
│   ├── providers_aws.tf
│   ├── providers_localstack.tf
│   └── versions.tf
├── modules/
│   └── ec2-spot/
│       ├── main.tf
│       ├── outputs.tf
│       └── variables.tf
├── stacks_base/
│   ├── 00_check/
│   │   ├── Makefile
│   │   └── outputs.tf
│   ├── 01_network/
│   │   ├── Makefile
│   │   ├── datasources.tf
│   │   ├── main.tf
│   │   └── versions.tf
│   ├── 02_ec2_nat/
│   │   ├── Makefile
│   │   ├── datasources.tf
│   │   ├── locals.tf
│   │   └── main.tf
│   ├── Makefile
│   ├── locals_all.tf
│   ├── locals_dev.tf
│   └── locals_prd.tf
├── stacks_eks/
│   ├── 00_check/
│   │   ├── Makefile
│   │   └── outputs.tf
│   ├── 01_vpc/
│   │   ├── Makefile
│   │   ├── datasources.tf
│   │   └── main.tf
│   ├── 02_ssm/
│   │   ├── Makefile
│   │   └── main.tf
│   ├── 10_eks_cluster/
│   │   ├── Makefile
│   │   ├── aws_fargate_profile_app.tf
│   │   ├── aws_fargate_profile_kube_system.tf
│   │   ├── aws_iam_oidc.tf
│   │   ├── datasources.tf
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   └── versions.tf
│   ├── 20_k8s_alb_controller/
│   │   ├── AWSLoadBalancerController.json
│   │   ├── Makefile
│   │   ├── datasources.tf
│   │   ├── iam.tf
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   └── versions.tf
│   ├── 20_k8s_eso/
│   │   ├── Makefile
│   │   ├── datasources.tf
│   │   ├── external_secrets_policy.json
│   │   ├── iam.tf
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   └── versions.tf
│   ├── 20_k8s_metrics_server/
│   │   ├── Makefile
│   │   ├── datasources.tf
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   └── versions.tf
│   ├── 21_k8s_argocd/
│   │   ├── Makefile
│   │   ├── datasources.tf
│   │   ├── ingress.tf
│   │   ├── k8s_external_secret.yaml
│   │   ├── k8s_repo.yaml
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   ├── repo.tf
│   │   └── versions.tf
│   ├── 21_k8s_dashboard/
│   │   ├── Makefile
│   │   ├── datasources.tf
│   │   ├── ingress.tf
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   └── versions.tf
│   ├── 40_app_argocd/
│   │   ├── Makefile
│   │   ├── datasources.tf
│   │   ├── ingress.tf
│   │   ├── k8s_argo_app.yaml
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   └── versions.tf
│   ├── Makefile
│   ├── README.md
│   ├── locals_all.tf
│   └── locals_prd.tf
└── stacks_template/
    ├── 00_check/
    │   ├── Makefile
    │   └── outputs.tf
    ├── Makefile
    ├── locals_all.tf
    ├── locals_dev.tf
    ├── locals_prd.tf
    └── locals_stg.tf

こんなイメージ


この構成の説明と基本操作方法は、下記の別記事を参照。
EKS環境は、前述の別記事(DockerDesktop版)と比較して、下記を変えてます。
  • app/には、deploymentとhpa,searviceのmanifestをおいてます。移動した理由は、argocdでの見え方の違いを試したかったから。
    ちなみに、ingressをapp/に移動しなかったのは、ALBを削除しないと、EKSを破棄できないから。(make destroy で一括破棄ができなくなる)
  • app/には、nginx, phpの2種類をおいてます。phpはhpaのスケールアウト確認用です。
  • ingress nginxのかわりにAWS Load Balancer Controllerを使ってます。
  • ALBは、自分のpublic ipのみ許可するようにSecurityGroupを設定しています。
    (public ipの取得は、global/ip_pub.sh で実施)


構築


準備


bitbucket
レポジトリアクセス用のSSH秘密鍵は下記のPATHを使用します。
~/.ssh/id_rsa

awscli 
AWS用のprofile名は "sandbox" を使用します。

ec2キーペア
NATインスタンスで使用するキーペアです。"sandbox"を使用します。
節約のためにNATゲートウェイでなくNATインスタンスを使ってます。

Terraform実行


下記コマンドを実行すると、terraform applyが実行されます。
これで、AWSのEKS環境にリソース一式(vpc, eks, ssm, argocd, dashbord, etc)が構築されます。
$ make opply ENV=prd OPT="-auto-approve" -C stacks_base
$ make apply ENV=prd OPT="-auto-approve" -C stacks_eks


確認


EKSへのkubectl接続

下記コマンドで config を更新

aws eks update-kubeconfig --name eks-main --alias eks-main

EKS作成者だけアクセスできます。

EKSへのアクアセス権限設定については下記URL参照


argocdのGUI
http://<ALBのDNS>
Userは、adminです。
Passwordは下記コマンドで調べます。
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath=“{.data.password}” | base64 -d; echo

dashbordのGUI
http://<ALBのDNS>
認証を無効に設定しています。
認証画面で[スキップ]ボタンをクリックすると入れます。

app(nginx/php)のページ
http://<ALBのDNS>
nginx(welcome ページ), php(OK)が表示されます。


破棄


下記コマンドを実行するとterraform destroyが実行されます。
を実行し、リソースを全部、破棄します。
$ make destroy ENV=prd OPT="-auto^approve" -C stacks_eks
$ make destroy ENV=prd OPT="-auto-approve" -C stacks_base


おまけ


demo_todo_k8s.org に記載した手順で構築と動作確認を実施している様子を動画にしました。


この動画で実行しているコマンド(aws-cliのalias)については、下記の記事を参照












2023年1月26日木曜日

pocoで k8s の context を切り替えてみる

 

.bashrc などに下記を記述

function k8c()
{
    local env=$(kubectl config view | egrep '^- context:' -A4 | awk '($0~/name:/){print $2}' | sort | peco)
    kubectl config use-context $env
}


ターミナルにk8cと入力してENTERすると context がメニュー表示されるので、選択すると切り替わります。

starshipなど使ってプロンプトに contextを表示すると便利です。(下記URL参照)


2023年1月24日火曜日

Docker Desktop(k8s)+Localstackでargocdを試す環境をterraformで作ってみた

 

やりたかったこと

  • DokerDesktop+Localstackの環境でk8sを試したい。
  • 試したいk8sパッケージ
    • eso
    • metric server
    • ingress nginx
    • argocd
    • kubernetes dashboard
  • argocd はBitbucketと連携させてnginxをdeploy
  • LocalstackのSSM ParameterStoreに、Bitbuket接続に使用するSSH秘密鍵を登録し、esoでk8sのsecretとして参照できるようにしたい。
  • ingressを使って、argocd, dashboardのGUIを見たい。
  • metric serverのhpaでpodをスケールアウトしたい。
  • 個人の学習目的なので、セキュリティはゆるくていい。


私の環境

  • SparkyLinux6.5(Debian系)
    • ssh秘密鍵(レポジトリアクセス用)
  • k8s
    • DockerDesktop4.12.0
    • kubectl1.25.4
    • helm3.10.2
  • aws
    • localstack1.3.1.dev
    • aws-cli2.9.4
  • terraform
    • tfenv3.0.0
    • tflint0.43.0
    • terraform1.3.6


サンプルコード


https://github.com/blue21jp/aws-sample-terraform-k8s


構成


├── Makefile
├── README.md
├── app/
│   └── deployment.yml
├── demo_todo_k8s.org
├── global/
│   ├── backend.tf
│   ├── ip.sh
│   ├── locals.tf
│   ├── providers_aws.tf
│   ├── providers_localstack.tf
│   └── versions.tf
├── stacks_k8s/
│   ├── 00_check/
│   │   ├── Makefile
│   │   └── outputs.tf
│   ├── 01_aws_ssm/
│   │   ├── Makefile
│   │   └── main.tf
│   ├── 10_k8s_eso/
│   │   ├── Makefile
│   │   ├── k8s_cluster_secret_store.yaml
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   └── versions.tf
│   ├── 10_k8s_ingress_nginx/
│   │   ├── Makefile
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   └── versions.tf
│   ├── 10_k8s_metric_server/
│   │   ├── Makefile
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   └── versions.tf
│   ├── 20_k8s_argocd/
│   │   ├── Makefile
│   │   ├── k8s_argocd_external_secret.yaml
│   │   ├── k8s_repo.yaml
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   ├── repo.tf
│   │   └── versions.tf
│   ├── 20_k8s_dashboard/
│   │   ├── Makefile
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   └── versions.tf
│   ├── 40_app_argocd/
│   │   ├── Makefile
│   │   ├── k8s_app.yaml
│   │   ├── k8s_hpa.yaml
│   │   ├── k8s_ingress.yaml
│   │   ├── k8s_service.yaml
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   └── versions.tf
│   ├── Makefile
│   ├── locals_all.tf
│   └── locals_dev.tf
└── stacks_template/
    ├── 00_check/
    │   ├── Makefile
    │   └── outputs.tf
    ├── Makefile
    ├── locals_all.tf
    ├── locals_dev.tf
    ├── locals_prd.tf
    └── locals_stg.tf
こんなイメージ



この構成の説明と基本操作方法は、別記事の「awsとlocalstackを切り替えながらterraformを使いたい」を参照。
app/ には、argocdでapp(nginx)をdeployするためのmanifestを置いてます。


構築


準備


Bitbucket
レポジトリアクセス用のSSH秘密鍵は下記のPATHを使用します。
~/.ssh/id_rsa

awscli 
Localstack用のprofile名は "localstack" を使用します。

/etc/hosts
下記のホスト名を登録します。ingressに設定してGUIアクセスで使用します。
127.0.0.1 argocd.example.local
127.0.0.1 nginx.example.local
127.0.0.1 dashboard.example.local

Terraform実行


下記コマンドを実行すると、terraform applyが実行されます。
これで、Localstack+DockerDesktop環境にリソース一式(ssm, argocd, dashbord, etc)が構築されます。
$ make apply OPT="-auto-approve" -C stacks_k8s


確認


argocdのGUI
http://argocd.example.local
Userは、adminです。
Passwordは下記コマンドで調べます。
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath=“{.data.password}” | base64 -d; echo

dashbordのGUI
http://dashboard.example.local
認証を無効に設定しています。
認証画面で[スキップ]ボタンをクリックすると入れます。

app(nginx)のページ
http://nginx.example.local
nginxの welcome ページが表示されます。


破棄


argocdでdeployしたnginxを削除します。
$ kubectl delete deploy nginx-deploy

下記コマンドを実行するとterraform destroyが実行されます。
を実行し、リソースを全部、破棄します。
$ make destroy OPT="-auto-approve" -C stacks_k8s


おまけ


demo_todo_k8s.org に記載した手順で構築と動作確認を実施している様子を動画にしました。


この動画で実行しているコマンド(aws-cliのalias)については、下記の記事を参照














2023年1月21日土曜日

pecoでecsexecしてみる


ecsexec については、下記URL参照。


peco でECSタスクをメニュー表示して選択し、ecsexec してコンテナに入れるようにします。


下記を ~/.bashrc などに記述します。

ecsexec() {
  if [ $# -eq 0 ]; then
    echo "usage: ecsexec <cluster name>"
    return
  fi

  local cluster=$1
  local tasks=$(aws ecs list-tasks --cluster $cluster --query 'taskArns[]' --output text | tr "\t" " ")
  local w_task=$(aws ecs describe-tasks \
      --cluster $cluster \
      --tasks $tasks \
      --output json \
      |jq -r '.tasks[]|{group:.group,name:.containers[].name,runtimeId:.containers[].runtimeId}' \
      | jq -r -s 'map(map(.)) as $rows|$rows[]|@csv' \
      | sort \
      | peco)
  local svc=$(echo $w_task| awk -F, '{print $1}'| cut -d':' -f2| tr -d '"')
  local task=$(echo $w_task| awk -F, '{print $3}'| cut -d'-' -f1| tr -d '"')
  local container=$(echo $w_task| awk -F, '{print $2}'| tr -d '"')
  echo "*************************************************"
  echo "cluster  : $cluster"
  echo "service  : $svc"
  echo "task     : $task"
  echo "container: $container"
  echo "*************************************************"

  aws ecs execute-command \
  --cluster $cluster \
  --task $task \
  --container $container \
  --interactive --command "/bin/sh"
}


ターミナルで "ecsexec <クラスタ名>" と入力して実行すると、下図のようにECSタスクが表示されるので選択します。

メニューには、「サービス名」、「コンテナ名」、「ECSタスクのruntimeId(task-id含む)」が表示されます。




ecsexecが成功してコンテナに入ると、下図のように表示されます。





2023年1月15日日曜日

環境(awsとlocalstack)を切り替えながらterraformを使ってみた


私がterraformでやりたかったこと

  • 環境(awsとlocalstack)を切り替えながらterraformを使いたい
  • 寝る前にAWSリソース破棄して、翌日、再構築したい(節約のため)
  • 個人の学習目的なので、terraformのbackendはlocalでいい
  • 自作moduleは、好きではないが、たまに作るかもしれない
  • 環境ごとにディレクトリを作りたくない
  • 環境切り替えにwokspaceは使いたくない
  • 環境差分は変数にして、awsとlocalstackで同一コードを実行したい
  • localstack停止後はリソース消えるので、terraformも初期状態にリセットしたい


私の環境

  • SparkyLinux6.5(debian系)
  • terraform1.3.6
  • tfenv3.0.0
  • tflint0.43.0
  • awscli2.9.4
  • localstack1.3.1.dev
  • make4.3
  • aws ec2キーペア(sandbox)


サンプルコード


https://github.com/blue21jp/aws-sample-terraform


注意)

サンプルコードのEC2はキーペア(sandbox)を使用します。

このキーペアは、terraformで作成しないので、事前に用意するか、コードを修正してください。


構成


コードの構成は下記のとおり。
terraformコマンドは、Makefileに記述して実行します。
makeの使用方法については後述。
.
├── Makefile
├── README.md
├── global/
│   ├── backend.tf
│   ├── ip.sh
│   ├── locals.tf
│   ├── providers_aws.tf
│   ├── providers_localstack.tf
│   └── versions.tf
├── modules/
│   ├── ec2-spot/
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   └── ecs-fargate/
│       ├── cwl.tf
│       ├── iam.tf
│       ├── main.tf
│       └── variables.tf
├── stacks_base/
│   ├── 00_check/
│   │   ├── Makefile
│   │   └── outputs.tf
│   ├── 01_network/
│   │   ├── Makefile
│   │   ├── datasources.tf
│   │   ├── main.tf
│   │   └── versions.tf
│   ├── 02_ec2_nat/
│   │   ├── Makefile
│   │   ├── datasources.tf
│   │   ├── locals.tf
│   │   └── main.tf
│   ├── Makefile
│   ├── locals_all.tf
│   ├── locals_dev.tf
│   └── locals_prd.tf
├── stacks_demo/
│   ├── 00_check/
│   │   ├── Makefile
│   │   └── outputs.tf
│   ├── 03_ec2/
│   │   ├── Makefile
│   │   ├── datasources.tf
│   │   ├── locals.tf
│   │   ├── locals.tf.dev
│   │   ├── locals.tf.prd
│   │   └── main.tf
│   ├── 04_ecs/
│   │   ├── Makefile
│   │   ├── datasources.tf
│   │   ├── locals.tf
│   │   ├── locals.tf.dev
│   │   ├── locals.tf.prd
│   │   ├── main.tf
│   │   ├── taskdef_amzn2.json
│   │   └── taskdef_nginx.json
│   ├── Makefile
│   ├── locals_all.tf
│   ├── locals_dev.tf
│   └── locals_prd.tf
└── stacks_template/
    ├── 00_check/
    │   ├── Makefile
    │   └── outputs.tf
    ├── Makefile
    ├── locals_all.tf
    ├── locals_dev.tf
    ├── locals_prd.tf
    └── locals_stg.tf

こんなイメージ


リソース構築用のterraformコードの格納場所

modules/

  • 自作のモジュールは、modules/配下にディレクトリを作成して、そこに置きます。

stacks_xxxx/

  • 構築するリソース(vpc,ec2,etc)は、共通用、デモ用などグループ化してstacks_xxxx/ ディレクトリを作成し、そこに置きます。

stacks_xxxx/NN_xxxxx

  • stacks_xxxx/ 配下は、「数値で始まるディレクトリ」を作成して、そこにコードを格納します。この「数値で始まるディレクトリ(00_check,01_netowprk,etc)」を、ここではスタックと呼ぶことにします。
  • スタックは、ライフサイクルが同じリソースの集まりです。
  • スタックの数値の小さいものから構築すると stacks_xxxx が完成するようにします。
  • 全環境で、同一コード(スタックのコード)を実行します。

環境差分の変数を設定する場所

global/

全環境の全スタックで参照できます。

  • locals.tf・・・local.global.XXXXで参照する

stacks_xxxx/

たとえば、stacks_baseの下記ファイルに定義した変数は、stacks_base配下のスタックだけで参照できます。

  • locals_all.tf・・・全環境共通の変数。local.common_all.XXXXで参照する
  • locals_dev.tf・・・dev環境用の変数。local.common_env.XXXXで参照する
  • locals_stg.tf・・・stg環境用の変数。local.common_env.XXXXで参照する
  • lcoals_prd.tf・・・prd環境用の変数。local.common_env.XXXXで参照する
 

stacks_xxxd/NN_xxxx

たとえば、00_chackの下記ファイルに定義した変数は、00_checkだけで参照できます。

  • locals.tf.dev・・・dev環境用の変数。local.XXXXで参照する
  • locals.tf.stg・・・stg環境用の変数。local.XXXXで参照する
  • locals.tf.prd・・・prd環境用の変数。local.XXXXで参照する

terraformプラグインのキャッシュ場所

awsなどのプラグインは、「terraform init」時にダウンロードして、下記にキャッシュします。

  • ${HOME}/.teraform.d/plugin-cache

tfstateの格納場所

terraformのstateは、スタック用ディレクトリ(00_check, 01_network, etc)内に、環境ごとに作成します。

  • stacks_xxxx/NN_xxxx/tfstate.d/dev
  • stacks_xxxx/NN_xxxx/tfstate.d/stg
  • stacks_xxxx/NN_xxxx/tfstate.d/prd

プロビジョニング環境

構築する環境は3種類の前提

  • dev・・・ localstack
  • stg・・・ awsアカウント ※サンプルコードでは未使用
  • prd・・・ awsアカウント


プロビジョニング先の環境を指定する方法

locals_dev.tf, locales_stg.tf, locals_prd.tf でプロビジョニングする環境を指定します。

下記のようにして、awscliのプロファイル名と、リージョンを設定します。
env_typeは、環境を識別するための値(dev|stg|prd)を設定します。

locals {
  common_env = {
    env_type = "dev"
    profile  = "localstack"
    region   = "us-east-1"
  }
}

localstackで使用するサービスを設定する方法

global/provisers_localstack.tf で設定します。

下記のようにして使用するサービスのエンドポイントをlocalstackに向けます。

  endpoints {
    sts            = "http://${data.external.myip.result["ip"]}:4566"
    s3             = "http://${data.external.myip.result["ip"]}:4566"
    ec2            = "http://${data.external.myip.result["ip"]}:4566"
    route53        = "http://${data.external.myip.result["ip"]}:4566"
    cloudwatch     = "http://${data.external.myip.result["ip"]}:4566"
    iam            = "http://${data.external.myip.result["ip"]}:4566"
    eks            = "http://${data.external.myip.result["ip"]}:4566"
    wafregional    = "http://${data.external.myip.result["ip"]}:4566"
    wafv2          = "http://${data.external.myip.result["ip"]}:4566"
    waf            = "http://${data.external.myip.result["ip"]}:4566"
    cloudfront     = "http://${data.external.myip.result["ip"]}:4566"
    lambda         = "http://${data.external.myip.result["ip"]}:4566"
    secretsmanager = "http://${data.external.myip.result["ip"]}:4566"
    cloudformation = "http://${data.external.myip.result["ip"]}:4566"
    ssm            = "http://${data.external.myip.result["ip"]}:4566"
  }


使い方

terraformコマンドは、makeで実行します。

ここでは、特に記載がなければ、TOPディレクトリでmakeコマンドを実行します。

動作環境の確認

stacks_xxxx/00_check を使用します。このスタックは動作環境の情報を表示するだけでリソースは何もつくりません。

dev(localstack)に向ける場合

これで terraformの init, tflint, planが実行されます。

$ make plan -C stacks_base/00_check
実行前の00_checkは下記のとおり
Permissions Size User   Date Modified Name
.rw-r--r--     6 blue21 14 Jan 16:23  .terraform-version
.rw-r--r--  2.6k blue21 14 Jan 16:23  Makefile
.rw-r--r--   246 blue21 14 Jan 16:23  outputs.tf

実行後の00_checkは下記のようになります。

アンダースコアで始まるシンボリックリンク・ディレクトリは make で自動生成したものです。

Permissions Size User   Date Modified Name
drwxr-xr-x     - blue21 14 Jan 19:04  .terraform
.rw-r--r--     6 blue21 14 Jan 16:23  .terraform-version
.rw-r--r--   464 blue21 14 Jan 19:04  .terraform.lock.hcl
lrwxrwxrwx    23 blue21 14 Jan 19:04  _backend.tf -> ../../global/backend.tf
lrwxrwxrwx    16 blue21 14 Jan 19:04  _locals_all.tf -> ../locals_all.tf
lrwxrwxrwx    16 blue21 14 Jan 19:04  _locals_env.tf -> ../locals_dev.tf
lrwxrwxrwx    22 blue21 14 Jan 19:04  _locals_global.tf -> ../../global/locals.tf
lrwxrwxrwx    36 blue21 14 Jan 19:04  _providers.tf -> ../../global/providers_localstack.tf
drwxr-xr-x     - blue21 14 Jan 19:04  _tfstate.d
lrwxrwxrwx    24 blue21 14 Jan 19:04  _versions.tf -> ../../global/versions.tf
.rw-r--r--  2.6k blue21 14 Jan 16:23  Makefile
.rw-r--r--   246 blue21 14 Jan 16:23  outputs.tf

prd(aws)に向ける場合

ENVで環境を指定します。(dev|stg|prd)

$ make plan ENV=prd -C stacks_base/00_check
シンボリックリンク先は prd 用に変わります。
ermissions Size User   Date Modified Name
drwxr-xr-x     - blue21 14 Jan 19:07  .terraform
.rw-r--r--     6 blue21 14 Jan 16:23  .terraform-version
.rw-r--r--   464 blue21 14 Jan 19:04  .terraform.lock.hcl
lrwxrwxrwx    23 blue21 14 Jan 19:07  _backend.tf -> ../../global/backend.tf
lrwxrwxrwx    16 blue21 14 Jan 19:07  _locals_all.tf -> ../locals_all.tf
lrwxrwxrwx    16 blue21 14 Jan 19:07  _locals_env.tf -> ../locals_prd.tf
lrwxrwxrwx    22 blue21 14 Jan 19:07  _locals_global.tf -> ../../global/locals.tf
lrwxrwxrwx    29 blue21 14 Jan 19:07  _providers.tf -> ../../global/providers_aws.tf
drwxr-xr-x     - blue21 14 Jan 19:07  _tfstate.d
lrwxrwxrwx    24 blue21 14 Jan 19:07  _versions.tf -> ../../global/versions.tf
.rw-r--r--  2.6k blue21 14 Jan 16:23  Makefile
.rw-r--r--   246 blue21 14 Jan 16:23  outputs.tf

スタックのapply

例として、stacks_base/01_network を使用します。

このスタックはVPC,Subnetを作成します。

dev(localstack)に向ける場合

$ make apply -C stacks_base/01_network

prd(aws)に向ける場合

$ make apply ENV=prd -C stacks_base/01_network

ちなみに、terraform apply に引数を追加したい場合は下記のようにします。

$ make apply ENV=prd OPT="-auto-approve" -C stacks_base/01_network

また、stacks_baseのスタックを一括でapplyしたい場合は以下のようにします。

$ make apply ENV=prd OPT="-auto-approve" -C stacks_base


スタックのdesttroy

例として、stacks_base/01_network を使用します。

使用方法は apply と同じです。

dev(localstack)に向ける場合

$ make destroy -C stacks_base/01_network

prd(aws)に向ける場合

$ make destroy ENV=prd -C stacks_base/01_network


初期化

localstack, awsのリソースを全部destroyしたあとに、下記を実行すると、tfstateやmakeが自動生成したシンボリックリンクを削除して初期状態に戻します。

$ make clean ENV=prd -C stacks_base/01_network


その他

  • make list -C stacks_xxxx/NN_xxxx
    tarraform state list を実行します。

  • make outputs -C stacks_xxxx/NN_xxxx
    terraform output を実行します。

  • make mv OPT="xxxx yyyy" -C stacks_xxxx/NN_xxxx
    terraform state mv $OPT を実行します。

  • make rm OPT="xxx" -C stacks_xxxx/NN_xxxx
    terraform state rm $OPT を実行します。

  • make import OPT="xxx yyyy" -C stacks_xxxx/NN_xxxx
    terrafprm import $OPT を実行します。


おまけ

サンプルコードを使って、demo_todo.orgの手順で実施した構築作業を動画にしました。


この動画で実行しているコマンド(aws-cliのalias)については、下記の記事を参照







2023年1月8日日曜日

pecoでawscliのprofileを切り替える


peco は、「brew install peco」などとするとインストールできます。


~/.bashrcなどに下記を記述します。

alias awsa='aws sts get-caller-identity'

export AWS_PROFILE='sandbox'
function awsp()
{
    export AWS_PROFILE=$(egrep '^\[profile' ~/.aws/config | cut -d" " -f2 | tr -d ']' | peco)
}


ターミナルで"awsp"と入力して実行すると、下図のように awscliのprofileを選択するメニューが表示されるので、profileを選択すると環境変数のAWS_PROFILEに選択したprofileが設定されます。


starshipなど使用してターミナルのプロンプトにAWS_PROFILEを表示するようにしておくと便利です。


また、ターミナルで"awsa"と入力して実行すると、アカウントIDを確認できます。