Fire 7 に Firefox をインストールする手順
- 設定 > セキュリティとプライバシー の 詳細設定 にある 不明ソースからのアプリ をオンにする
- Download Firefox for Android in your language で、ARM デバイスの apk をダウンロード
- apk を開いてインストールする
- 設定 > セキュリティとプライバシー の 詳細設定 にある 不明ソースからのアプリ をオフにする
Route 53 と カスタムドメインを使った Gmail の設定
今使っている DNS サービスより、AWS Route 53 の方が何かと扱いやすい気がしてきたので引越しをすることにしました。 その手順のメモです。
手順
AWS Route 53 コンソールを開きます
[Create Hosted Zone] を選択します
[Create Hosted Zone]ペインでドメイン名を入力します
NS レコードの4つの名前をメモします
Example: ns1.amazon.com ns2.amazon.org ns3.amazon.net ns4.amazon.co.uk
TTL を 172800 から 900 に変更します
G Suite > Google Admin > ドメイン > メールの配信設定 の記述に従って、MX レコードの追加と迷惑メール防止のため SPF レコードを追加します
dig
やnslookup
を使って、Route 53 による DNS の動作が確認されたら、TTL を 900 から 172800 に戻します
参考
Raspberry Pi 3 をアクセスポイントにする
公式のサイトのACCESS-POINTの "Using the Raspberry Pi as an access point to share an internet connection (bridge)" を参考に Raspberry Pi 3 をアクセスポイントにしました。
$ sudo -s # apt-get update # apt-get upgrade # apt-get install hostapd bridge-utils # systemctl stop hostapd
/etc/dhcpcd.conf の最後に、denyinterfaces wlan0
と denyinterfaces eth0
を追記します。
ブリッジを追加します。
# brctl addbr br0
br0 に eth0 を接続します。
# brctl addif br0 eth0
/etc/network/interfaces に追記します。
# Bridge setup auto br0 iface br0 inet manual bridge_ports eth0 wlan0 bridge_stp on
/etc/hostapd/hostapd.conf を記述します。
interface=wlan0 bridge=br0 #driver=nl80211 ssid=NameOfNetwork hw_mode=g channel=7 wmm_enabled=0 macaddr_acl=0 auth_algs=1 ignore_broadcast_ssid=0 wpa=2 wpa_passphrase=AardvarkBadgerHedgehog wpa_key_mgmt=WPA-PSK wpa_pairwise=TKIP rsn_pairwise=CCMP country_code=JP
ここまでの設定でリブートすれば動くように書かれていましたが、試しに、hostapd /etc/hostapd/hostapd.conf
を実行してみると、AP-DISABLED となっていました。
rfkill list
を実行すると以下のように表示されました。
0: phy0: Wireless LAN Soft blocked: yes Hard blocked: no 1: hci0: Bluetooth Soft blocked: yes Hard blocked: no
そこで、rfkill unblock 0
として、Wireless LAN のブロックを解除しました。
最後に、/etc/default/hostapd の DAEMON_CONF="" のところを次のように修正して、reboot
します。
DAEMON_CONF="/etc/hostapd/hostapd.conf"
Microservices と DDD
本記事はドメイン駆動設計 Advent Calendar 2018 - Qiitaの4日目の記事です。
3日目は、bigwheelさんの「集約の境界と整合性の維持の仕方に悩んで2ヶ月ぐらい結論を出せていない話」でした。
5日目は、yoskhdiaさんの「エンティティの同一性を表現するためにequalsをオーバーライドすべきか否か」です。
Microservices の利点
- 技術異質性
- 回復性
- スケーリング
- デプロイの容易性
- 組織面の一致
- 合成可能性
- 交換可能にするための最適化
Monoliths, Microliths での境界づけられたコンテキストの統合
Monoliths
Monoliths なアプリケーションに複数の境界づけられたコンテキストを統合するケースでは、共有ライブラリや、モジュールによって 分散コンピューティングで遭遇する煩わしい問題の多くを回避できます。
Monoliths なアプリケーションの欠点は、変更した場合にアプリケーション全体をデプロイしなおす必要がありデプロイ容易性に欠けるという点です。 このことから頻繁なデプロイを行うことが少なく、時間の経過とともに技術的負債が蓄積され、変更がさらに困難となっていきます。
Microliths
Monoliths なアプリケーションのケースでも、必ずしも一つのアプリケーションで構成されるわけではなく、日次、月次、年次等のようなバッチ処理アプリケーションとWebアプリケーションのように、複数のアプリケーションに境界づけられたコンテキストが統合されます。
これをさらに細かく分割して Microservices と似た構成のアプリケーションに分割することもできます、分割したアプリケーションで次のような問題が発見されることがあります。
- アプリケーション間の結合度が高く、いずれかのアプリケーションの障害により分割した他のアプリケーションに影響を与える
- 類似のロジックが分散していて、あるアプリケーションの変更を、他のアプリケーションでも行う必要がある
結果として、分割したアプリケーション単体でのデプロイは困難となり、複数のアプリケーション、最悪の場合は、すべてのアプリケーションを同時期にデプロイしなければならなくなります。
このように分割されたアプリケーションは Microliths と呼ばれます。
Microservices
実践ドメイン駆動設計から、Microservices としての利点を満たすアプリケーションにとって特に重要なポイントをピックアップしてみます。
第2章 ドメイン、サブドメイン、境界づけられたコンテキスト
Microservices ではアプリケーションと組織面の一致が必要です。したがって、ドメイン、サブドメインや境界づけられたコンテキストと組織面の一致がないと、不要なドメイン知識まで取り込むことになったり、ドメインの知識を、外部のコンテキスト - つまりは他の Microservices - に依存しなければならなくなり、自律的なサービスを実現することができなくなります。
第13章 境界づけられたコンテキストの統合
Microservices として自律的なサービスを担保するためには、境界づけられたコンテキストの統合にメッセージングが最も有力な候補となります。
第14章 アプリケーション
Microservices に統合する、複数の境界づけられたコンテキストは組織面と一致させる必要があります。
まとめ
Microservices に分割したアプリケーションがうまく機能しないというのを見聞きすることがありますが、これは、Microservices だからということではなく、 境界づけられたはずのコンテキストの境界があいまいであったり、ドメイン、サブドメインについての考察が十分ではないことが原因の多くをしめているのではと考えています。 Monoliths であればそういった誤りは技術的負債として将来に繰延べされますが、Microservices の場合は初期にこのような問題が発見されるため、設計に対するフィードバックを早めることができるという利点もあると考えています。
参考文献
他アカウントの CodeCommit を使用した CodePipeline
開発アカウントに CodeCommit を使用して、プロダクションアカウントでビルドやデプロイを行うためのメモ。
1. プロダクションアカウント
1-1. CodePipeline のサービスロールのためのポリシーを作成する
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:GetObject", "s3:GetObjectVersion", "s3:GetBucketVersioning" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "s3:PutObject" ], "Resource": [ "arn:aws:s3:::codepipeline*", "arn:aws:s3:::elasticbeanstalk*" ], "Effect": "Allow" }, { "Action": [ "codecommit:CancelUploadArchive", "codecommit:GetBranch", "codecommit:GetCommit", "codecommit:GetUploadArchiveStatus", "codecommit:UploadArchive" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "codedeploy:CreateDeployment", "codedeploy:GetApplicationRevision", "codedeploy:GetDeployment", "codedeploy:GetDeploymentConfig", "codedeploy:RegisterApplicationRevision" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "elasticbeanstalk:*", "ec2:*", "elasticloadbalancing:*", "autoscaling:*", "cloudwatch:*", "s3:*", "sns:*", "cloudformation:*", "rds:*", "sqs:*", "ecs:*", "iam:PassRole" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "lambda:InvokeFunction", "lambda:ListFunctions" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "opsworks:CreateDeployment", "opsworks:DescribeApps", "opsworks:DescribeCommands", "opsworks:DescribeDeployments", "opsworks:DescribeInstances", "opsworks:DescribeStacks", "opsworks:UpdateApp", "opsworks:UpdateStack" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "cloudformation:CreateStack", "cloudformation:DeleteStack", "cloudformation:DescribeStacks", "cloudformation:UpdateStack", "cloudformation:CreateChangeSet", "cloudformation:DeleteChangeSet", "cloudformation:DescribeChangeSet", "cloudformation:ExecuteChangeSet", "cloudformation:SetStackPolicy", "cloudformation:ValidateTemplate", "iam:PassRole" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "codebuild:BatchGetBuilds", "codebuild:StartBuild" ], "Resource": "*", "Effect": "Allow" }, { "Effect": "Allow", "Action": [ "devicefarm:ListProjects", "devicefarm:ListDevicePools", "devicefarm:GetRun", "devicefarm:GetUpload", "devicefarm:CreateUpload", "devicefarm:ScheduleRun" ], "Resource": "*" } ] }
1-2. CodePipeline のサービスロールを作成する
CodePipeline サービスのロールを作成する
1-3. IAMの暗号化キーを作成する
- IAM から 暗号化キー を選択して、使用するリージョンで キーの作成 を選択する
- エイリアスと説明の作成で、エイリアス を入力し 次のステップ を選択する
- タグの追加で必要に応じてタグを追加し、次のステップ を選択する
- キーの使用アクセス許可の定義 の キー管理者 を必要に応じて設定し、次のステップ を選択する
- キーの使用アクセス許可の定義 の このアカウント で 1-2 の手順で作成した CodePipeline のサービスロールを選択する、 外部アカウント で 外部アカウントの追加 を選択して開発アカウントIDを入力する
- キーポリシーのプレビューで 完了 を選択する
1-4. CodePipeline のサービスロールに暗号化キーのポリシーを追加する
1-2 の手順で作成した CodePipeline のロールに 1-3 の手順で作成した暗号化キーの ARN をリソースに設定して作成したポリシーをアタッチする
{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": [ "kms:*" ], "Resource": [ "arn:aws:kms:ap-northeast-1:${ProductionAccount}:key/2222222-3333333-4444-556677EXAMPLE" ] } }
1-5. CodeBuild のサービスロールのためのポリシーを作成する
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "codebuild:*", "iam:PassRole", "logs:FilterLogEvents", "logs:GetLogEvents", "logs:CreateLogStream", "logs:CreateLogGroup", "logs:PutLogEvents", "s3:CreateBucket", "s3:GetObject", "s3:List*", "s3:PutObject" ], "Resource": "*", "Effect": "Allow" } ] }
1-6. CodeBuild のサービスロールを作成する
CodeBuild サービスのロールを作成し、1-5 の手順で作成した CodeBuild のポリシーと 1-4 の手順で作成したポリシーをアタッチする
2. 開発アカウント
2-1. CodeCommit にクロスアカウントアクセスのためのポリシーを作成する
1-3 の手順で作成した暗号化キーの ARN を設定して、 クローンしたイメージを暗号化して CodePipeline の S3 に PutObject するためのポリシーを作成する。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "codecommit:BatchGetRepositories", "codecommit:Get*", "codecommit:GitPull", "codecommit:List*", "codecommit:CancelUploadArchive", "codecommit:UploadArchive", "s3:*" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "kms:*" ], "Resource": [ "arn:aws:kms:ap-northeast-1:${ProductionAccount}:key/2222222-3333333-4444-556677EXAMPLE" ] } ] }
2-2. CodeCommit のロールを作成する
- IAM から ロール を選択し ロールの作成 を選択する
- 別のAWSアカウント を選択し、アカウントID にプロダクションアカウントのアカウントIDを入力し、次のステップ:アクセス権限 を選択する
- 2-1 の手順で作成したポリシーをアタッチし、次のステップ:確認 を選択する
- ロール名を入力し、ロールの作成 を選択する
2-3. CodeCommit を作成する
CodeCommit を作成する。CodeCommit はあらかじめ作成しておいてもよい。
3. プロダクションアカウント
3-1. CodePipeline のサービスロールに開発アカウントのポリシーを追加
CodePipeline に開発アカウントの CodeCommit のロールにアクセスするポリシーを作成しアタッチする
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "sts:AssumeRole" ], "Resource": [ "arn:aws:iam::${DevelopAccount}:role/${CodeCommitRoleName}" ] } ] }
3-2. CodePipeline の Artifact Store となる S3 Bucket を作成する
codebuild.amazonaws.com サービスと開発アカウントの CodeCommit ロールからアクセスされる CodePipeline で使う S3 Bucket を作成する。
Key | Description |
---|---|
BucketName | CodePipeline が使用するバケット名 |
CodeCommitRoleName | 2-2 の手順で作成したロール名 |
DevelopAccount | 開発アカウントID |
AWSTemplateFormatVersion: '2010-09-09' Parameters: BucketName: Type: String CodeCommitRoleName: Type: String DevelopAccount: Type: String Resources: S3Bucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref BucketName BucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref S3Bucket PolicyDocument: Statement: - Action: s3:* Effect: Allow Resource: - !Sub arn:aws:s3:::${BucketName} - !Sub arn:aws:s3:::${BucketName}/* Principal: Service: - codebuild.amazonaws.com AWS: - !Sub arn:aws:iam::${DevelopAccount}:role/${CodeCommitRoleName}
3-3. CodeBuild
Key | Description |
---|---|
CacheLocation | CodeBuild のキャッシュが使用するバケット名 |
CodeBuildRoleName | 1-6 の手順で作成したロール名 |
Image | CodeBuildに使用するコンテナ名 |
Name | CodeBuild名 |
AWSTemplateFormatVersion: '2010-09-09' Parameters: CacheLocation: Type: String CodeBuildRoleName: Type: String Image: Type: String Name: Type: String Resources: CodeBuild: Type: AWS::CodeBuild::Project Properties: Artifacts: Type: CODEPIPELINE Cache: Location: !Sub ${CacheLocation}/ivy2 Type: S3 Description: !Ref Name EncryptionKey: arn:aws:kms:ap-northeast-1:${ProductionAccount}:key/2222222-3333333-4444-556677EXAMPLE Environment: ComputeType: BUILD_GENERAL1_SMALL Image: !Ref Image EnvironmentVariables: - Name: BUCKET_NAME Value: !Ref CacheLocation PrivilegedMode: true Type: LINUX_CONTAINER Name: !Ref Name ServiceRole: !Sub arn:aws:iam::${AWS::AccountId}:role/${CodeBuildRoleName} Source: Type: CODEPIPELINE
3-4. CodePipeline
Key | Description |
---|---|
BucketName | 3-2 の手順で作成したバケット名 |
CodeCommitRoleName | 2-2 の手順で作成したロール名 |
CodePipelineRoleName | 1-2 の手順で作成したロール名 |
DevelopAccount | 開発アカウントID |
Name | CodePipeline名 |
RepositoryName | 2-3 の手順で作成した CodeCommit リポジトリ名 |
AWSTemplateFormatVersion: '2010-09-09' Parameters: BucketName: Type: String CodeCommitRoleName: Type: String CodePipelineRoleName: Type: String DevelopAccount: Type: String Name: Type: String RepositoryName: Type: String Resources: CodePipeline: Type: AWS::CodePipeline::Pipeline Properties: ArtifactStore: EncryptionKey: Id: arn:aws:kms:ap-northeast-1:${ProductionAccount}:key/2222222-3333333-4444-556677EXAMPLE Type: KMS Location: !Ref BucketName Type: S3 Name: !Ref Name RoleArn: !Sub arn:aws:iam::${AWS::AccountId}:role/${CodePipelineRoleName} Stages: - Actions: - ActionTypeId: Category: Source Owner: AWS Provider: CodeCommit Version: 1 Configuration: PollForSourceChanges: false RepositoryName: !Ref RepositoryName BranchName: master Name: source OutputArtifacts: - Name: MyApp RoleArn: !Sub arn:aws:iam::${DevelopAccount}:role/${CodeCommitRoleName} Name: source - Actions: - ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: 1 Configuration: ProjectName: !Ref Name InputArtifacts: - Name: MyApp OutputArtifacts: - Name: App Name: build Name: build
参考
ECR のイメージを別のアカウントの ECR に転送する
準備
$ pip install boto3 $ pip install docker
ECR から pull
import boto3 import base64 import docker account_id = '123456789012' region = 'ap-northeast-1' name = '%s.dkr.ecr.%s.amazonaws.com/%s' % (account_id, region, 'example') session = boto3.Session( profile_name = SWITCH_ACCOUNT_PROFILE, region_name = region ) ecr = session.client('ecr') authorization_token = ecr.get_authorization_token()['authorizationData'][0] token = base64.b64decode(authorization_token['authorizationToken']).split(':') user = token[0] pwd = token[1] auth_cred = { 'username': user, 'password': pwd } client = docker.from_env() client.images.pull(name, auth_config = auth_cred)
転送先の ECR 用に tag を設定
import docker src_account_id = '123456789012' dist_account_id = '210987654321' region = 'ap-northeast-1' src = '%s.dkr.ecr.%s.amazonaws.com/%s' % (src_account_id, region, 'example') dist = '%s.dkr.ecr.%s.amazonaws.com/%s' % (dist_account_id, region, 'example') client = docker.from_env() images = client.images.list(name = src) for image in images: for tag in image.tags: t = tag.split(':')[1] image.tag(dist, t)
別のアカウントの ECR に push
import boto3 import base64 import docker account_id = '210987654321' region = 'ap-northeast-1' session = boto3.Session( profile_name = SWITCH_ANOTHER_ACCOUNT_PROFILE, region_name = region ) name = '%s.dkr.ecr.%s.amazonaws.com/%s' % (account_id, region, 'example') ecr = session.client('ecr') authorization_token = ecr.get_authorization_token()['authorizationData'][0] token = base64.b64decode(authorization_token['authorizationToken']).split(':') user = token[0] pwd = token[1] auth_cred = { 'username': user, 'password': pwd } client = docker.from_env() images = client.images.list(name = name) for image in images: for tag in image.tags: client.images.push(tag, auth_config = auth_cred)