AWSメモ(追加中)
cloud initのデバック
ECSの初期起動時のユーザーデータ(User Data)のデバックには以下のログを利用する。
/var/log/cloud-init-output.log
AWSのEC2のインスタンスメタデータについて
インスタンスメタデータとは
インスタンスメタデータは、インスタンスに関するデータで、実行中のインスタンスを設定または管理するために使用します。
取得方法
curlコマンドで取得
[ec2-user@ip-XX-X-X-115 XX~]$ curl http://169.254.169.254/latest/meta-data ami-id ami-launch-index ami-manifest-path block-device-mapping/ events/ hibernation/ hostname identity-credentials/ instance-action instance-id instance-life-cycle instance-type local-hostname local-ipv4 mac metrics/ network/ placement/ profile public-hostname public-ipv4 public-keys/ reservation-id security-groups
ami-idを取得したい場合は、
[ec2-user@ip-XX-X-X-115 XX~]$ curl http://169.254.169.254/latest/meta-data/ami-id ami-0ce107ae7af2e92b5
ec2-metadataコマンドで取得
[ec2-user@ip-XX-X-X-115 XX~]$ ec2-metadata --help ec2-metadata v0.1.2 Use to retrieve EC2 instance metadata from within a running EC2 instance. e.g. to retrieve instance id: ec2-metadata -i to retrieve ami id: ec2-metadata -a to get help: ec2-metadata --help For more information on Amazon EC2 instance meta-data, refer to the documentation at http://docs.amazonwebservices.com/AWSEC2/2008-05-05/DeveloperGuide/AESDG-chapter-instancedata.html Usage: ec2-metadata <option> Options: --all Show all metadata information for this host (also default). -a/--ami-id The AMI ID used to launch this instance -l/--ami-launch-index The index of this instance in the reservation (per AMI). -m/--ami-manifest-path The manifest path of the AMI with which the instance was launched. -n/--ancestor-ami-ids The AMI IDs of any instances that were rebundled to create this AMI. -b/--block-device-mapping Defines native device names to use when exposing virtual devices. -i/--instance-id The ID of this instance -t/--instance-type The type of instance to launch. For more information, see Instance Types. -h/--local-hostname The local hostname of the instance. -o/--local-ipv4 Public IP address if launched with direct addressing; private IP address if launched with public addressing. -k/--kernel-id The ID of the kernel launched with this instance, if applicable. -z/--availability-zone The availability zone in which the instance launched. Same as placement -c/--product-codes Product codes associated with this instance. -p/--public-hostname The public hostname of the instance. -v/--public-ipv4 NATted public IP Address -u/--public-keys Public keys. Only available if supplied at instance launch time -r/--ramdisk-id The ID of the RAM disk launched with this instance, if applicable. -e/--reservation-id ID of the reservation. -s/--security-groups Names of the security groups the instance is launched in. Only available if supplied at instance launch time -d/--user-data User-supplied data.Only available if supplied at instance launch time.
ami-idを取得したい場合は、
[ec2-user@ip-XX-X-X-115 XX~]$ ec2-metadata -a ami-id: ami-0ce107ae7af2e92b5
curlコマンドとec2-metadataの使い分け
curlコマンドは値だけ取得できるのでプログラムで利用するのに向いている。
ec2-metadataコマンドはデータのkeyも取得されるので、プログラムで利用する場合は不便。
ただ、ec2-metadata --all
なので、値を確認するのに便利。
なので、
- curlコマンド ・・・プログラムで利用
- ec2-metadataコマンド・・・EC2の情報を確認するのに使用
パーミッションについて
パーミッション
ファイルの実行権限のこと。
どの種類のオーナーが、このファイルに対して何ができるのか。
以下のコマンドで確認することができる。
ls -la
パーミッションは以下のように9桁で表示される。
-rwxrwxrwx 1 root root
権限 | 説明 |
---|---|
r | Read 読み込み権限 |
w | Write 書き込み権限 |
x | Execute 実行権限 |
- | 権限なし |
パーミッションの変更
パーミッション変更時は、「読み込み」「書き込み」「実行可能」を3ビットの2進数で表し、8進数へ変換したものを利用します。
8進数 | 権限 |
---|---|
1 | --x |
2 | -w- |
3 | -wx |
4 | r-- |
5 | r-x |
6 | rw- |
7 | rwx |
フル権限である-rwxrwxrwx
にする場合は、以下を実行する。
chmod 777 ファイル名
所有者が読み取りのみできる-r-------
のようにするには、以下を実行する。
chmod 400 ファイル名
Laravel Passportをやってみるメモ
Laravel Passportを利用した場合のメモ。
ライブラリインストール。
$ composer require laravel/passport
マイグレーションを実行。
$ php artisan migrate Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (83.67ms) Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table (55.75ms) Migrating: 2016_06_01_000001_create_oauth_auth_codes_table Migrated: 2016_06_01_000001_create_oauth_auth_codes_table (68.58ms) Migrating: 2016_06_01_000002_create_oauth_access_tokens_table Migrated: 2016_06_01_000002_create_oauth_access_tokens_table (103.69ms) Migrating: 2016_06_01_000003_create_oauth_refresh_tokens_table Migrated: 2016_06_01_000003_create_oauth_refresh_tokens_table (119.95ms) Migrating: 2016_06_01_000004_create_oauth_clients_table Migrated: 2016_06_01_000004_create_oauth_clients_table (73.17ms) Migrating: 2016_06_01_000005_create_oauth_personal_access_clients_table Migrated: 2016_06_01_000005_create_oauth_personal_access_clients_table (37.69ms) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (58.61ms)
安全なアクセストークンを生成するのに必要な暗号キーを作成します。
さらにアクセストークンを生成するために使用する、「パーソナルアクセス」クライアントと「パスワードグラント」クライアントも作成します。
Clientはユーザではなくアクセストークンを利用するアプリケーションのこと。
生成された情報はoauth_clients
テーブルに保存されます。
$ php artisan passport:install Personal access client created successfully. Client ID: 1 Client secret: Pn1hA2F8ngjZwPxcmYb3aZ9CqqRRM9zWJNwPtNqZ Password grant client created successfully. Client ID: 2 Client secret: hDdQbSAX484FRtCQpHafotaMEfBv0ryuWCn7kvUN
Personal access clientとPassword grant clientが作成されます。
Laravel標準のusersテーブルをPassport認証に使用する。
◎ app/Models/User.php
<?php namespace App\Models; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Passport\HasApiTokens; // 追加 class User extends Authenticatable { use HasFactory; use Notifiable; use HasApiTokens; // 追加 ... }
◎ app/Providers/AppServiceProvider.php
<?php namespace App\Providers; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; use Illuminate\Support\Facades\Gate; use Laravel\Passport\Passport; class AuthServiceProvider extends ServiceProvider { /** * アプリケーションのポリシーのマップ * * @var array */ protected $policies = [ 'App\Models\Model' => 'App\Policies\ModelPolicy', ]; /** * 全認証/認可サービスの登録 * * @return void */ public function boot() { $this->registerPolicies(); Passport::routes(); } }
Passport::routes()
を追加したあと、`php artisan route:list
をするとルーティングが追加されている。
テストユーザーを作成
Seederを作成。
◎ database/seeders/UsersTabaleSeeder.php
<?php namespace Database\Seeders; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; class UsersTabaleSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { $param = [ 'name' => 'taro', 'email' => 'taro@example.com', 'password' => Hash::make('test') ]; DB::table('users') -> insert($param); } }
database/seeders/DatabaseSeeder.php
にも以下を追加。
public function run() { $this->call(UsersTabaleSeeder::class); }
php artisan db:seed
を実行。
リクエストしてみる(Personal Access Token)
とりあえず、いきなりtokenが発行されるPersonal Access Token
で試してみます。
routers/api
に以下を追加。
Route::get('/test', function(){ $user = App\Models\User::find(1); $token = $user->createToken('')->accessToken; return response()->json(['token' => $token]); });
Bearer tokenが発行される。
{ "token": "eyJ0eXAiOiJKV1QiL..." }
リクエストヘッダーにAuthorization : Bearer eyJ0eXAiOiJKV1QiL...
をつけて、
http://localhost/api/userを実行。
user情報が返却される。
{ "id": 1, "name": "taro", "email": "taro@example.com", "email_verified_at": null, "created_at": null, "updated_at": null }
リクエストしてみる(Password Grant Token)
パスワードを送信してTokenが発行される、よくある認証方式です。
php artisan passport:install
で作成したPassword grant client
を利用します。
認可サーバhttp://localhot/oauth/token
(Laravel)に POSTリクエストを送信します。
リクエストパラメータはこちら。
{ "grant_type": "password", "client_id": "2", "client_secret": "hDdQbSAX484FRtCQpHafotaMEfBv0ryuWCn7kvUN", "username": "taro@example.com", "password": "test", "scope": "" }
アクセストークンが返却される。
{ "token_type": "Bearer", "expires_in": 31536000, "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..." }
リクエストヘッダーにAuthorization : Bearer eyJ0eXAiOiJKV1QiL...
をつけて、
http://localhost/api/userを実行。
user情報が返却される。
{ "id": 1, "name": "taro", "email": "taro@example.com", "email_verified_at": null, "created_at": null, "updated_at": null }
続く ...
composer require実行時にAllowed memory size of 1610612736 bytes exhausted エラーが発生する
composer require実行時に以下のエラーが発生。
Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes)
memory_limitの設定値を確認。
$ php -r "echo ini_get('memory_limit').PHP_EOL;" 128M
php.iniの場所を確認する。
$ php -i | grep php.ini Configuration File (php.ini) Path => /usr/local/etc/php/7.4 Loaded Configuration File => /usr/local/etc/php/7.4/php.ini
php.iniを編集。
$ vi /usr/local/etc/php/7.4/php.ini ; memory_limit = 128M memory_limit = -1 ←こちらに変更
取りあえずの対処の場合
とりあえずで良い場合の以下のコマンドできるようでした。
$ COMPOSER_MEMORY_LIMIT=-1 composer require xxxx/xxxx
CodeDeployと CodePipelineを使ってEC2に自動デプロイのメモ
自動でEC2にソースをデプロイにチャレンジです。
次回やるときの為ののメモです。
自動デプロイの流れ
違うかもしれませんが、やりたいことはこんなイメージです。
- githubにpush
- CodePipelineをが起動
- codeDeployがEC2にpush
EC2の設定
CodeDeploy エージェントをインストールする
そのままではCodeDeployからEC2が操作できないのでAgentを追加する必要がある。
Amazon Linux 用または RHEL 用の CodeDeploy エージェントをインストールする - AWS CodeDeploy
$ sudo yum update $ sudo yum install ruby $ sudo yum install wget $ cd /home/ec2-user // アジアパシフィック (東京)の場合 // wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install $ wget https://{bucket-name}.s3.{region-identifier}.amazonaws.com/latest/install $ chmod +x ./install $ sudo ./install auto
サービスが正しく実行されているかは以下のコマンドで確認。
$ sudo service codedeploy-agent status
実行されていない場合、デプロイ時に以下のようなエラーが発生する。
The overall deployment failed because too many individual instances failed deployment, too few healthy instances are available for deployment, or some instances in your deployment group are experiencing problems.
クライアント側の設定
CodeDeployにはappspec.yml
が必要で、同期させるファイルのルートに配置する必要がある。
version: 0.0 os: linux files: - source: /index.html destination: /var/www/html/ hooks: BeforeInstall: - location: scripts/install_dependencies timeout: 300 runas: root - location: scripts/start_server timeout: 300 runas: root ApplicationStop: - location: scripts/stop_server timeout: 300 runas: root
- files
- source : 同期元
- destination : 同期先
- hooks
- BeforeInstall(例) : イベント名
- location : イベントで実行するファイル(場所)
- timeout : 実行時間
- runas : ユーザー
- BeforeInstall(例) : イベント名
scripts/install_dependencies
apacheをインストールする。
#!/bin/bash yum install -y httpd
scripts/start_server
apacheを起動する。
#!/bin/bash service httpd start
scripts/stop_server
apacheを停止する。
#!/bin/bash isExistApp=`pgrep httpd` if [[ -n $isExistApp ]]; then service httpd stop fi
イベントフック
デプロイは アプリケーションの停止 アプリケーションファイルのダウンロード アプリケーションファイルのインストール アプリケーションの起動 という順で実行され、 次のデプロイライフサイクル図において、オレンジ背景の箇所が実際にフック処理を割り込めるイベントです。
※ ApplicationStopは2回目のデプロイ移行実行される
CodeDeployの設定
アプリケーションとデプロイグループを作成
CodeDeploy > アプリケーション > 「アプリケーションの作成」ボタンを押す。
アプリケーション名を入力して、コンピューティングプラットフォームに「EC2/オンプレミス」を選択。
デプロイグループを作成する。
githubを接続
CodeDeploy > アプリケーション > codedeploy-test > codedeploy-group-test > 「デプロイ作成」を押す。
必要項目を入力する。
デプロイする。
CodePipelineの設定
CodePipeline > パイプライン > 「パイプラインを作成する」ボタンを押す。
パイプラインの設定
「パイプライン名」を入力。
ソースステージを追加する
ソースプロバイダーに「Github」。 リポジトリ、ブランチに対象のものを設定。
ビルドステージを追加する
Dockerイメージを作成する必要がある場合や、javaなどのコンパイル言語の場合に利用します。
phpやrubyのソースを配置するだけであれば、ビルドが必要ないのでスキップします、
デプロイステージを追加する
デプロイプロバイダーはCodeDeployを選択。
その他の項目もCodeDeployで作成したものを設定する。
パイプラインを作成
codepipelineが作成されて、デプロイが実行されます。
CodePipelineを利用する場合はEC2にS3にアクセスする権限を与える必要があります。
権限がない場合は以下のようなエラーが発生します。
S3への権限を追加する。
クロスドメインでBasic認証を自動ログインさせるメモ
あまり無いと思いますが、クロスドメインでベーシック認証をする必要があったので、
忘れないようにメモしておきます。
仕組みとしては以下のイメージ。
- クライアント(表示元)にiframeを埋める。
- iframeのsrcにベーシック認証先のサーバーに配置したcgiファイルを指定する
- cgiでクライアント(表示元)のjsを呼び出す。
- クライアント(表示元)のjsでベーシック認証を行う。
※ 手順3のcgiでベーシック認証を行っても良いかも
CGIを追加
/etc/httpd/conf/httpd.conf
に以下を追加。
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" <Directory "/var/www/cgi-bin"> AllowOverride None Options None Order allow,deny Allow from all </Directory>
/var/www/cgi-bin
にcgiファイルを配置。
vi /var/www/cgi-bin/authentication.cgi
中身はこんな感じ。
#!/usr/bin/perl -- print "Content-type: text/html\n\n"; print "<html><head>\n"; print "<script type=\"text/javascript\" src=\"http://hoge.co.jp/authentication.js\"></script>\n"; print "</head></html>\n"; exit;
該当のcgiファイルの権限を変更。
chmod 755 authentication.cgi
クライアント(http://hoge.co.jp)にjsフィアルを用意。 ベーシック認証用のスクリプトを用意する。 ※第3引数のasyncはtrue (非同期) or false (同期)は要件によって。
(function () { const xhr = new XMLHttpRequest() xhr.open("GET", "http://fuga.com", false, "user", "password") xhr.send(null); }());
ただし、上記だと通信内容にログイン情報が出てしまうので、リクエストヘッダーのAuthorization
を利用することで少し隠蔽することができます。
(function() { const xhr = new XMLHttpRequest() const authorizationBasic = window.btoa('user' + ':' + 'password') xhr.open('GET', 'http://fuga.com"', false) xhr.setRequestHeader('Authorization', 'Basic ' + authorizationBasic) xhr.send(null) })()