AWS認定DevOpsエンジニア-プロフェッショナルに合格しました
本日、AWS認定資格 DevOpsエンジニア-プロフェッショナル
に合格しました。
今年の2月にAWS認定資格を取ろうと決心。コツコツと1個ずつ取得していきました。
(資格もアウトプットですね)
- AWS認定 ソリューションアーキテクト – アソシエイト (03/22)
- AWS認定 SysOps アドミニストレーター – アソシエイト (04/24)
- AWS認定 デベロッパー – アソシエイト (05/10)
- AWS認定 ソリューションアーキテクト – プロフェッショナル (06/30)
- AWS認定 DevOps エンジニア – プロフェッショナル (8/30)
これで5冠達成です。
自分はソフトウェア開発者なので、今回の DevOpsエンジニア – プロフェッショナル
が、やはり1番嬉しいです。
資格を取得してよかったこと
資格を取得する過程で、体系的に勉強できたことが一番です。
例えば、IAMのロールやポリシー、Security Token Service(STS)に関して。
Amazon Cognitoの認証の仕組みがイマイチわからなかったのですが、STSを理解すれば仕組みが理解できます。
つらかったこと
本試験、模擬試験、全て実費だったので金銭的につらかったです。。。
妻にはAmazon
で何か買ったと思われていますし。
ここからがスタートライン
認定資格を受けて感じたことは、少し古臭いと感じたことです。
当たり前ですが、クラウドは日々進化しています。
出来なかったことが出来るようになったり、新しいサービスが出てクラウドパターンが通用しなくなったり。
資格を取得したから終わり、ではありません。
AWS関連のニュースを日々キャッチアップして、知識をアップデートしていく必要があります。
そういった意味で、ここからがスタートラインです。
これからやりたいこと
サーバーレスアーキテクチャに興味があります。
また、以下のサービスが気になるので、ちょっとずつ勉強していこうかと思います。
- Amazon API Gateway
- AWS AppSync
- Amazon EKS
- Code兄弟
- AWS Cloud9
Elastic BeanstalkのサンプルアプリでBlue/Greenデプロイを試す
Elastic Beanstalkにはデプロイ方式がいくつかあります。
今回は、ダウンタイム無しのURL Swap
による環境の切り替えを試してみます。
サンプルアプリ
サンプルアプリは、Amazon Elastic Beanstalk を使用したアプリケーションの起動 で利用しているPHPアプリを利用します。
公式サイトから http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/samples/php-v1.zip をダウンロードします。
ファイル構成
解凍してファイルの中身を確認します。
$ unzip php-v1.zip -d php-v1 $ tree -a php-v1 php-v1 ├── .ebextensions │ └── logging.config ├── cron.yaml ├── index.php ├── logo_aws_reduced.gif ├── scheduled.php └── styles.css
設定ファイル用の .ebextensions
という隠しフォルダがあります。アップロードする時は含める必要があるので注意しましょう。
1つめの環境作成
サービス [コンピューティング] - [Elastic Beanstalk] を選択。 [新しいアプリケーションの作成]ボタン をクリックします。
アプリケーションの作成
アプリケーション名を入力して、[作成]ボタンをクリックします。
環境の作成
[アクション]-[環境の作成]をクリックします。
環境枠の選択でウェブサーバー環境
を選択します。
必要な項目を入力して、[環境の作成]ボタンをクリックします。
- ドメイン:ユニークな環境URLを割り当てます
- コードのアップロード:ダウンロードした
php-v1.zip
をそのままアップロードします
ヘルスがOK
になるまで待機します。
URLを開いて、サンプルアプリが表示されることを確認します。
これで1つめの環境が出来ました。
2つめの環境作成
サンプルアプリの改修
ダウンロードしたサンプルアプリを少し変更します。
styles.css
section.instructions { display: block; padding: 50px; text-align: left; background-color: #0f0; /*変更*/ position: absolute; top: 0; left: 50%; right: 0; bottom: 0; }
背景色を白から緑に変更しました。
index.php ファイルのあるディレクトリでファイルを圧縮します。
$ zip php-v2.zip -r .e* *
この時、隠しフォルダ.ebextensions
を含めるようにします。含めないとエラーになります。
※Windowsの人はアプリケーションを更新するを参考にしてください。
環境のクローン作成
作成した環境をコピーして、改修したサンプルアプリをデプロイします。
[アクション]-[環境のクローン作成]メニューを選択します。
ユニークな環境URLを割り当て、[クローン]ボタンをクリックします。
[アップロードとデプロイ]ボタンから、改修したサンプルアプリをアップロードし、[デプロイ]ボタンをクリックします。
URLを開いて、背景色が緑色になっていることを確認します。
これで2つめの環境が出来ました。
環境URLのスワップ
2つの環境のDNSレコードのCNAMEを切り替えます。
[アクション]-[環境URLのスワップ]メニューを選択します。
スワップする環境を選択して、[スワップ]ボタンをクリックします。
環境 | スワップ前 | スワップ後 |
---|---|---|
1つめ | aaa.xxx.elasticbeanstalk.com | bbb.xxx.elasticbeanstalk.com |
2つめ | bbb.xxx.elasticbeanstalk.com | aaa.xxx.elasticbeanstalk.com |
1つめの環境のURLを開いた時に、背景色が緑色になっていることを確認します。
アプリに問題があれば、スワップして元に戻すだけです。
素晴らしいですね!
まとめ
Elastic Beanstalkを使うと、簡単にデプロイが出来て、簡単にダウンタイム無しにアプリを切り替えることが出来ます。
デプロイについては、冒頭の資料 AWS Black Belt Online Seminar 2017 AWS Elastic Beanstalkと、下記のブログを一読することをおすすめします。 どちらもよくまとまっています。
参考
- AWSドキュメント
- 10分間チュートリアル
- AWS Black Belt
CloudFormationテンプレートのDeletionPolicy属性
Resourcesセクション内のリソース定義時に、DeletionPolicy属性を指定すると、リソースの削除方法を制御できます。
DeletionPolicy属性は、リソースのふるまいや関連性を制御するリソース属性
の1つです。
リソース属性
- CreationPolicy 属性
- DeletionPolicy 属性 (これ)
- DependsOn 属性
- Metadata 属性
- UpdatePolicy 属性
DeletionPolicy属性のオプション
- Delete
- リソースを削除する
- Retain
- スタック削除しても、対象のリソースを削除しない
- 残ったリソースはCloudFormationの管理外
- Snapshot
- リソースを削除する前にスナップショット作成
- 対応リソース
- AWS::EC2::Volume
- AWS::ElastiCache::CacheCluster
- AWS::ElastiCache::ReplicationGroup
- AWS::RDS::DBInstance
- AWS::RDS::DBCluster
- AWS::Redshift::Cluster
デフォルトの動作
DeletionPolicy属性は省略可能です。
省略した場合はリソースが削除されますが、一部のリソースタイプはデフォルトの動作が異なります。
リソースタイプ | デフォルトの動作 |
---|---|
AWS::RDS::DBCluster | Snapshot |
AWS::RDS::DBInstance | Auroraエンジン用のDBClusterIdentifierプロパティ ・指定する:Delete ・指定しない:Snapshot |
それ以外 | Delete |
サンプルテンプレート
Amazon RDSのDBインスタンスを作成するテンプレートです。
リソースタイプ AWS::RDS::DBInstance の DeletionPolicy属性にRetain
を指定しています。
スタック作成時に
AWSTemplateFormatVersion: 2010-09-09 Parameters: DBUser: NoEcho: true Description: The database admin account username Type: String MinLength: 1 MaxLength: 16 AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*' ConstraintDescription: must begin with a letter and contain only alphanumeric characters. DBPassword: NoEcho: true Description: The database admin account password Type: String MinLength: 8 MaxLength: 41 AllowedPattern: '[a-zA-Z0-9]*' ConstraintDescription: must contain only alphanumeric characters. Resources: MyDB: Type: AWS::RDS::DBInstance Properties: DBName: MyDatabase AllocatedStorage: 5 DBInstanceClass: db.t2.small Engine: MySQL MasterUsername: !Ref DBUser MasterUserPassword: !Ref DBPassword DeletionPolicy: Retain Outputs: JDBCConnectionString: Description: JDBC connection string for the database Value: !Join - '' - - 'jdbc:mysql://' - !GetAtt - MyDB - Endpoint.Address - ':' - !GetAtt - MyDB - Endpoint.Port - /MyDatabase
スタックを削除すると、RDSを削除しないため、一瞬で完了します。 (残ったRDSは削除してください)
AWS::RDS::DBInstanceの場合、DeletionPolicy属性を削除するとSnapshot
として動作します。
この場合、スナップショットが残っているのが確認できます。
参考
- AWSドキュメント
T3インスタンスの制限数
2018年8月現在、T3インスタンス(オンデマンド)の制限数を調べました。
リージョン | nano | micro | small | medium | large | xlarge | 2xlarge |
---|---|---|---|---|---|---|---|
バージニア北部 | 10 | 10 | 10 | 7 | 5 | 3 | 3 |
オハイオ | 10 | 10 | 6 | 4 | 3 | 2 | 1 |
北カリフォルニア | 5 | 5 | 5 | 3 | 3 | 2 | 2 |
オレゴン | 10 | 10 | 10 | 10 | 5 | 3 | 3 |
ムンバイ | - | - | - | - | - | - | - |
ソウル | - | - | - | - | - | - | - |
シンガポール | 5 | 5 | 5 | 5 | 3 | 1 | 1 |
シドニー | 5 | 5 | 5 | 5 | 3 | 2 | 2 |
東京 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
カナダ | 7 | 7 | 5 | 5 | 5 | 3 | 1 |
フランクフルト | 5 | 5 | 5 | 5 | 3 | 1 | 1 |
アイルランド | 5 | 5 | 5 | 3 | 3 | 3 | 2 |
ロンドン | 5 | 5 | 5 | 5 | 3 | 3 | 1 |
パリ | - | - | - | - | - | - | - |
サンパウロ | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
東京リージョンが少ないですね。。。
制限を超える場合は、上限緩和の申請
をしましょう。
参考
- AWSドキュメント
せっかくだから、俺はこのT3インスタンスを選ぶぜ!
T3インスタンスがリリースされました。
t2.micro
とt3.micro
を比較してみます。
料金は東京リージョン、オンデマンド、Linux/UNIXの条件です。
t2.micro | t3.micro | |
---|---|---|
vCPU | 1 | 2 |
EBS最適化利用 | - | はい |
ネットワークパフォーマンス | 低から中 | Up to 5 Gigabit |
T2/T3 Unlimited | - | デフォルトで有効化 |
1時間あたりに受け取るCPUクレジット | 6 | 12 |
蓄積可能な最大獲得クレジット | 144 | 288 |
初期クレジット | 30 | 0 |
料金(時間) | $0.0152 | $0.0136 |
無料利用枠の対象 | はい | - |
t3の方が1時間あたりに受け取るCPUクレジットが倍になっていますが、初期クレジット(CPUCreditBalance)が0です。
無料利用枠が関係ないのであれば、積極的にt3を利用したいですね。
リザーブドインスタンス
ちょうど自宅での検証用にリザーブドインスタンスが欲しかったので、t3.micro
を購入します。
サービス [EC2] - [リザーブドインスタンス] を選択し、[リザーブドインスタンスの購入]ボタンをクリックします。
- 東京リージョン
- プラットフォーム: Linux/UNIX
- テナンシー: デフォルト(共有)
- 提供クラス: スタンダード
- 期間: 1年間
- お支払い方法: 全前払い
インスタンスタイプ t2.micro
とt3.micro
を比較してみます。(2018年8月現在)
t2.micro
前払い価格: $84.0
t3.micro
前払い価格: $76.0
1年間で見ると、T3の方が 8ドル ほど安くなっています。お得ですね。
「ポチッとな」
無事購入できました。
まとめ
こうして俺は「T3インスタンス」を手に入れた。
参考
- AWS News Blog
- AWSドキュメント
- Developers.IO
シンプルなネットワークとサーバーをCloudFormationで構築する 〜3. サーバー構築〜
前回はセキュリティーグループ、ネットワークACLを設定しました。
今回は、作成したネットワーク上にEC2インスタンスを作成し、Webサーバーを構築します。 Webサーバーはnginxデフォルト状態とします。
サーバー構築用のテンプレート
今回作成したテンプレートは以下になります。
server.template.yaml
AWSTemplateFormatVersion: 2010-09-09 Parameters: ProjectCode: Type: String Description: Enter your project code InstanceType: Type: String Description: WebServer EC2 instance type ConstraintDescription: must be a valid EC2 instance type. Default: t2.micro AllowedValues: - t2.nano - t2.micro - t2.small - t2.medium - t2.large KeyName: Type: AWS::EC2::KeyPair::KeyName Description: Name of an existing EC2 KeyPair to enable SSH access to the instance ConstraintDescription: must be the name of an existing EC2 KeyPair. Mappings: RegionMap: us-east-1: AL2: ami-04681a1dbd79675a5 us-east-2: AL2: ami-0cf31d971a3ca20d6 us-west-1: AL2: ami-0782017a917e973e7 us-west-2: AL2: ami-6cd6f714 ap-northeast-1: AL2: ami-08847abae18baa040 ap-southeast-1: AL2: ami-01da99628f381e50a Resources: WebServerInstance: Type: AWS::EC2::Instance Properties: ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", AL2] InstanceType: !Ref InstanceType KeyName: !Ref KeyName NetworkInterfaces: - GroupSet: - Fn::ImportValue: !Sub ${ProjectCode}-web-sg AssociatePublicIpAddress: true DeviceIndex: 0 DeleteOnTermination: true SubnetId: Fn::ImportValue: !Sub ${ProjectCode}-subnet UserData: !Base64 | #!/bin/bash amazon-linux-extras install nginx1.12 -y systemctl start nginx systemctl enable nginx Tags: - Key: Name Value: !Ref ProjectCode Outputs: WebServerInstance: Description: InstanceId of the newly created EC2 instance Value: !Ref WebServerInstance
パラメータ
パラメータは3つあります。
パラメータ | 説明 |
---|---|
ProjectCode | プロジェクトコードを指定します。 各リソースの名前とテンプレート連携(クロススタック参照)で利用します。 |
InstanceType | インスタンスタイプを指定します。デフォルトはt2.micro です。(テンプレートを短くするため数を減らしています) |
KeyName | EC2 のキーペアの名前を指定します。 |
マッピング
AMIはリージョン単位のサービスです。
各リージョンのAmazon Linux2のAMIをマッピングで用意します。
目的のリージョンがない場合は追加してください。
リソース
ImageId
マッピングから選択リージョンのAMIを取得します。
ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", AL2]
NetworkInterfaces
アタッチされるネットワークインターフェイスを指定します。
組み込み関数Fn::ImportValue
を利用して、作成したサブネットID、セキュリティーグループIDをインポートします。
NetworkInterfaces: - GroupSet: - Fn::ImportValue: !Sub ${ProjectCode}-web-sg AssociatePublicIpAddress: true DeviceIndex: 0 DeleteOnTermination: true SubnetId: Fn::ImportValue: !Sub ${ProjectCode}-subnet
UserData
単純なインストールであれば、ユーザーデータにシェルを書くのが簡単です。 nginxをインストールして起動、自動起動を設定します。
UserData: !Base64 | #!/bin/bash amazon-linux-extras install nginx1.12 -y systemctl start nginx systemctl enable nginx
出力
確認用にEC2インスタンスIDを出力します。
スタックの作成
ではスタックを作成してみましょう。
スタックの名前、パラメータを指定します。ProjectCodeは前回と同じ値を設定してください。
スタック作成完了後に、出力を確認します。
サービス [EC2] - [インスタンス] を選択し、作成したインスタンスのパブリックIP
をブラウザに入力してnginxが起動しているか確認をします。
まとめ
ちょっとした目的でもテンプレートは長くなりがちです。 その場合、テンプレートを目的ごとに分割すると、再利用しやすく、管理がしやすくなります。
参考
シンプルなネットワークとサーバーをCloudFormationで構築する 〜2. セキュリティ設定〜
前回はVPC、サブネット、インターネットゲートウェイ、ルートテーブルを作成して、ネットワークを構築しました。
今回はセキュリティを作成・設定します。
セキュリティーグループとネットワークACL
VPCのファイアウォール機能として、セキュリティーグループ
とネットワークACL
があります。
両者は適用するレベル(単位)が異なります。
インスタンス単位で動作する第1層のセキュリティーグループ、サブネット単位で動作する第2層のネットワークACLです。
セキュリティーグループとネットワークACLの大まかな違いは下記になります。
セキュリティーグループ | ネットワークACL | |
---|---|---|
適用単位 | インスタンス単位 | サブネット単位 |
ルール | 許可 | 許可と拒否 |
ルールロジック | すべてのルールを評価 | 順番にルールを処理 |
作成されたデフォルト値 | インバウンド: すべて拒否 アウトバウンド:すべて許可 |
インバウンド: すべて許可 アウトバウンド:すべて許可 |
特徴 | ステートフル 許可された送信の戻りは自動的に許可 |
ステートレス 許可された送信の戻りもルールチェックされる |
ネットワークACLは、VPC作成時にデフォルトのネットワークACLが作成されます。 インバウンド、アウトバウンドともにすべて許可されているので、拒否ルールが不要であればデフォルトを利用します。
セキュリティ設定用のテンプレート
今回作成したテンプレートは以下になります。
security.template.yaml
AWSTemplateFormatVersion: 2010-09-09 Parameters: ProjectCode: Type: String Description: Enter your project code SSHLocation: Type: String Description: The IP address range that can be used to SSH to the EC2 instances ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. MinLength: 9 MaxLength: 18 Default: 0.0.0.0/0 AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2}) Resources: SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: Fn::ImportValue: !Sub ${ProjectCode}-vpc GroupDescription: Enable SSH access via port 22, 80 SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref SSHLocation - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 Tags: - Key: Name Value: !Ref ProjectCode NetworkAcl: Type: AWS::EC2::NetworkAcl Properties: VpcId: Fn::ImportValue: !Sub ${ProjectCode}-vpc Tags: - Key: Name Value: !Ref ProjectCode InboundHTTPNetworkAclEntry: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref NetworkAcl RuleNumber: 100 Protocol: 6 RuleAction: allow Egress: false CidrBlock: 0.0.0.0/0 PortRange: From: 80 To: 80 InboundSSHNetworkAclEntry: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref NetworkAcl RuleNumber: 101 Protocol: 6 RuleAction: allow Egress: false CidrBlock: 0.0.0.0/0 PortRange: From: 22 To: 22 InboundResponsePortsNetworkAclEntry: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref NetworkAcl RuleNumber: 102 Protocol: 6 RuleAction: allow Egress: false CidrBlock: 0.0.0.0/0 PortRange: From: 1024 To: 65535 OutBoundHTTPNetworkAclEntry: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref NetworkAcl RuleNumber: 100 Protocol: 6 RuleAction: allow Egress: true CidrBlock: 0.0.0.0/0 PortRange: From: 80 To: 80 OutBoundHTTPSNetworkAclEntry: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref NetworkAcl RuleNumber: 101 Protocol: 6 RuleAction: allow Egress: true CidrBlock: 0.0.0.0/0 PortRange: From: 443 To: 443 OutBoundResponsePortsNetworkAclEntry: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref NetworkAcl RuleNumber: 102 Protocol: 6 RuleAction: allow Egress: true CidrBlock: 0.0.0.0/0 PortRange: From: 1024 To: 65535 SubnetNetworkAclAssociation: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: Fn::ImportValue: !Sub ${ProjectCode}-subnet NetworkAclId: !Ref NetworkAcl Outputs: WebSecurityGroup: Description: Id of the newly created Security Group Value: !Ref SecurityGroup Export: Name: !Sub ${ProjectCode}-web-sg
パラメータ
パラメータは2つあります。
パラメータ | 説明 |
---|---|
ProjectCode | プロジェクトコードを指定します。 各リソースの名前とテンプレート連携(クロススタック参照)で利用します。 |
SSHLocation | SSH接続を許可するIPアドレスです。 デフォルトは制限無しの 0.0.0.0/0 です。 |
リソース
1. セキュリティーグループ
VPC上にセキュリティーグループを作成します。
組み込み関数Fn::ImportValue
を利用して、前回作成したVPC IDをインポートします。
SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: Fn::ImportValue: !Sub ${ProjectCode}-vpc GroupDescription: Enable SSH access via port 22, 80 SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref SSHLocation - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0
この時点では、セキュリティグループに属しているインスタンスはありません。
2. ネットワークACL
ネットワークACLを作成し、サブネットに関連付けをします。
組み込み関数Fn::ImportValue
を利用して、前回作成したサブネットIDをインポートします。
NetworkAcl: Type: AWS::EC2::NetworkAcl Properties: VpcId: Fn::ImportValue: !Sub ${ProjectCode}-vpc SubnetNetworkAclAssociation: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: Fn::ImportValue: !Sub ${ProjectCode}-subnet NetworkAclId: !Ref NetworkAcl
ルール設定
ネットワークACLを作成した時点のルールは、インバウンド/アウトバウンドともに、すべて拒否になります。
基本は AWS::EC2::NetworkAclEntry
を使用して、許可ルールを設定します。
インバウンド
ルール番号 | プロトコル | ポート | 送信元IP | 用途 |
---|---|---|---|---|
100 | TCP | 80 | 0.0.0.0/0 | HTTP |
101 | TCP | 22 | 0.0.0.0/0 | SSH |
102 | TCP | 1024-65535 | 0.0.0.0/0 | サーバー側用一時ポート |
アウトバウンド
ルール番号 | プロトコル | ポート | 送信元IP | 用途 |
---|---|---|---|---|
100 | TCP | 80 | 0.0.0.0/0 | HTTP |
101 | TCP | 443 | 0.0.0.0/0 | HTTPS |
102 | TCP | 1024-65535 | 0.0.0.0/0 | クライアント側用一時ポート |
出力
後続のテンプレート用にセキュリティーグループIDをエクスポートします。
パラメータ | 説明 |
---|---|
WebSecurityGroup | セキュリティーグループIDの参照用に、エクスポート名を {プロジェクトコード}-web-sg にします。 |
スタックの作成
ではスタックを作成してみましょう。
スタックの名前、パラメータを指定します。ProjectCodeは前回と同じ値を設定してください。
スタック作成完了後に、出力を確認します。
サービス [ネットワーキング & コンテンツ配信] - [VPC] を選択し、各リソースが作成されていることを確認します。
- ネットワーク ACL
- セキュリティグループ