AWS入門記録(できるだけテキストベースの資料、論より動いているもの)
前提
- 特定の誰か向けではなく、自分が理解するまでの記録です
- 資格の習得は目的にしていません
- AWSを仕事でちょっと触ったが、0ベースで始動する際の設定が理解できていない前提です
- 仕事でEC2インスタンスにゴニョゴニョアクセスした程度でAWS経験あります、と言いたくない
- macOS(Apple Silicon)前提
- 資料はできるだけテキストベースで理解したい
- 初心者向けは動画の方が多いが、読んだ方が早く理解できるため
- とにかく動かしているという実感を得たい、IaCできるならIaCすることを前提にしたい
- 仮の最終目的は超基礎的なサービス+フロントエンド向けのサービス(AWS Amplify等)
AWSアカウント開設とロールアカウント作成
AWSアカウントを0から開設。過去に使ったメールアドレスだとダメだったのでAWS学習用のGmailを取得した。
普段使い用のアカウントを作成。ルートアカウントじゃなくてログイン用のアカウントを作成。
ログイン用アカウントが作成されると、Invitation to join AWS IAM Identity Center (successor to AWS Single Sign-On)
というメールが来るので、そのリンクからパスワード設定、ログインを行う。
AWS CLI設定
AWS CLI v2 Apple Silicon向け設定(注意点あり)
公式通り入れたい…のだが、公式のインストーラーだとAWS CLI v2のApple Silicon向け(ARM64)ビルドをインストールする手順が少々面倒らしい。
ビルドすればできないことはないらしいが、流石に面倒臭い。
コマンドを使ってみて、正直どちらでも問題なさそうとは思うが、自分はHomebrew経由で入れた。
$ brew install awscli
公式のGUIインストーラーとHomebrewで入れた際の違いは source/arm64
の箇所。
# from Homebrew
$ aws --version
aws-cli/2.13.32 Python/3.11.6 Darwin/23.0.0 source/arm64 prompt/off
# from GUI installer
$ aws --version
aws-cli/2.13.32 Python/3.11.6 Darwin/23.0.0 exe/x86_64 prompt/off
AWS CLIインストール完了後、AWS管理コンソールにてCommand line or programmatic access
をクリックするとAWSの認証情報が表示される。
aws configure sso
コマンドで設定していく。 最後に聞かれるCLI profile name
は毎回打つことになるので自分で打ちやすいものにする。
CLI profile name [***]: my-dev-profile
設定ができたか確認する。アカウント作りたてで何もしていない場合、下記のコマンド実行結果は何も出力されない。
$ aws s3 ls --profile my-dev-profile
毎度--profile
を聞かれるのが面倒な場合は、CLI profile name
にてdefault
と入力するか、~/.aws/config
にて設定を書き換える。
-[profile my-dev-profile]
+[default]
sso_session = my-sso
設定ができると--profile
なしで[default]の設定が使われる。
$ aws s3 ls
AWS CLIの挙動確認
公式通り確認する。ただし現時点の日本語ガイドの手順だけだとエラーが起きることがある。
これはaws configure sso
で認証する方法が紹介されていないため。
英語版では解決しているので、翻訳待ちかと思われる。(フィードバックは送信済み)
エラーが起きた場合は下記のように対処する。
エラー(AuthFailure)
$ aws ec2 describe-vpcs
An error occurred (AuthFailure) when calling the DescribeVpcs operation: AWS was not able to validate the provided access credentials
aws configure
で対話的に設定したため、aws_session_tokenの設定がされていないと思われる。
対応は間違って入力された~/.aws/credentials
と ~/.aws/config
の中身を削除後、aws configure sso
で設定しなおす。
エラー(RequestExpired)
$ aws ec2 describe-vpcs
An error occurred (RequestExpired) when calling the DescribeVpcs operation: Request has expired.
そもそもとして、環境変数でexportするか、または~/.aws/credentials
にて手動で書き込む設定は、短期的な認証設定であるため、認証が切れてしまう。
対応は同じく、aws configure sso
の方が推奨であるため、そちらで設定する。
EC2の起動とAWS CLIでの確認
EC2起動はチュートリアル通りに管理画面から作成、EC2 Instance Connect、終了を経験しておく。
EC2インスタンスについて実感がつかめたら、CLIでもやってみる。
自分が建てたEC2インスタンスについて確認する。そのまま出力すると大量に表示されるので、表示を絞ることも可能。
# 終了後はqキーで抜ける
$ aws ec2 describe-instances
# instance idのみ
$ aws ec2 describe-instances --query "Reservations[].Instances[].InstanceId"
AWS CLIでのEC2の起動と終了
EC2インスタンスを起動する。先ほどと同じような条件で起動する。
$ aws ec2 run-instances --image-id ami-098940df4d3292e9a --instance-type t2.micro
※余談だがCLI経由での起動時、インスタンス種別を指定しない場合m1.small
でインスタンスが起動した。
起動完了後、EC2の管理画面にて、インスタンスが起動している旨が確認できる。
EC2インスタンスは削除されるまで使用料が発生するので、確認が済んだら「終了」を行う。
(誤解しやすいが、停止と終了は違う状態なので注意する)
管理画面でインスタンスのIDを確認して実行する。i-XXXXXXは自分のインスタンスに読み替えてください。
$ aws ec2 terminate-instances --instance-ids i-XXXXXX
完了後、管理画面で「インスタンスの状態」が「終了済み」になっていることを確認する。
課金回避のため、全てのリージョンでEC2が停止していることを確認する
慣れていない内は複数のリージョンでEC2を立てっぱなしにしてしまうことがあるので、Amazon EC2 グローバルビューで起動しているインスタンスがないか確認しておく。
AWS CDKを使ってみる
AWS CDK CLI設定
AWS CDK CLIはnpm経由でインストールする。自分はpnpmを使っているのでpnpm i -g aws-cdk
でインストール。
正常にインストールできると下記のような表示になる。
$ pnpm i -g aws-cdk
$ cdk --version
2.104.0 (build 3b99abe)
個人的なハマりどころ
cdk bootstrap aws://ACCOUNT-NUMBER/REGION
時
特にポリシーを指定しない場合、アカウントはAdministratorAccess
を用いる必要がある
PowerUserAccess
でも良さそうと思えたが、IAMのロール作成も行われるため、これではエラーが出る
Using default execution policy of 'arn:aws:iam::aws:policy/AdministratorAccess'. Pass '--cloudformation-execution-policies' to customize.
aws configure sso
にて設定されたRoleがsso_role_name = AdministratorAccess
であるか確認する
間違っている場合は再設定を行う
途中で失敗した時は作成されたS3バケットとCloudFormationを削除する
S3バケットはcdk-
で始まるもの。CloudFormationはスタック名がCDKToolkit
のスタック。
CDKのリージョン設定はAWS CLIで設定しているのと同じにしておく
チュートリアル上ではus-east-1 か eu-west-1にすると記載があるが、失敗したので、cdk bootstrapで設定した東京リージョン設定だとうまくいった。
const app = new cdk.App();
new CdkDemoStack(app, 'CdkDemoStack', {
env: { account: 'ACCOUNT-NUMBER', region: 'ap-northeast-1' },
});
余談
AdministratorAccess
はかなり強い権限であり、日常遣いするには強すぎるのでせめてPowerUserAccess
でできないか考慮する
AWS CDK でEC2インスタンスを立ててみる
チュートリアルから発展して、とりあえずEC2インスタンスをCDKで定義してみる。
$ mkdir cdk-demo
$ cd cdk-demo
$ cdk init --language typescript
YOUR_ACCOUNT_NUMBER
は自分のアカウントナンバーに読み替えてください。
#!/usr/bin/env node
import 'source-map-support/register'
import { App } from 'aws-cdk-lib'
import { CdkDemoStack } from '../lib/cdk-demo-stack'
const app = new App()
new CdkDemoStack(app, 'CdkDemoStack', {
env: { account: 'YOUR_ACCOUNT_NUMBER', region: 'ap-northeast-1' },
})
PrivateなVPCとEC2インスタンスを定義する。
import {Stack, StackProps} from 'aws-cdk-lib'
import { Construct } from 'constructs'
import * as ec2 from 'aws-cdk-lib/aws-ec2'
export class CdkDemoStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props)
const vpc = new ec2.Vpc(this, `demo-VPC`, {
subnetConfiguration: [
{
cidrMask: 24,
name: 'private-subnet',
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
},
],
})
new ec2.Instance(this, `demo-EC2`, {
instanceType: ec2.InstanceType.of(
ec2.InstanceClass.T2,
ec2.InstanceSize.NANO
),
machineImage: new ec2.AmazonLinuxImage({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
}),
vpc: vpc,
})
}
}
new ec2.Vpc
がVPCを定義しているコード。今回は外部向けに後悔するわけではないのでPrivateなサブネットを定義。
new ec2.Instance
がEC2がインスタンスを定義しているコード。インスタンスのタイプやインスタンスのAMI、VPCをPropsとして渡す必要がある。
ec2.InstanceType.of
にてマシンのサイズとクラスを定義できる。ここで存在しないタイプを定義すると、デプロイ時にエラーになる。
環境のデプロイ
定義ができたらデプロイする。途中でYes/Noで聞かれるのでyで実行。
$ cdk deploy
デプロイできたらコンソール画面で下記が作成されていることが確認できる。
- EC2インスタンス
CdkDemoStack/demo-EC2
- VPC
CdkDemoStack/demo-VPC
環境とコードの差分チェック
現在デプロイされている環境と、定義しているコードの差を確認するためのコマンドがある。試しにインスタンスのタイプを変えてみる。
instanceType: ec2.InstanceType.of(
ec2.InstanceClass.T2,
- ec2.InstanceSize.NANO
+ ec2.InstanceSize.SMALL
),
この状態で差分を確認してみる。コードの変更箇所とデプロイされている差分が出力される。
$ cdk diff
Stack CdkDemoStack
Resources
[~] AWS::EC2::Instance demo-EC2 demoEC2ADA90D49 may be replaced
└─ [~] InstanceType (may cause replacement)
├─ [-] t2.nano
└─ [+] t2.small
✨ Number of stacks with differences: 1
環境を更新するには再度デプロイします。デプロイ後、インスタンスタイプがt2.small
であることを確認できます。
$ cdk deploy
環境の破棄
一通り学習が終わったら環境を破棄してお片付けします。途中でYes/Noで聞かれるのでyで実行。
今回の場合は定義したVPC、EC2インスタンスが破棄されます。
$ cdk destroy
CDKコマンド実行時には自動的にtscされる
TypeScriptに慣れ親しんだ人ならcdkコマンドを打つ前にコンパイルしないの?と疑問に思われたかもしれないが、AWS CDKでは自動的にTypeScript→JavaScriptのコンパイルを自動で行ってくれる模様。tscは型チェックを手動を行うためにある模様。
The AWS CDK automatically does this whenever it needs to run your app.
CDK参考例
CDKのテスト
CDKで定義したリソースがCloudformationのテンプレートに変換されるので、その値が想定通りになっているかをテストする。
とはいえ初見だと実際にどんなテンプレートが吐き出されているかわからないのでconsole.log(template.toJSON())
で中身を見てみるとどんなテストが書けるかわかってくる。
CDKのテスト用にaws-cdk-lib/assertions
があり、テンプレートにどんな値があるか確認できる。
import * as cdk from "aws-cdk-lib";
import { Template } from "aws-cdk-lib/assertions";
import * as CdkDemo from "../lib/cdk-demo-stack";
test("VPC, EC2 instance Created", () => {
const app = new cdk.App();
const stack = new CdkDemo.CdkDemoStack(app, "MyTestStack");
const template = Template.fromStack(stack);
// 実際にどんな形で出力されるのか確認できる
console.log(template.toJSON())
// 出力されたテンプレートが前回のスナップショットから変更点がないか
expect(template.toJSON()).toMatchSnapshot();
// VPCが1件作成されている
template.resourceCountIs("AWS::EC2::VPC", 1);
// EC2インスタンスが1件作成されている
template.resourceCountIs("AWS::EC2::Instance", 1);
// EC2インスタンスのタイプは"t2.nano"である
template.hasResourceProperties("AWS::EC2::Instance", {
"InstanceType": "t2.nano",
});
});
CIと組み合わせれば想定外のインスタンスが作られて重課金される、無駄なリソースを定義していないか、確認ができそう。
余談
TypeScriptのCDKが独自の継承クラスベースの設計なのも癖が強いが、テストのモジュールも独自のやり方を強いる点でだいぶ癖が強いと思います