20210912のAWSに関する記事は20件です。

[rails] nginx + unicorn + mysql (aws EC2 RDS) production環境立ち上げ時のメモ

はじめに 初心者がRailsチュートリアルのやり方を無視アレンジして無謀にもAWSでデプロイしたためにエラー地獄にハマった軌跡をメモとして残しました。 (ミドルウェアもチュートリアルと変えてます。WEBサーバー:nginx + unicorn、DB:mysql(RDS)) 参考記事 「rails aws」で検索して上位に出てきた こちらの記事を参考(めちゃくちゃ助かりました。) 環境 Rails 6.0.3 ruby 3.0.2 unicorn v6.0.0 nginx/1.20.1 mysql 8.0.2 unicorn.rb listenのパスを{app_name}/tmp/unicorn.sock に変更する(pidも同様)。こちらにある通り、参考記事は古い記述になってるので上記の通り変更することでNginxとの接続が可能になるらしい。 credentials.yml.enc さらにRails5.2以降はsecret.ymlがcredentials.yml.encになったらしい。{app_name}/で以下を実行で編集&master.key作成 (master.keyは.gitignoreに入るのでproduction環境は手動で作成する必要があるらしい。unicorn起動時に意味のわからないエラーの原因の1つはこれでした。このあたりで結構ハマった...) $ EDITOR="vi" bin/rails credentials:edit ちなみにcredentials.yml.encは普通にvimで直接編集できないのでこの方法でやる必要があるらしいです。 nginxの設定ファイル デフォルトは/etc/nginx/conf.d/default.confに作られるので{app_name}.confに変更した後に以下の部分を変更。 /etc/nginx/conf.d/rails.conf upstream unicorn { server unix:{app_name}/tmp/unicorn.sock; } おわりに これらの設定を見直した状態でunicorn、nginxなど再起動で無事サーバーが正常起動しました。終わってみれば、参考記事と現行バージョンの差異による設定ファイルの場所や書き方などの変更作業がエラー対処の大半の時間を費やしていた気がします。 aws要素は? aws特に関係ない話になってしまいましたが、DBをチュートリアルのpostgresからmysql(RDS)に変えた部分は大して影響ありませんでした(今のところ)。DB接続周りはdatabase.ymlでhostをRDSのエンドポイントにして、usernameとpassword変えたくらいで問題なかったはずです。VPCのセキュリティグループでRDSとEC2間のポートなどが適切に設定してあればこれくらいの変更でいけると思います。 約15時間にわたる死闘の末 唐突に画面に映ったhello, world!の文字列。ああ、そういえばRailsチュートリアル進めてたんだった…ここまで感動したhello, world!は初めてだよ。もう、ゴールしていいよね…? 参考記事 【Ruby on Rails】unicornをNginx環境下で動かす時の設定方法 【CentOS 7】Nginx + Unicorn で Rails アプリケーションを本番環境で立ち上げる方法 ActiveRecord::NoDatabaseErrorが出た時の対処法 | Rails Ambassador ~Railsの伝道師~ Nginxで「could not build server_names_hash...」エラーが出た時の対処方法 - Qiita "The name org.freedesktop.PolicyKit1 was not provided by any .service files"が表示されたら... - Qiita Rails5.2から追加された credentials.yml.enc のキホン - Qiita MySQLのバージョンを5.1から5.7にしてRubyからMySQLに接続する際にlibmysqlclient_ | tackeyy.com 【Rails】Webサーバー「Unicorn」の基本情報と実装方法 - AUTOVICE 【YAML】Railsのdatabase.ymlについてなんとなく分かった気になっていた記法・意味まとめ - Qiita
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Terraform を使って GitHub v2 ソースアクションでコードを取得する CodePipeline を構築する

はじめに GitHub と AWS CodePipeline を連携させようとした際、GitHub v1 ソースアクションが非推奨となり、v2 が推奨になっている事を知りました。 v1 は GitHub から OAuth トークンを払い出し Webhook で連携させます。 v2 は CodeStar SourceConnection を使って GitHub と連携させるようになっていました。 Terraform 上で GitHub v2 ソースアクションを連携させることが出来たので記録を残しておきます。 CodePipeline の Source ステージ に GitHub v2 ソースアクション を設定する点に絞ってこの記事を書きます。 KensukeTakahara/terraform-codepipeline-github で実装したコードを公開しています。 このリポジトリでは Build, Deploy ステージまで含めて CodePipeline を構築しています。 実行環境 Terraform は version 1.0.5、AWS Provider は version 3.58.0 を使用しました。 Terraform で実装 下記のリソースについて実装します。 S3 (アーティファクト格納用) CodeStar Connection CodePipeline S3 (アーティファクト格納用) s3 resource "aws_s3_bucket" "artifact" { bucket = "terraform-codepipeline-github-artifact" } CodePileline がアーティファクトを格納するために必要な S3 バケットです。 CodePileline では次のステージにアーティファクトを引き渡す時、S3 バケットを経由させます。 bucket にはリージョン内でユニークになるよう値を設定します。 CodeStar Connection codestarconnections resource "aws_codestarconnections_connection" "example" { name = "github-connection" provider_type = "GitHub" } provide_type に "GitHub" を指定します。 CodePipeline codepipeline resource "aws_codepipeline" "example" { name = "example" role_arn = aws_iam_role.codepipeline.arn stage { name = "Source" action { name = "Source" category = "Source" owner = "AWS" provider = "CodeStarSourceConnection" version = 1 output_artifacts = ["Source"] configuration = { ConnectionArn = aws_codestarconnections_connection.github.arn FullRepositoryId = "KensukeTakahara/terraform-codepipeline-github" BranchName = "main" OutputArtifactFormat = "CODEBUILD_CLONE_REF" } } } # Build, Deploy ステージの記述は省略 # terraform apply 実行時には必須 artifact_store { location = aws_s3_bucket.artifact.id type = "S3" } } provider に "CodeStarSourceConnection" を指定します。 configuration でリポジトリ名とブランチ名を指定します。 また Build ステージに CodeBuild を使う時は OutputArtifactFormat に "CODEBUILD_CLONE_REF" を指定しましょう。 "CODE_ZIP" を指定すると CodeBuild で使用するメタデータを生成できず、Build ステージで失敗します。 参考 iam data "aws_iam_policy_document" "codepipeline" { statement { effect = "Allow" resources = ["*"] actions = [ "s3:PutObject", "s3:GetObject", "s3:GetObjectVersion", "s3:GetBucketVersioning", "codestar-connections:UseConnection" ] } } resource "aws_iam_policy" "codepipeline" { name = "example-codepipeline-s3-policy" policy = data.aws_iam_policy_document.codepipeline.json } data "aws_iam_policy_document" "assume_role" { statement { actions = ["sts:AssumeRole"] principals { type = "Service" identifiers = ["codepipeline.amazonaws.com"] } } } resource "aws_iam_role" "codepipeline" { name = "example-codepipeline-role" assume_role_policy = data.aws_iam_policy_document.assume_role.json } resource "aws_iam_role_policy_attachment" "example" { role = aws_iam_role.codepipeline.name policy_arn = aws_iam_policy.codepipeline.arn } IAM ロールではアーティファクトバケットと CodeStar Connection へのアクセス権限を設定しましょう。 これは Source ステージに必要な権限だけなので、適宜 Build, Deploy ステージに必要な IAM ポリシーを加えてください。 プロビジョニング terraform apply で実行して AWS 環境にプロビジョニングしても CodePipeline の構築はまだ完了していません。 GitHub 側の認証が必要です。 AWS マネジメントコンソールで CodePipeline を確認してみると、いきなり失敗しています。 失敗の原因は CodeStar Connection のアクセス権限がないとのこと。 なのでコンソール上から「設定」->「接続」を選択して CodeStar Connection を確認しましょう。 「保留中の接続を更新」を選択。 別ウィンドウが出てきて GitHub 接続設定画面が出てきます。 AWS アカウントと GitHub アカウントを連携させます。 対象の GitHub アカウントに AWS Connector for GitHub がない場合は新しくインストールします。 連携が完了すると、CodeStar Connection も接続が確立します。 Source ステージの再試行を実施すると成功します。 まとめ 安全な GitHub v2 ソースアクションが Terraform 上で実装できました。 リソースの設定は Terraform 上でほとんど完結し AWS マネジメントコンソールでは GitHub 側の認証を済ませるだけなので、実装も簡単で管理もしやすいです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Amplify Mock APIの接続先DynamoDBへのアクセス方法

はじめに AWS Amplify Mock APIで起動しているローカルのDynamoDBにアクセスしたい。 AWS Amplifyを使って開発を行うのであれば、別でDynamoDB localを実行するようなことは避けたい。 2021年9月時点 接続情報 { endpoint: "localhost:62224", region: "us-fake-1", accessKeyId: "fake", secretAccessKey: "fake", } AWS SAMを利用してDocker経由でアクセスする場合 { endpoint: "http://host.docker.internal:62224", region: "us-fake-1", accessKeyId: "fake", secretAccessKey: "fake", } 接続時のTableNameは、「schema.graphql」指定のTable名 + "Table"となります。 コメント AWS SAMを使用してLambda関数作成時にDynamoDBに接続できなくてはまりました。 参考 https://github.com/aws-amplify/amplify-cli/blob/24d8085325d435284b9c49a43592e61891fd72bc/packages/amplify-dynamodb-simulator/index.js
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SSMを使ってEC2内のシェルスクリプトを動かす

lamdaから、rubySDKを使いec2内にあるshスクリプトファイルを実行したい。 準備 lamdaにポリシーをアタッチ ①AmazonSSMFullAccess ②AmazonEC2RoleforSSM を与えた。 ざっくり与えすぎてるのでも精査する必要があり。 参考にしないで下さい。。 EC2の準備 最近のversionのec2は最初からSSMエージェントがインストールされているらしいが、 古いEC2などの場合は手動でインストールする必要がある。 東京リージョンのAmazon Linux (x86_64)の場合 ① EC2にエージェントをインストール sudo yum install -y https://s3.ap-northeast-1.amazonaws.com/amazon-ssm-ap-northeast-1/latest/linux_amd64/amazon-ssm-agent.rpm 参考 https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/agent-install-al.html ②EC2にポリシーをアタッチ EC2にくっついてるロールに「AmazonSSMManagedInstanceCore」ポリシーをアタッチする。 実装 以下のようになる。 ssm_client = Aws::SSM::Client.new( region: 'ap-northeast-1') command = 'sh /home/test.sh' resp = ssm_client.send_command({ instance_ids: ["i-06efd939bf8b0fef7"], document_name: "AWS-RunShellScript", timeout_seconds: 3600, comment: "Comment", parameters: { "commands" => [command]} }) send_commandの使い方は以下を参考 https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SSM/Client.html#send_command-instance_method
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

lamdaからEC2でコマンドを実行[AWS Systems Manager�]

lamdaから、rubySDKを使いec2内にあるshスクリプトファイルを実行したい。 AWS Systems Manager (旧称 SSM)を使う。 準備 lamdaにポリシーをアタッチ ①AmazonSSMFullAccess ②AmazonEC2RoleforSSM を与えた。 ざっくり与えすぎてるのでも精査する必要があり。 参考にしないで下さい。。 EC2の準備 最近のversionのec2は最初からSSMエージェントがインストールされているらしいが、 古いEC2などの場合は手動でインストールする必要がある。 東京リージョンのAmazon Linux (x86_64)の場合 ① EC2にエージェントをインストール sudo yum install -y https://s3.ap-northeast-1.amazonaws.com/amazon-ssm-ap-northeast-1/latest/linux_amd64/amazon-ssm-agent.rpm 参考 https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/agent-install-al.html ②EC2にポリシーをアタッチ EC2にくっついてるロールに「AmazonSSMManagedInstanceCore」ポリシーをアタッチする。 実装 以下のようになる。 ssm_client = Aws::SSM::Client.new( region: 'ap-northeast-1') command = 'sh /home/test.sh' resp = ssm_client.send_command({ instance_ids: ["i-06efd939bf8b0fef7"], document_name: "AWS-RunShellScript", timeout_seconds: 3600, comment: "Comment", parameters: { "commands" => [command]} }) send_commandの使い方は以下を参考 https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SSM/Client.html#send_command-instance_method
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

S3バケットを作成してEC2と接続する【備忘録】

はじめに  前記事(EC2サーバー構築の概要【備忘録】)で作成したEC2インスタンスと、AWSストレージサービスであるS3をPHPで接続した時に調べたことの備忘録。  AWSアカウントを作成し、EC2インスタンスのセットアップが完了していることが前提です。  具体的な概要・用語についての記事であり、具体的な手順については割愛しています。 目次 全体の流れ 項目別の詳細 yumとrpm 参考文献 全体の流れ S3セットアップ S3バケット作成 IAMロール作成 EC2インスタンスにIAMロールを割り当て エンドポイントの作成 AWS SDK for PHP でS3に接続 PHPのバージョンアップ Composerインストール AWS SDK for PHPをインストール 項目別の詳細 S3バケット作成  手順通りやればいいので割愛。 IAMロール作成・IAMロールを割り当て  IAM(Identity and Access Management)とは、AWSサービスへのアクセスを安全に行うためのAWSサービス。その機能の一つに、「限定されたアクセス権限を持つロールやユーザーの作成」がある。仮にアクセス情報が漏洩した場合、これらのIAMロール・IAMユーザーを認証に用いていれば、アクセス権限が限定されているため、被害を最小限に抑えられるという利点がある。  また、IAMユーザーとIAMロールの違いは使用方法の違いにある。  IAMユーザーは「アクセス権限を限定されたユーザー」という体でアクセスキーとシークレットキーを設定ファイルなどに記述して認証させるが、IAMロールはAWSコンソールからEC2インスタンスへの割り当て設定をすることで、いちいちキーを記述したりせず自動的に認証をさせることができる。  今回は、EC2とS3の接続にはこのIAMロールを用いた。 エンドポイントの作成  IAMの件と同様、最大限「セキュアな通信」というものを実現させるために作られたシステム。  AWSサービスの中で、EC2はVPC(仮想空間的なもの)内にあり、S3はVPC外にある。EC2がVPC外のサービスと通信をするためにはプライベートネットワークからインターネットへの接続を仲介させる必要があるが、エンドポイントを設定すると、その役割をエンドポイントが担ってくれる。これにより通信の際にインターネットを挟まずに済むため、「セキュアな通信」が可能となる。 PHPのバージョンアップ  AWSサービスとの接続にはAWS SDK for PHPを用いるが、これはPHP5.4に対応していない。しかしながら、yum install phpでPHPを入れると5.4が入ってしまう。  この問題には「パッケージリポジトリ」と「yum」の概念が関係している。  「yum install パッケージ 」は、「登録されたパッケージリポジトリ(色々なパッケージが入ってるフォルダ)から指定されたパッケージをインストールする」という指示を出す。そしてEC2にデフォルトで登録されているAmazon LinuxのパッケージリポジトリにはPHPは5.4しか入っていないため、このような不具合が起きる。  そこで、PHP7.4が入っている外部リポジトリ「remi」を登録し、そこからインストールする。 sudo amazon-linux-extras install epel //amazon linuxリポジトリにepelを追加し、yumでインストールできるようにする //epel-release:remiを入れるために必要なパッケージ sudo yum install epel-release //epel-releaseをインストール sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm //rpmコマンドでremiをインストール sudo yum install -y php74 php74-php php74-php-fpm //PHP7.4をインストール sudo ln -s /usr/bin/php74 /usr/bin/php //php74のシンボリックリンクを作成する(phpコマンドを使えるようにする) 備考:-UvhはオプションU(アップグレード),v(詳細情報),h(進行状況の表示)のまとめ書き。 Composerをインストール  AWS SDK for PHPはComposerからインストールするので、まずはComposerを入れる。  今回はcurlコマンド(ファイルを転送するコマンド。引数にURLを指定することでファイルをダウンロードできる。-sSでエラーメッセージ以外の進捗状況を非表示にする)を用いる。 curl -sS https://getcomposer.org/installer | php //Composerをインストール AWS SDK for PHPをインストール php composer.phar require aws/aws-sdk-php //AWS SDK for PHPをインストール yumとrpm  個人的に気になった部分なので調べた。  rpm(Redhat Package Manager):Red Hat系のLinuxで用いられるパッケージマネージャ。以前はパッケージを入れる際に用いられていたが、依存関係を考慮するのが厄介になってきたため、リポジトリ内の依存関係にあるパッケージをすべてインストールするyumが作られた。現在はリポジトリ単位のパッケージ(remiなど)を入れる際に使われる。  yumはrpmを基に作られているため、併用しても依存関係は崩れない。 参考文献 LaravelでAWS S3へ画像をアップロードする [AWS] VPCエンドポイント経由でEC2からS3へファイル転送 Amazon S3 におけるエンドポイント IAM ロール リポジトリ・yum・rpmについて AWS SDK For PHPを使ってみた
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker Compose で ECS にアプリケーションをデプロイする

初めに 本日 docker-compose を使ってみた記事を書いたので、AWS ECS でも使えないかと調べたところ、ブログで見つけました。いずれ使うときが来るかもしれないのでメモとして残しておきます。 こちらが AWS ECS に Docker Compose でアプリケーションをデプロイする公式ブログになります。 以下の記事も参考にしました。デプロイの詳細な手順について非常にわかりやすく書かれております。 準備 Linux で Docker Compose CLI を使用するための前提条件があります。 1 . Docker Desktop 最新版をダウンロードしインストールしていることが必要です。 Download for Mac Download for Windows あるいは Docker Compose CLI for Linux をインストールしていることが必要です。 2 . AWS アカウントを持っていることが必要です。 こちらのドキュメントを参考にインストールスクリプトを使用します。 curl -L https://raw.githubusercontent.com/docker/compose-cli/main/scripts/install/install_linux.sh | sh AWS コンテキストの生成 このコンテキストにより AWS への認証を行います。aws configure コマンドで認証情報をローカルに登録後、以下のコマンドを実行します。 docker context create ecs myecscontext なお、このコマンド実行時、以下のエラーが発生しました。インスタンスに再ログインしたところ、正常に動作しました。 "docker context create" requires exactly 1 argument. when docker context create ecs myecscontext is executed An existing AWS profile を選択します。 [ec2-user@ip-172-31-39-188 compose]$ docker context create ecs myecscontext ? Create a Docker context using: [Use arrows to move, type to filter] > An existing AWS profile AWS secret and token credentials AWS environment variables ECS へデプロイ 以下の記事で使用したアプリケーションを使用します。 編集前 docker-compose.yml version: '3' services: web: build: . ports: - "8080:5000" volumes: - .:/code redis: image: "redis:alpine" 編集後 docker-compose.yml version: '3' services: web: image: "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/web-app:latest" ports: - "5000:5000" redis: image: "redis:alpine" flask イメージはビルドではなく、ECR にプッシュしておきます。 ポート番号を 5000:5000 に変更したのは、docker compose up コマンド実行時に以下のエラーが発生したためです。 published port can't be set to a distinct value than container port: incompatible attribute コンテキストを切り替えます。 docker context use myecscontext 現在のコンテキストを確認するには docker context ls コマンドを実行します。 [ec2-user@ip-172-31-39-188 compose]$ docker context ls NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR default moby Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm myecscontext * ecs コンテキストを切り替えた後ですが、通常の docker コマンドは使用できなくなるようです。例えば docker ps は使えなくなりました。 [ec2-user@ip-172-31-39-188 compose]$ docker ps Command "ps" not available in current context (myecscontext) こういった場合、コンテキストをデフォルトに戻します。 docker context use default compose コマンドで ECS ヘアプリケーションをデプロイします。 docker compose up 以下はコマンド実行中です。完了すると、すべて青色に変わり、ユーザー入力を受け付けるようになります。 デプロイの後、http://NLB の DNS 名:ポート番号 にアクセスします。これは例えば以下のような URL です。 http://compo-loadb-1grujljfn1mmd-06b3d6a23c13c06a.elb.ap-northeast-1.amazonaws.com:5000/ リソース削除には以下のコマンドを実行します。 docker compose down AWS リソースの確認 docker compose up によって新規に作成されたリソースを確認します。VPC、サブネット、セキュリティグループはデフォルトのものが用いられていました。 クラスター クラスター名ですが、ローカルマシンの docker-compose.yml ファイルが存在するディレクトリのディレクトリ名が付けられていました。 サービス flask タスクと redis タスクのサービスがそれぞれ作成されています。 NLB 参考記事
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

以前リファクタリングしたスクレイピングバッチアプリをAWS Lambdaへアップロードしてみた。

はじめに 以前リファクタリングしたこちらのスクレイピングバッチアプリを今回はAWS Lambdaへアップロードしてみました。 今回はその手順を備忘録として残しておこうと思います。 AWS Toolkit for Visual Studioのインストール こちらからダウンロード&インストールを行います。 既存のASP.NET Coreプロジェクトのフレームワークを.NET 5から.NET Core 3.1へ変更する 調べた感じですと、まだAWS Lambdaでは.NET 5がサポートされていないようだったので.NET Core3.1へフレームワークを変更しました。 既存のASP.NET CoreプロジェクトファイルへAWS情報を入れる。 PropertyGroup要素へ以下を追加します。 ScrapingApp.csproj <AWSProjectType>Lambda</AWSProjectType> <!-- This property makes the build directory similar to a publish directory and helps the AWS .NET Lambda Mock Test Tool find project dependencies. --> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> 上記の設定後、プロジェクトを右クリックするとLambdaへの公開オプションが見れるようになります。 AWS Explorerの設定 "表示" > "AWS Explorer"を選択すると画面左側にAWS Explorerが表示されるので赤枠部分をクリックします。 アカウント情報を入力します。 ProfileNameは任意の値を入れ、Access Key IDやSecret Access Keyは任意のIAMユーザの情報を入れて"OK"ボタンを押します。 AWS Lambdaへアップロードする プロジェクトを右クリックし、"Publish to AWS Lambda..."を選択します。 選択後、以下の画面が出てくるかと思います。 それぞれの項目へ値を入れていきます。 ラベル名 説明 Package Type Lambdaへのアップロード形式 Lambda Runtime ランタイム情報 Function Name Lambda関数の名前(任意の名前を入力) Description Lambda関数の説明 Configuration Release Framework netcoreapp3.1 Assembly アセンブリ名(デフォルトではプロジェクト名になっていると思います) Type プロジェクト名.エントリーポイントのクラス名 Method エントリーポイント "Next"をクリックすると以下の画面が表示されます。 Role Nameには任意のRoleを割り当てます(ない場合は作成する必要があります。) "Memory"項目ではLambda 関数が使用できるメモリの量を設定し、"Timeout"項目ではタイムアウトさせる時間を設定します。 設定完了後、"Upload"ボタンをクリックします。 アップロードが完了するまで待ちます。 完了したらAWS Lambdaへアップロードされていることが確認できます。 おわりに 今回はAWS Lambdaへアップロードした内容のみですが、後々はAmazon EventBridgeと組み合わせて定期的に動くようにしていきたいと思います!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

"context requires credentials to be passed as environment variables"の対処法

エラー内容 Docker ComposeのAmazon ECSデプロイを試してみた 上の記事を参考にAWSのコンテナ基盤であるECSの概要を理解しようとぽちぽち触っていたところ、contextを作成するために下のコードを実行すると記事にはない選択項目が出現。 $ docker context create ecs myecscontext ↓ > AWS secret and token credentials AWS environment variables 挙動を確認するためと軽い気持ちで2つめのAWS environment variablesを選択したところ, contextの作成に成功したようですが記事のように内容の入力が求められませんでした。 Successfully created ecs context "myecscontext" 気にせず作成したcontextをuseするために下のコードを実行すると悲劇が起きました。 $ docker context use myecscontext docker compose upすると $ docker compose up ↓ context requires credentials to be passed as environment variables 当然何も入力していないcontextなのでこういう挙動なのだなと確認してcontextをdefaultに戻そうとすると $ docker context ls ↓ context requires credentials to be passed as environment variables contextが確認できません。 確認はできなくてもdefaultに戻せれば...と思って実行するも $ docker context use default ↓ context requires credentials to be passed as environment variables 完全にハマってしまいました。コマンド操作をするために元に戻す操作自体ができなくなってしまったのです。 しかしエラー文であるcontext requires credentials to be passed as environment variablesで検索しても全然情報が出てきません。 日本語の情報だけでは解決策がなかったのでついに愛用のMacを詰ませてしまったかと覚悟しましたが、英語のstackoverflowにて同じ悩みを抱えている人を発見。その方も情報が少ないことに悩んでいるようでしたが、回答者の1人が解決策を提示していました。。 Passing environment variables to docker-compose when using ecs context 解決策 $ AWS_SECRET_ACCESS_KEY=dummy AWS_ACCESS_KEY_ID=dummy AWS_DEFAULT_REGION=dummy docker context ls NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR default moby Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm myecscontext * ecs credentials read from environment $ AWS_SECRET_ACCESS_KEY=dummy AWS_ACCESS_KEY_ID=dummy AWS_DEFAULT_REGION=dummy docker context use default default $ docker context ls NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR default * moby Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm myecscontext ecs credentials read from environment $ docker context rm myecscontext myecscontext まとめ どうやらAWS environment variablesは文字通りAWSの環境変数を直接ターミナルに打ち込んでデプロイ できる仕組みのようでデタラメでも何かしらを環境変数に代入して実行する必要があったようです。 もちろん何がわからないかもわからない状態で操作してしまった私に非がありますが、どう言ったテンプレートで入力するべき状況で起きているエラーなのかを最低限エラーメッセージとして書いていて欲しかったなと感じました。 今の私には自力でこの解決方法にたどり着くことは不可能だったので、私のように時間を取られる人が1人でも減るように共有したいと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS CLI復習◆Cloud9用VPCの構築

JAWS-UG CLI専門支部でのハンズオンを参考に、AWS CLIの復習として投稿します。 JAWS-UG CLI専門支部とは? VPCを作ろう 1.今回の目的 VPCをCLIで作成していくのですが、今回は「Cloud9環境用のVPC」を作っていきたいと思います。 Cloud9環境全体イメージを以下としますと、 緑のVPCの部分、ネットワーク周りをCloudShellからCLIで作成します。 私のアカウントには現在、タグなしデフォルトVPCと、JAWS-UG CLI専門支部用のハンズオンVPCがあります。 2.前提条件 以下アクセス権のあるユーザで実施してください。 AWSCloudShellFullAccess AmazonVPCFullAccess また、VPCは各リージョン5つまでというソフトクォータがありますので、既存のVPCが既に5つある場合は1つ以上VPCを削除するか、VPCを作成していない別リージョンに読み替えて実施してください。 3.Cloud9用VPCの構築 JAWS-UG CLI専門支部 以下手順を参考にします。 事前作業1.1. VPCの構築 (CloudShell: handson-cloud9-vpc) まずはVPCの枠の部分だけ作っていきます。 AWSマネジメントコンソールのCloudShellアイコンをクリックしてCloudShellを開いていきます。 ようこそ的な画面は「Close」で閉じます。 10秒くらい待ちます。 CloudShellが立ち上がってきたら、コマンドを打ち込んでいきます。 リージョン確認 右上のリージョンメニューから"東京 "を選択しておきます。 (読み替えられる方は別のリージョンでも構いません) VPCのタグ名 EC2_VPC_TAG_NAMEという変数に、VPCのタグ名を指定します。私はコーヒーが好きなのでcloud9-coffee-vpcとタグ名を付けましょう。 EC2_VPC_TAG_NAME='cloud9-coffee-vpc' VPCのアドレスレンジ設定 EC2_VPC_CIDRという変数に、VPCのアドレスレンジを指定します。 プライベートIPアドレスってなんだ?という方はこちらへ(@ITのサイトにとびます) プライベートアドレスの範囲は以下のように決まっています。 クラスA:10.0.0.0~10.255.255.255 (10.0.0.0/8) クラスB:172.16.0.0~172.31.255.255 (172.16.0.0/12) クラスC:192.168.0.0~192.168.255.255 (192.168.0.0/16) この範囲の中から好きなIPアドレスを割り当てればいいのですが、今回はCloud9環境を個人の練習用にたてたいだけなので、深く考えなくてもよいです。 「お仕事で今後IPアドレスがたくさん必要!」とか、「ほかのVPCとかぶらないようにしないといけない!」というときはよく考えてあげてください。 ハンズオンではクラスAとかクラスCとか使いがちな気がするので、今回はクラスBのIPアドレス範囲を指定してみましょう。 172.16.0.0~172.16.255.255(172.16.0.0/16)を設定します。 EC2_VPC_CIDR='172.16.0.0/16' ヒアドキュメントで、変数に値が正しく入っているか確認します。 cat << END # 0. AWS_REGION:"ap-northeast-1" AWS_REGION="${AWS_REGION}" # 1. EC2_VPC_TAG_NAME:"cloud9-coffee-vpc" EC2_VPC_TAG_NAME="${EC2_VPC_TAG_NAME}" # 2. EC2_VPC_CIDR:"172.16.0.0/16" EC2_VPC_CIDR="${EC2_VPC_CIDR}" END 出力例 # 0. AWS_REGION:"ap-northeast-1" AWS_REGION="ap-northeast-1" # 1. EC2_VPC_TAG_NAME:"cloud9-coffee-vpc" EC2_VPC_TAG_NAME="cloud9-coffee-vpc" # 2. EC2_VPC_CIDR:"172.16.0.0/16" EC2_VPC_CIDR="172.16.0.0/16" 上下の文字列が同じであれば、変数に正しい値が格納されています。 (ちょっと脱線)ヒアドキュメントとはなんぞや AWS_REGIONという変数は、環境変数です。最初に選択したリージョン名が自動的に格納されています。 参考(IT用語辞典 e-words様)環境変数 【environment variables】 VPCのタグ文字列設定 EC2_VPC_TAG_NAMEという変数でVPCのタグ名を指定しましたが、次はSTRING_EC2_VPC_TAGという変数にタグ文字列を格納します。 リソースタイプ=vpcと指定します。 また、タグの要素は「key」と「value」です。keyにName、valueにcloud9-coffee-vpcを格納します。 STRING_EC2_VPC_TAG="ResourceType=vpc,Tags=[{Key=Name,Value=${EC2_VPC_TAG_NAME}}]" \ && echo ${STRING_EC2_VPC_TAG} 出力例 ResourceType=vpc,Tags=[{Key=Name,Value=cloud9-coffee-vpc}] ヒアドキュメントで、変数に値が正しく入っているか確認します。 cat << END # STRING_EC2_VPC_TAG:"ResourceType=vpc,Tags=[{Key=Name,Value=cloud9-coffee-vpc}]" STRING_EC2_VPC_TAG="${STRING_EC2_VPC_TAG}" END 出力例 # STRING_EC2_VPC_TAG:"ResourceType=vpc,Tags=[{Key=Name,Value=cloud9-coffee-vpc}]" STRING_EC2_VPC_TAG="ResourceType=vpc,Tags=[{Key=Name,Value=cloud9-coffee-vpc}]" 上下の文字列が同じであれば、変数に正しい値が格納されています。 VPC作成 VPCを作成します。 aws ec2 create-vpc \ --cidr-block ${EC2_VPC_CIDR} \ --tag-specifications ${STRING_EC2_VPC_TAG} 出力例 { "Vpc": { "VpcId": "vpc-xxxxxxxxxxxxxxxxx", "InstanceTenancy": "default", "Tags": [ "Value": "cloud9-coffee-vpc", "Key": "Name" ], "CidrBlockAssociationSet": [ { "AssociationId": "vpc-cidr-assoc-xxxxxxxx", "CidrBlock": "172.16.0.0/16", "CidrBlockState": { "State": "associated" } } ], "Ipv6CidrBlockAssociationSet": [], "State": "pending", "DhcpOptionsId": "dopt-xxxxxxxx", "CidrBlock": "vpc-xxxxxxxxxxxxxxxxx", "OwnerId": "XXXXXXXXXXXX", "IsDefault": false } } aws ec2 create-vpc VPCを作成する --cidr-block VPCのIPアドレス範囲(CIDRブロック)を指定する --tag-specifications VPCにタグ付けする (ちょっと脱線)VPCを操作するのにCLIコマンドが「aws ec2」? マネジメントコンソール上のサービスとしては「VPC」と独立していますが、APIとしてはVPCは「EC2」のAPIの中に含まれています。公式リファレンス検索の際には気を付けてください。 マネジメントコンソール CLI(API) VPC EC2 EC2 EC2 AWS創設(?)当時はVPCというサービスがなく、EC2だけがポンと立てられるようになっていた時代があったそうです(今でいうクラシックEC2というもの、らしい)。EC2サービスがその後拡張してネットワーキングの設定も細かくできるようになって、VPCというサービスに発展したらしく、そのような歴史があってVPCのAPIはEC2のAPIに含まれてしまっているようです。 (脱線ここまで) VPCが作成できているか確認 では、"cloud9-coffee-vpc"なんてタグ名がついたVPCができているかを確認します。 aws ec2 describe-vpcs \ --filters Name=tag:Name,Values=${EC2_VPC_TAG_NAME} \ --query 'Vpcs[].Tags[?Key == `Name`].Value' \ --output text 出力例 cloud9-coffee-vpc aws ec2 describe-vpcs VPCの詳細を出力する --filters より具体的なリストを返すためのフィルター名と値のペア。フィルタを使用して、タグ、属性、IDなどの特定の基準によってリソースをフィルタする。 Name=tag:Name:フィルタの名前(今回はタグのkeyがName) Values=${EC2_VPC_TAG_NAME}:フィルタの値(今回はタグのvalueがcloud9-coffee-vpc) --query 'Vpcs[].Tags[?Key == `Name`].Value' 応答データのフィルタリングに使用するJMESPathクエリ。今回は、VPCの中で、keyがNameなものの中でvalue項目だけ出力させる --output text 出力のフォーマットをテキスト文書に指定 filterとqueryの使い分けはまた別にまとめたいと思っているのですが、大まかに以下のような使い分けになるようです。 フィルター:出力結果の絞り込み(--filters) クエリー:出力項目の絞り込み(--query) 参考(Developer IO様)AWS CLIのフィルターとクエリーの使い方についてまとめてみた 次に、VPC"cloud9-coffee-vpc"のCIDRが"172.16.0.0/16"であることを確認します。 aws ec2 describe-vpcs \ --filters Name=tag:Name,Values=${EC2_VPC_TAG_NAME} \ --query "Vpcs[].CidrBlock" \ --output text 出力例 172.16.0.0/16 --query "Vpcs[].CidrBlock" VPCの中のCidrBlockという項目を表示させる ここでCloudShellのセッションはいったん切断します。 以後の操作で変数汚染を防ぐため、Ctr+Dで接続を切断します。 再度CloudShellから操作する際はEnterでCloudShellに再接続します。 マネジメントコンソール上でも、新しく「cloud9-coffee-vpc」というタグのついたVPCが作成されているのが確認できます。 ※表示されない場合は少し待ってからブラウザをリロードするか、選択しているリージョンが"東京"であることを確認してください。 4.Cloud9用VPCにアタッチするインターネットゲートウェイの作成 JAWS-UG CLI専門支部 以下手順を参考にします。 事前作業1.2. インターネットゲートウェイの作成 (CloudShell: handson-cloud9-internet-gateway) インターネットゲートウェイを作成します。 リージョン確認 右上のリージョンメニューから"東京"を選択しておきます。 VPC作成時に東京以外のリージョンを選択した方は、作成したVPCと同じリージョンにしておいてください。 インターネットゲートウェイのタグ名 EC2_INTERNET_GATEWAY_TAG_NAMEという変数に、インターネットゲートウェイのタグ名を格納します。 私はコーヒーが好きなのでcloud9-coffee-internet-gatewayとタグ名を付けましょう。 EC2_INTERNET_GATEWAY_TAG_NAME='cloud9-coffee-internet-gateway' ヒアドキュメントで、変数に値が正しく入っているか確認します。 cat << END # 0. AWS_REGION:"ap-northeast-1" AWS_REGION="${AWS_REGION}" # 1. EC2_INTERNET_GATEWAY_TAG_NAME:"cloud9-coffee-internet-gateway" EC2_INTERNET_GATEWAY_TAG_NAME="${EC2_INTERNET_GATEWAY_TAG_NAME}" END 出力例 # 0. AWS_REGION:"ap-northeast-1" AWS_REGION="ap-northeast-1" # 1. EC2_INTERNET_GATEWAY_TAG_NAME:"cloud9-coffee-internet-gateway" EC2_INTERNET_GATEWAY_TAG_NAME="cloud9-coffee-internet-gateway" 上下の文字列が同じであれば、変数に正しい値が格納されています。 繰り返しますがAWS_REGIONという変数は、環境変数です。 インターネットゲートウェイのタグ文字列設定 次はSTRING_EC2_INTERNET_GATEWAY_TAGという変数にインターネットゲートウェイのタグ文字列を格納します。 リソースタイプ=internet-gatewayと指定します。 また、タグはkeyにName、valueにcloud9-coffee-internet-gatewayを格納します。 STRING_EC2_INTERNET_GATEWAY_TAG="ResourceType=internet-gateway,Tags=[{Key=Name,Value=${EC2_INTERNET_GATEWAY_TAG_NAME}}]" \ && echo ${STRING_EC2_INTERNET_GATEWAY_TAG} 出力例 ResourceType=internet-gateway,Tags=[{Key=Name,Value=cloud9-coffee-internet-gateway}] ヒアドキュメントで、変数に値が正しく入っているか確認します。 cat << END # STRING_EC2_INTERNET_GATEWAY_TAG:"ResourceType=internet-gateway,Tags=[{Key=Name,Value=cloud9-coffee-internet-gateway}]" STRING_EC2_INTERNET_GATEWAY_TAG="${STRING_EC2_INTERNET_GATEWAY_TAG}" END 出力例 # STRING_EC2_INTERNET_GATEWAY_TAG:"ResourceType=internet-gateway,Tags=[{Key=Name,Value=cloud9-coffee-internet-gateway}]" STRING_EC2_INTERNET_GATEWAY_TAG="ResourceType=internet-gateway,Tags=[{Key=Name,Value=cloud9-coffee-internet-gateway}]" インターネットゲートウェイの作成 それではインターネットゲートウェイを作成します。 aws ec2 create-internet-gateway \ --tag-specifications ${STRING_EC2_INTERNET_GATEWAY_TAG} 出力例 { "InternetGateway": { "Attachments": [] "InternetGatewayId": "igw-xxxxxxxxxxxxxxxxx", "OwnerId": "XXXXXXXXXXXX", "Tags": [ { "Key": "Name", "Value": "cloud9-coffee-internet-gateway" } } } aws ec2 create-internet-gateway インターネットゲートウェイを作成する --tag-specifications タグ名を指定する インターネットゲートウェイが作成できているか確認 では、"cloud9-coffee-internet-gateway"なんてタグ名がついたインターネットゲートウェイができているかを確認します。 aws ec2 describe-internet-gateways \ --filters Name=tag:Name,Values=${EC2_INTERNET_GATEWAY_TAG_NAME} \ --query "InternetGateways[].Tags[].Value" \ --output text 出力例 cloud9-coffee-internet-gateway ここでCloudShellのセッションはいったん切断します。 以後の操作で変数汚染を防ぐため、Ctr+Dで接続を切断します。 再度CloudShellから操作する際はEnterでCloudShellに再接続します。 マネジメントコンソール上でも、新しく「cloud9-coffee-internet-gateway」というタグのついたインターネットゲートウェイが作成されているのが確認できます。 ※表示されない場合は少し待ってからブラウザをリロードするか、選択しているリージョンが"東京"であることを確認してください。 5.Cloud9用VPCにインターネットゲートウェイをアタッチする JAWS-UG CLI専門支部 以下手順を参考にします。 事前作業1.3. インターネットゲートウェイのアタッチ (CloudShell: handson-cloud9-vpc : handson-cloud9-internet-gateway) インターネットゲートウェイをVPCにアタッチしていきます。 リージョン確認 右上のリージョンメニューから"東京"を選択しておきます。 VPC作成時に東京以外のリージョンを選択した方は、作成したVPCと同じリージョンにしておいてください。 VPCとインターネットゲートウェイのタグ名 インターネットゲートウェイをVPCにアタッチするために、各タグ名を変数に格納しておきます。 VPCタグ名として、EC2_VPC_TAG_NAMEにはcloud9-coffee-vpcを格納します。 インターネットゲートウェイタグ名として、EC2_INTERNET_GATEWAY_TAG_NAMEにはcloud9-coffee-internet-gatewayを格納します。 EC2_VPC_TAG_NAME='cloud9-coffee-vpc' EC2_INTERNET_GATEWAY_TAG_NAME='cloud9-coffee-internet-gateway' ヒアドキュメントで、変数に値が正しく入っているか確認します。 cat << END # 0. AWS_REGION:"ap-northeast-1" AWS_REGION="${AWS_REGION}" # 1. EC2_VPC_TAG_NAME:"cloud9-coffee-vpc" EC2_VPC_TAG_NAME="${EC2_VPC_TAG_NAME}" # 2. EC2_INTERNET_GATEWAY_TAG_NAME:"cloud9-coffee-internet-gateway" EC2_INTERNET_GATEWAY_TAG_NAME="${EC2_INTERNET_GATEWAY_TAG_NAME}" END 出力例 # 0. AWS_REGION:"ap-northeast-1" AWS_REGION="ap-northeast-1" # 1. EC2_VPC_TAG_NAME:"cloud9-coffee-vpc" EC2_VPC_TAG_NAME="cloud9-coffee-vpc" # 2. EC2_INTERNET_GATEWAY_TAG_NAME:"cloud9-coffee-internet-gateway" EC2_INTERNET_GATEWAY_TAG_NAME="cloud9-coffee-internet-gateway" 上下の文字列が同じであれば、変数に正しい値が格納されています。 AWS_REGIONという変数は、環境変数です。 VPCとインターネットゲートウェイのID取得 インターネットゲートウェイをVPCにアタッチするために、該当のVPCとインターネットゲートウェイのIDが必要になります。そのIDを抽出して変数に格納していきます。 まずVPC IDを取得します。 EC2_VPC_IDという変数に、抽出したVPC IDを格納します。 EC2_VPC_ID=$( \ aws ec2 describe-vpcs \ --filters Name=tag:Name,Values=${EC2_VPC_TAG_NAME} \ --query 'Vpcs[].VpcId' \ --output text \ ) \ && echo ${EC2_VPC_ID} 出力例 vpc-xxxxxxxxxxxxxxxxx --query 'Vpcs[].VpcId' VPCの中でVpcIdという項目を表示する VPC IDは実施する環境によって違いますので、vpc-xxxxxxxxxxxxxxxxxとしています。 CloudShell上ではIDの数字が表示されているはずです。 次にインターネットゲートウェイIDを取得します。 EC2_INTERNET_GATEWAY_IDという変数に、抽出したインターネットゲートウェイIDを格納します。 EC2_INTERNET_GATEWAY_ID=$( \ aws ec2 describe-internet-gateways \ --filters Name=tag:Name,Values=${EC2_INTERNET_GATEWAY_TAG_NAME} \ --query "InternetGateways[].InternetGatewayId" \ --output text \ ) \ && echo ${EC2_INTERNET_GATEWAY_ID} 出力例 igw-xxxxxxxxxxxxxxxxx --query "InternetGateways[].InternetGatewayId" インターネットゲートウェイの中でInternetGatewayIdという項目を表示する インターネットゲートウェイIDは実施する環境によって違いますので、igw-xxxxxxxxxxxxxxxxxとしています。 CloudShell上ではIDの数字が表示されているはずです。 ヒアドキュメントで、変数に値が正しく入っているか確認します。 cat << END # EC2_VPC_ID:"vpc-xxxxxxxxxxxxxxxxx" EC2_VPC_ID="${EC2_VPC_ID}" # EC2_INTERNET_GATEWAY_ID:"igw-xxxxxxxxxxxxxxxxx" EC2_INTERNET_GATEWAY_ID="${EC2_INTERNET_GATEWAY_ID}" END 出力例 # EC2_VPC_ID:"vpc-xxxxxxxxxxxxxxxxx" EC2_VPC_ID="vpc-xxxxxxxxxxxxxxxxx" # EC2_INTERNET_GATEWAY_ID:"igw-xxxxxxxxxxxxxxxxx" EC2_INTERNET_GATEWAY_ID="igw-xxxxxxxxxxxxxxxxx" インターネットゲートウェイをVPCにアタッチする インターネットゲートウェイをVPCにアタッチしていきます。 aws ec2 attach-internet-gateway \ --vpc-id ${EC2_VPC_ID} \ --internet-gateway-id ${EC2_INTERNET_GATEWAY_ID} (出力なし) aws ec2 attach-internet-gateway インターネットゲートウェイをアタッチするコマンド --vpc-id インターネットゲートウェイをアタッチするVPC IDを指定 --internet-gateway-id アタッチするインターネットゲートウェイIDを指定 インターネットゲートウェイがVPCにアタッチされているか確認 VPCcloud9-coffee-vpcにインターネットゲートウェイcloud9-coffee-internet-gatewayがアタッチされていることを確認します。 aws ec2 describe-internet-gateways \ --filters Name=tag:Name,Values=${EC2_INTERNET_GATEWAY_TAG_NAME} \ --query "InternetGateways[].Attachments[?VpcId == \`${EC2_VPC_ID}\`].VpcId" \ --output text 出力例 vpc-xxxxxxxxxxxxxxxxx aws ec2 describe-internet-gateways インターネットゲートウェイの詳細を表示する --filters Name=tag:Name,Values=${EC2_INTERNET_GATEWAY_TAG_NAME} 表示したいkeyがName、valueがcloud9-coffee-internet-gatewayであるインターネットゲートウェイを検索する --query "InternetGateways[].Attachments[?VpcId == \`${EC2_VPC_ID}\`].VpcId" アタッチされているインターネットゲートウェイの中でVpcIdがcloud9-coffee-vpcであるもののVPC IDを表示させる ここでCloudShellのセッションはいったん切断します。 以後の操作で変数汚染を防ぐため、Ctr+Dで接続を切断します。 再度CloudShellから操作する際はEnterでCloudShellに再接続します。 マネジメントコンソール上でも、「cloud9-coffee-internet-gateway」というタグのついたインターネットゲートウェイが「cloud9-coffee-vpc」というタグのついたVPCにアタッチされているのが確認できます。 ※表示されない場合は少し待ってからブラウザをリロードするか、選択しているリージョンが"東京"であることを確認してください。 6.Cloud9用VPC内のサブネットに紐づけるルートテーブルを作成する JAWS-UG CLI専門支部 以下手順を参考にします。 事前作業1.4. ルートテーブルの作成 (CloudShell: handson-cloud9-route-table) ルートテーブルは後ほど中にルーティング情報を設定してサブネットに紐づけます。 まずは空っぽのルートテーブルの枠だけ作成します。 リージョン確認 右上のリージョンメニューから"東京"を選択しておきます。 VPC作成時に東京以外のリージョンを選択した方は、作成したVPCと同じリージョンにしておいてください。 VPCのタグ名 ルートテーブルを作成する際、ルートテーブルが紐づくサブネットが含まれる(サブネットはこの後作成するのですが)VPCのIDが必要になります。VPC IDを抽出するのにVPCのタグ名が必要になるため、変数にVPCのタグ名を格納しておきます。 EC2_VPC_TAG_NAME='cloud9-coffee-vpc' ルートテーブルのタグ名 EC2_ROUTE_TABLE_TAG_NAMEという変数に、ルートテーブルのタグ名を指定します。私はコーヒーが好きなのでcloud9-coffee-route-tableとタグ名を付けましょう。 EC2_ROUTE_TABLE_TAG_NAME='cloud9-coffee-route-table' ヒアドキュメントで、変数に値が正しく入っているか確認します。 cat << END # 0. AWS_REGION:"ap-northeast-1" AWS_REGION="${AWS_REGION}" # 1. EC2_VPC_TAG_NAME:"cloud9-coffee-vpc" EC2_VPC_TAG_NAME="${EC2_VPC_TAG_NAME}" # 2. EC2_ROUTE_TABLE_TAG_NAME:"cloud9-coffee-route-table" EC2_ROUTE_TABLE_TAG_NAME="${EC2_ROUTE_TABLE_TAG_NAME}" END 出力例 # 0. AWS_REGION:"ap-northeast-1" AWS_REGION="ap-northeast-1" # 1. EC2_VPC_TAG_NAME:"cloud9-coffee-vpc" EC2_VPC_TAG_NAME="cloud9-coffee-vpc" # 2. EC2_ROUTE_TABLE_TAG_NAME:"cloud9-coffee-route-table" EC2_ROUTE_TABLE_TAG_NAME="cloud9-coffee-route-table" 上下の文字列が同じであれば、変数に正しい値が格納されています。 AWS_REGIONという変数は、環境変数です。 VPC IDの取得 ルートテーブル作成時、VPC IDが必要になる話を先ほどしました。早速VPC IDを抽出してEC2_VPC_IDという変数に格納していきます。 EC2_VPC_ID=$( \ aws ec2 describe-vpcs \ --filters Name=tag:Name,Values=${EC2_VPC_TAG_NAME} \ --query 'Vpcs[].VpcId' \ --output text \ ) \ && echo ${EC2_VPC_ID} 出力例 vpc-xxxxxxxxxxxxxxxxx ルートテーブルのタグ文字列設定 次はSTRING_EC2_ROUTE_TABLE_TAGという変数にルートテーブルのタグ文字列を格納します。 リソースタイプ=route-tableと指定します。 また、タグはkeyにName、valueにcloud9-coffee-route-tableを格納します。 STRING_EC2_ROUTE_TABLE_TAG="ResourceType=route-table,Tags=[{Key=Name,Value=${EC2_ROUTE_TABLE_TAG_NAME}}]" \ && echo ${STRING_EC2_ROUTE_TABLE_TAG} 出力例 ResourceType=route-table,Tags=[{Key=Name,Value=cloud9-coffee-route-table}] ヒアドキュメントで、変数に値が正しく入っているか確認します。 cat << END # EC2_VPC_ID:"vpc-xxxxxxxxxxxxxxxxx" EC2_VPC_ID="${EC2_VPC_ID}" # STRING_EC2_ROUTE_TABLE_TAG:"ResourceType=route-table,Tags=[{Key=Name,Value=cloud9-coffee-route-table}]" STRING_EC2_ROUTE_TABLE_TAG="${STRING_EC2_ROUTE_TABLE_TAG}" END 出力例 # EC2_VPC_ID:"vpc-xxxxxxxxxxxxxxxxx" EC2_VPC_ID="vpc-xxxxxxxxxxxxxxxxx" # STRING_EC2_ROUTE_TABLE_TAG:"ResourceType=route-table,Tags=[{Key=Name,Value=cloud9-coffee-route-table}]" STRING_EC2_ROUTE_TABLE_TAG="ResourceType=route-table,Tags=[{Key=Name,Value=cloud9-coffee-route-table}]" ルートテーブル作成 ルートテーブルを作成します。 aws ec2 create-route-table \ --vpc-id ${EC2_VPC_ID} \ --tag-specifications ${STRING_EC2_ROUTE_TABLE_TAG} 出力例 { "RouteTable": { "Associations": [], "PropagatingVgws": [], "RouteTableId": "rtb-xxxxxxxxxxxxxxxxx", "VpcId": "vpc-xxxxxxxxxxxxxxxxx", "Tags": [ { "Key": "Name", "Value": "cloud9-coffee-route-table" } ], "OwnerId": "XXXXXXXXXXXX", "Routes": [ { "GatewayId": "local", "DestinationCidrBlock": "172.16.0.0/16", "State": "active", "Origin": "CreateRouteTable" } ] } } aws ec2 create-route-table ルートテーブルを作成する --vpc-id VPC IDを指定する --tag-specifications ルートテーブルのタグ名を指定する ルートテーブルが作成できているか確認 では、"cloud9-coffee-route-table"なんてタグ名がついたルートテーブルができているかを確認します。 aws ec2 describe-route-tables \ --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_ROUTE_TABLE_TAG_NAME} \ --query "RouteTables[].Tags[?Key == \`Name\`].Value" \ --output text 出力例 handson-cloud9-route-table aws ec2 describe-route-tables ルートテーブルの詳細を表示する --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_ROUTE_TABLE_TAG_NAME} \ ここで--filterオプションを使ってAND検索しています。 VPC ID(vpc-id)が"vpc-xxxxxxxxxxxxxxxxx(取得したVPC ID)"かつタグ名が"cloud9-coffee-route-table"のAND検索をしているというわけです。 --query "RouteTables[].Tags[?Key == \`Name\`].Value" key=Nameであるタグのvalue値を表示する ここでCloudShellのセッションはいったん切断します。 以後の操作で変数汚染を防ぐため、Ctr+Dで接続を切断します。 再度CloudShellから操作する際はEnterでCloudShellに再接続します。 マネジメントコンソール上でも、新しく「cloud9-coffee-route-table」というタグのついたルートテーブルが作成されているのが確認できます。 ※表示されない場合は少し待ってからブラウザをリロードするか、選択しているリージョンが"東京"であることを確認してください。 7.ルートテーブルにルート設定する JAWS-UG CLI専門支部 以下手順を参考にします。 事前作業1.5. ルートの作成 (CloudShell: インターネットゲートウェイ: 0.0.0.0/0) ルートテーブル"cloud9-coffee-route-table"に、宛先"0.0.0.0/0"へのゲートウェイがインターネットゲートウェイ"cloud9-coffee-internet-gateway"となるルートを作成します。 リージョン確認 右上のリージョンメニューから"東京"を選択しておきます。 VPC作成時に東京以外のリージョンを選択した方は、作成したVPCと同じリージョンにしておいてください。 VPCとルートテーブルのタグ名 ルートテーブルにルート設定する際、VPC IDとルートテーブルIDとインターネットゲートウェイIDが必要になります。各種IDを抽出するために、タグ名を変数に格納しておきます。 EC2_VPC_TAG_NAME='cloud9-coffee-vpc' EC2_ROUTE_TABLE_TAG_NAME='cloud9-coffee-route-table' EC2_INTERNET_GATEWAY_TAG_NAME='cloud9-coffee-internet-gateway' 宛先アドレス(0.0.0.0/0) 宛先アドレス(インターネット向け:0.0.0.0/0)を指定します。 EC2_ROUTE_DESTINATION_CIDRという変数に、IPアドレスCIDR範囲0.0.0.0/0を格納します。 EC2_ROUTE_DESTINATION_CIDR='0.0.0.0/0' ヒアドキュメントで、変数に値が正しく入っているか確認します。 cat << END # 0. AWS_REGION:"ap-northeast-1" AWS_REGION="${AWS_REGION}" # 1. EC2_VPC_TAG_NAME:"cloud9-coffee-vpc" EC2_VPC_TAG_NAME="${EC2_VPC_TAG_NAME}" # 2. EC2_ROUTE_TABLE_TAG_NAME:"cloud9-coffee-route-table" EC2_ROUTE_TABLE_TAG_NAME="${EC2_ROUTE_TABLE_TAG_NAME}" # 3. EC2_ROUTE_DESTINATION_CIDR:"0.0.0.0/0" EC2_ROUTE_DESTINATION_CIDR="${EC2_ROUTE_DESTINATION_CIDR}" # 4. EC2_INTERNET_GATEWAY_TAG_NAME:"cloud9-coffee-internet-gateway" EC2_INTERNET_GATEWAY_TAG_NAME="${EC2_INTERNET_GATEWAY_TAG_NAME}" END 出力例 # 0. AWS_REGION:"ap-northeast-1" AWS_REGION="ap-northeast-1" # 1. EC2_VPC_TAG_NAME:"cloud9-coffee-vpc" EC2_VPC_TAG_NAME="cloud9-coffee-vpc" # 2. EC2_ROUTE_TABLE_TAG_NAME:"cloud9-coffee-route-table" EC2_ROUTE_TABLE_TAG_NAME="cloud9-coffee-route-table" # 3. EC2_ROUTE_DESTINATION_CIDR:"0.0.0.0/0" EC2_ROUTE_DESTINATION_CIDR="0.0.0.0/0" # 4. EC2_INTERNET_GATEWAY_TAG_NAME:"cloud9-coffee-internet-gateway" EC2_INTERNET_GATEWAY_TAG_NAME="cloud9-coffee-internet-gateway" 上下の文字列が同じであれば、変数に正しい値が格納されています。 AWS_REGIONという変数は、環境変数です。 各種IDの取得 VPC IDを取得します。 EC2_VPC_IDという変数に、抽出したVPC IDを格納します。 EC2_VPC_ID=$( \ aws ec2 describe-vpcs \ --filters Name=tag:Name,Values=${EC2_VPC_TAG_NAME} \ --query 'Vpcs[].VpcId' \ --output text \ ) \ && echo ${EC2_VPC_ID} 出力例 vpc-xxxxxxxxxxxxxxxxx ルートテーブルIDを取得します。 EC2_ROUTE_TABLE_IDという変数に、抽出したルートテーブルIDを格納します。 EC2_ROUTE_TABLE_ID=$( \ aws ec2 describe-route-tables \ --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_ROUTE_TABLE_TAG_NAME} \ --query "RouteTables[].RouteTableId" \ --output text \ ) \ && echo ${EC2_ROUTE_TABLE_ID} 出力例 rtb-xxxxxxxxxxxxxxxxx aws ec2 describe-route-tables ルートテーブルの詳細を表示する --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_ROUTE_TABLE_TAG_NAME} \ VPC ID(vpc-id)が"vpc-xxxxxxxxxxxxxxxxx(取得したVPC ID)"かつタグ名が"cloud9-coffee-route-table"のAND検索をしている --query "RouteTables[].RouteTableId" ルートテーブルの中のルートテーブルID項目(RouteTableId)を表示する インターネットゲートウェイIDを取得します。 EC2_INTERNET_GATEWAY_IDという変数に、抽出したインターネットゲートウェイIDを格納します。 EC2_INTERNET_GATEWAY_ID=$( \ aws ec2 describe-internet-gateways \ --filters Name=tag:Name,Values=${EC2_INTERNET_GATEWAY_TAG_NAME} \ --query "InternetGateways[].InternetGatewayId" \ --output text \ ) \ && echo ${EC2_INTERNET_GATEWAY_ID} 出力例 igw-xxxxxxxxxxxxxxxxx ヒアドキュメントで、変数に値が正しく入っているか確認します。 cat << END # EC2_ROUTE_TABLE_ID:"rtb-xxxxxxxxxxxxxxxxx" EC2_ROUTE_TABLE_ID="${EC2_ROUTE_TABLE_ID}" # EC2_INTERNET_GATEWAY_ID:"igw-xxxxxxxxxxxxxxxxx" EC2_INTERNET_GATEWAY_ID="${EC2_INTERNET_GATEWAY_ID}" END 出力例 # EC2_ROUTE_TABLE_ID:"rtb-xxxxxxxxxxxxxxxxx" EC2_ROUTE_TABLE_ID="rtb-xxxxxxxxxxxxxxxxx" # EC2_INTERNET_GATEWAY_ID:"igw-xxxxxxxxxxxxxxxxx" EC2_INTERNET_GATEWAY_ID="igw-xxxxxxxxxxxxxxxxx" ルートの設定 ではルートテーブルの中にルートを設定していきます。 aws ec2 create-route \ --route-table-id ${EC2_ROUTE_TABLE_ID} \ --destination-cidr-block ${EC2_ROUTE_DESTINATION_CIDR} \ --gateway-id ${EC2_INTERNET_GATEWAY_ID} 出力例 { "Return": true } aws ec2 create-route ルートを作成する --route-table-id ルートを設定するルートテーブルIDを指定する --destination-cidr-block 宛先CIDR範囲を指定する --gateway-id ターゲットとなるゲートウェイIDを指定する。今回はインターネットゲートウェイを指定している ルートテーブルに設定したルーティング設定があることを確認する ルートテーブル"cloud9-coffee-route-table"に"0.0.0.0/0"へのルートが存在することを確認します。 aws ec2 describe-route-tables \ --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_ROUTE_TABLE_TAG_NAME} \ --query "RouteTables[].Routes[?DestinationCidrBlock == \`${EC2_ROUTE_DESTINATION_CIDR}\`].DestinationCidrBlock" \ --output text 出力例 0.0.0.0/0 --query "RouteTables[].Routes[?DestinationCidrBlock == \`${EC2_ROUTE_DESTINATION_CIDR}\`].DestinationCidrBlock" \ ルートテーブルの中の宛先CIDR範囲(DestinationCidrBlock)が、設定したCIDR範囲(0.0.0.0/0)である宛先CIDR範囲項目(DestinationCidrBlock)を表示する 続いてルートテーブル"cloud9-coffee-route-table"の"0.0.0.0/0"へのルートがインターネットゲートウェイ"cloud9-coffee-internet-gateway"に設定されていることを確認します。 aws ec2 describe-route-tables \ --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_ROUTE_TABLE_TAG_NAME} \ --query "RouteTables[].Routes[?DestinationCidrBlock == \`${EC2_ROUTE_DESTINATION_CIDR}\`].GatewayId" \ --output text 出力例 igw-xxxxxxxxxxxxxxxxx --query "RouteTables[].Routes[?DestinationCidrBlock == \`${EC2_ROUTE_DESTINATION_CIDR}\`].GatewayId" \ ルートテーブルの中の宛先CIDR範囲(DestinationCidrBlock)が、設定したCIDR範囲(0.0.0.0/0)であるゲートウェイID項目(GatewayId)を表示する ここでCloudShellのセッションはいったん切断します。 以後の操作で変数汚染を防ぐため、Ctr+Dで接続を切断します。 再度CloudShellから操作する際はEnterでCloudShellに再接続します。 マネジメントコンソール上でも、ルートテーブル「cloud9-coffee-route-table」のルーティング設定に、送信先が"0.0.0.0/0"、ターゲットが"igw-xxxxxxxxxxxxxxxxx(作成したインターネットゲートウェイのID)"のルートが存在するのが確認できます。 ※表示されない場合は少し待ってからブラウザをリロードするか、選択しているリージョンが"東京"であることを確認してください。 8.Cloud9用VPC内にサブネットを作成する JAWS-UG CLI専門支部 以下手順を参考にします。 事前作業1.6. サブネットの作成 (CloudShell: public-subnet) サブネットを作成します。 リージョン確認 右上のリージョンメニューから"東京"を選択しておきます。 VPC作成時に東京以外のリージョンを選択した方は、作成したVPCと同じリージョンにしておいてください。 VPCのタグ名 サブネットを作成するにはサブネットを作成するVPCのVPC IDが必要になります。VPC IDを抽出するのにVPCのタグ名が必要になるため、変数にVPCのタグ名を格納しておきます。 EC2_VPC_TAG_NAME='cloud9-coffee-vpc' サブネットのタグ名 EC2_SUBNET_TAG_NAMEという変数に、サブネットのタグ名を指定します。 このサブネットはインターネットへ接続できるパブリックサブネットにする予定です。私はコーヒーが好きなのでcloud9-coffee-public-subnetとタグ名を付けましょう。 EC2_SUBNET_TAG_NAME='cloud9-coffee-public-subnet' サブネットのアドレスレンジ設定 EC2_SUBNET_CIDRという変数に、サブネットのアドレスレンジを指定します。 現在作成済みのcloud9-coffee-vpcのアドレス範囲は172.16.0.0~172.16.255.255(172.16.0.0/16)です。 サブネットのIPアドレス範囲は、このVPCのアドレス範囲に収まるように設定します。 今回は172.16.0.0~172.16.255.255(172.16.0.0/24)と設定してみましょう。 EC2_SUBNET_CIDR='172.16.0.0/24' サブネットを配置するAZ名を指定する EC2_AZ_NAMEという変数に、サブネットを配置するAZ(アベイラビリティゾーン)名を指定します。 東京リージョン(ap-northeast-1)には以下3つのAZがあります。 ap-northeast-1a ap-northeast-1c ap-northeast-1d 今回はどこでもいいですが、ap-northeast-1dにしてみましょう。 EC2_AZ_NAME="ap-northeast-1d" 2021年8月7日のAWS亀田さん勉強会「最新サービスをみんなで触ってみる」で聞いたうろ覚えのことですが、一度にたくさんの人がap-northeast-1dを選択しても、ap-northeast-1dAZ内のいろいろなデータセンタに分散されるため、ある程度同時にアクセスしても大丈夫、みたいな感じらしいです。規模が大きいのでしょうかね? ヒアドキュメントで、変数に値が正しく入っているか確認します。 cat << END # 0. AWS_REGION:"ap-northeast-1" AWS_REGION="${AWS_REGION}" # 1. EC2_VPC_TAG_NAME:"cloud9-coffee-vpc" EC2_VPC_TAG_NAME="${EC2_VPC_TAG_NAME}" # 2. EC2_SUBNET_TAG_NAME:"cloud9-coffee-public-subnet" EC2_SUBNET_TAG_NAME="${EC2_SUBNET_TAG_NAME}" # 3. EC2_SUBNET_CIDR:"172.16.0.0/24" EC2_SUBNET_CIDR="${EC2_SUBNET_CIDR}" # 4. EC2_AZ_NAME:"ap-northeast-1d" EC2_AZ_NAME="${EC2_AZ_NAME}" END 出力例 # 0. AWS_REGION:"ap-northeast-1" AWS_REGION="ap-northeast-1" # 1. EC2_VPC_TAG_NAME:"cloud9-coffee-vpc" EC2_VPC_TAG_NAME="cloud9-coffee-vpc" # 2. EC2_SUBNET_TAG_NAME:"cloud9-coffee-public-subnet" EC2_SUBNET_TAG_NAME="cloud9-coffee-public-subnet" # 3. EC2_SUBNET_CIDR:"172.16.0.0/24" EC2_SUBNET_CIDR="172.16.0.0/24" # 4. EC2_AZ_NAME:"ap-northeast-1d" EC2_AZ_NAME="ap-northeast-1d" 上下の文字列が同じであれば、変数に正しい値が格納されています。 AWS_REGIONという変数は、環境変数です。 VPC IDの取得 VPC IDの取得も慣れてきましたね。 EC2_VPC_ID=$( \ aws ec2 describe-vpcs \ --filters Name=tag:Name,Values=${EC2_VPC_TAG_NAME} \ --query 'Vpcs[].VpcId' \ --output text \ ) \ && echo ${EC2_VPC_ID} 出力例 vpc-xxxxxxxxxxxxxxxxx サブネットのタグ文字列設定 次はSTRING_EC2_SUBNET_TAGという変数にサブネットのタグ文字列を格納します。 リソースタイプ=subnetと指定します。 また、タグはkeyにName、valueにcloud9-coffee-public-subnetを格納します。 STRING_EC2_SUBNET_TAG="ResourceType=subnet,Tags=[{Key=Name,Value=${EC2_SUBNET_TAG_NAME}}]" \ && echo ${STRING_EC2_SUBNET_TAG} 出力例 ResourceType=subnet,Tags=[{Key=Name,Value=cloud9-coffee-public-subnet}] サブネットの作成 サブネットを作成します。 aws ec2 create-subnet \ --vpc-id ${EC2_VPC_ID} \ --cidr-block ${EC2_SUBNET_CIDR} \ --availability-zone ${EC2_AZ_NAME} \ --tag-specifications ${STRING_EC2_SUBNET_TAG} 出力例 { "Subnet": { "AvailabilityZone": "ap-northeast-1d", "AvailabilityZoneId": "<AZ_ID>", "AvailableIpAddressCount": 251 "CidrBlock": "172.16.0.0/24", "DefaultForAz": false, "MapPublicIpOnLaunch": false, "State": "pending", "SubnetId": "subnet-xxxxxxxxxxxxxxxxx", "VpcId": "vpc-xxxxxxxxxxxxxxxxx", "OwnerId": "XXXXXXXXXXXX", "AssignIpv6AddressOnCreation": false, "Ipv6CidrBlockAssociationSet": [], "Tags": [ { "Key": "Name", "Value": "cloud9-coffee-public-subnet" } ], "SubnetArn": "arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-xxxxxxxxxxxxxxxxx" } } aws ec2 create-subnet サブネットを作成する --vpc-id サブネットを作成するVPCのVPC IDを指定する --cidr-block サブネットのCIDR範囲を指定する --availability-zone サブネットを作成するAZ名を指定する --tag-specifications タグ名を指定する サブネットができているか確認 VPC"cloud9-coffee-vpc"にサブネット"cloud9-coffee-public-subnet"が存在することを確認します。 aws ec2 describe-subnets \ --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_SUBNET_TAG_NAME} \ --query 'Subnets[].Tags[?Key == `Name`].Value' \ --output text 出力例 cloud9-coffee-public-subnet aws ec2 describe-subnets サブネットの詳細を表示する --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_SUBNET_TAG_NAME} VPC ID(vpc-id)が"vpc-xxxxxxxxxxxxxxxxx(取得したVPC ID)"かつタグ名が"cloud9-coffee-public-subnet"のAND検索 --query 'Subnets[].Tags[?Key == `Name`].Value' key=Nameであるタグのvalue値を表示する 続いてサブネット"cloud9-coffee-public-subnet"のCIDRは"172.16.0.0/24"であることを確認します。 aws ec2 describe-subnets \ --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_SUBNET_TAG_NAME} \ --query "Subnets[].CidrBlock" \ --output text 出力例 172.16.0.0/24 --query "Subnets[].CidrBlock" サブネットの中のCidrBlockという項目を表示させる 続いて、サブネット"cloud9-coffee-public-subnet"のAZは"ap-northeast-1d"であることを確認します。 aws ec2 describe-subnets \ --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_SUBNET_TAG_NAME} \ --query "Subnets[].AvailabilityZone" \ --output text 出力例 ap-northeast-1d --query "Subnets[].AvailabilityZone" サブネットの中のAvailabilityZoneという項目を表示させる ここでCloudShellのセッションはいったん切断します。 以後の操作で変数汚染を防ぐため、Ctr+Dで接続を切断します。 再度CloudShellから操作する際はEnterでCloudShellに再接続します。 マネジメントコンソール上でも、新しく「cloud9-coffee-public-subnet」というタグのついたサブネットが作成されているのが確認できます。 ※表示されない場合は少し待ってからブラウザをリロードするか、選択しているリージョンが"東京"であることを確認してください。 9.Cloud9用VPC内のサブネットにルートテーブルを紐づける JAWS-UG CLI専門支部 以下手順を参考にします。 事前作業1.7. ルートテーブルの更新 (CloudShell: public-subnetとの関連付け) 作成したサブネットに、作成したルートテーブルを紐づけます。これでこのサブネットからインターネットへ接続できるようになり、パブリックサブネットと名乗れるようになります。 いよいよコーヒーのいい香りがしてきましたね。 リージョン確認 右上のリージョンメニューから"東京"を選択しておきます。 VPC作成時に東京以外のリージョンを選択した方は、作成したVPCと同じリージョンにしておいてください。 VPC、ルートテーブル、サブネットのタグ名 各種タグ名を変数に格納します。 EC2_VPC_TAG_NAME='cloud9-coffee-vpc' EC2_ROUTE_TABLE_TAG_NAME='cloud9-coffee-route-table' EC2_SUBNET_TAG_NAME='cloud9-coffee-public-subnet' ヒアドキュメントで、変数に値が正しく入っているか確認します。 cat << END # 0. AWS_REGION:"ap-northeast-1" AWS_REGION="${AWS_REGION}" # 1. EC2_VPC_TAG_NAME:"cloud9-coffee-vpc" EC2_VPC_TAG_NAME="${EC2_VPC_TAG_NAME}" # 2. EC2_ROUTE_TABLE_TAG_NAME:"cloud9-coffee-route-table" EC2_ROUTE_TABLE_TAG_NAME="${EC2_ROUTE_TABLE_TAG_NAME}" # 3. EC2_SUBNET_TAG_NAME:"cloud9-coffee-public-subnet" EC2_SUBNET_TAG_NAME="${EC2_SUBNET_TAG_NAME}" END 出力例 # 0. AWS_REGION:"ap-northeast-1" AWS_REGION="ap-northeast-1" # 1. EC2_VPC_TAG_NAME:"cloud9-coffee-vpc" EC2_VPC_TAG_NAME="cloud9-coffee-vpc" # 2. EC2_ROUTE_TABLE_TAG_NAME:"cloud9-coffee-route-table" EC2_ROUTE_TABLE_TAG_NAME="cloud9-coffee-route-table" # 3. EC2_SUBNET_TAG_NAME:"cloud9-coffee-public-subnet" EC2_SUBNET_TAG_NAME="cloud9-coffee-public-subnet" 上下の文字列が同じであれば、変数に正しい値が格納されています。 AWS_REGIONという変数は、環境変数です。 VPC、ルートテーブル、サブネットのID取得 VPC IDを取得します。 EC2_VPC_ID=$( \ aws ec2 describe-vpcs \ --filters Name=tag:Name,Values=${EC2_VPC_TAG_NAME} \ --query 'Vpcs[].VpcId' \ --output text \ ) \ && echo ${EC2_VPC_ID} 出力例 vpc-xxxxxxxxxxxxxxxxx ルートテーブルIDを取得します。 EC2_ROUTE_TABLE_ID=$( \ aws ec2 describe-route-tables \ --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_ROUTE_TABLE_TAG_NAME} \ --query "RouteTables[].RouteTableId" \ --output text \ ) \ && echo ${EC2_ROUTE_TABLE_ID} 出力例 rtb-xxxxxxxxxxxxxxxxx サブネットIDを取得します。 EC2_SUBNET_ID=$( \ aws ec2 describe-subnets \ --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_SUBNET_TAG_NAME} \ --query "Subnets[].SubnetId" \ --output text \ ) \ && echo ${EC2_SUBNET_ID} 出力例 subnet-xxxxxxxxxxxxxxxxx ヒアドキュメントで、変数に値が正しく入っているか確認します。 cat << END # EC2_SUBNET_ID:"subnet-xxxxxxxxxxxxxxxxx" EC2_SUBNET_ID="${EC2_SUBNET_ID}" # EC2_ROUTE_TABLE_ID:"rtb-xxxxxxxxxxxxxxxxx" EC2_ROUTE_TABLE_ID="${EC2_ROUTE_TABLE_ID}" END 出力例 # EC2_SUBNET_ID:"subnet-xxxxxxxxxxxxxxxxx" EC2_SUBNET_ID="subnet-xxxxxxxxxxxxxxxxx" # EC2_ROUTE_TABLE_ID:"rtb-xxxxxxxxxxxxxxxxx" EC2_ROUTE_TABLE_ID="rtb-xxxxxxxxxxxxxxxxx" ルートテーブルをサブネットに関連付ける ルートテーブルとサブネットを関連付けします。 aws ec2 associate-route-table \ --subnet-id ${EC2_SUBNET_ID} \ --route-table-id ${EC2_ROUTE_TABLE_ID} 出力例 { "AssociationId": "rtbassoc-xxxxxxxxxxxxxxxxx" "AssociationState": { "State": "associated" } } aws ec2 associate-route-table ルートテーブルをサブネットに関連付ける --subnet-id 関連付けるサブネットのサブネットIDを指定する --route-table-id 関連付けるルートテーブルのルートテーブルIDを指定する ルートテーブルがサブネットに紐づいたか確認する ルートテーブル"cloud9-coffee-route-table"がサブネット"cloud9-coffee-public-subnet"と関連付いていることを確認します。 aws ec2 describe-route-tables \ --route-table-ids ${EC2_ROUTE_TABLE_ID} \ --query "RouteTables[].Associations[?SubnetId == \`${EC2_SUBNET_ID}\`].RouteTableAssociationId" \ --output text 出力例 rtbassoc-xxxxxxxxxxxxxxxxxx ここでCloudShellのセッションはCtr+Dで切断します。 マネジメントコンソール上でも、ルートテーブル"cloud9-coffee-route-table"がサブネット"cloud9-coffee-public-subnet"と関連付いていることが確認できます。 ※表示されない場合は少し待ってからブラウザをリロードするか、選択しているリージョンが"東京"であることを確認してください。 Cloud9環境のためのVPCができました 以上で、Cloud9環境を作成する前準備として、ルートテーブルなども含むVPCの作成が完了しました。 ここまでで作成したリソースには課金されません。 次回は、Cloud9環境を操作するためのユーザ作成の復習を実施する予定です。 権限周りのイメージ図↓ 参考資料
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Terraformを使って一撃でAWS上にSambaファイルサーバを構築する

AWS上にSambaサーバを一撃で構築する Sambaの設定は無数にあるので極力シンプルに構築することを目的とする 近頃はEFS等便利なサービスがあるが色々なクラウドの無料枠乞食をすることを考えるとやはり知っておいた方が良い考え備忘録として残す 準備 Terraformのインストール brewなりDLしてPathを通してterraform initする 秘密鍵作る ssh-keygenとかPuttygenでおk 最近はWindowsでもデフォルトで出来るようになってた フォルダ構造 samba | id_rsa.pub | samba.tf | userdata.sh | terraform.tfstate # Stateファイル | terraform.tfstate.backup # Stateのバックアップファイル | .terraform.lock.hcl # initで作られる \ .terraform # initで作られる Terraformコード # provider provider "aws" { region = "ap-northeast-1" #profile = "dialogueplus" } variable "tags" { default = "samba" } # これだと全世界にファイルサーバーを晒す設定なので # ここは自分のIPアドレスを入れた方が良いとは思う variable "myIpAdress" { default = "0.0.0.0/0" # default = "0.0.0.0/32" } # VPC resource "aws_vpc" "VPC" { cidr_block = "10.1.0.0/16" instance_tenancy = "default" enable_dns_support = "true" enable_dns_hostnames = "false" tags = { Name = "${var.tags}-VPC" } } # IGW resource "aws_internet_gateway" "GW" { vpc_id = aws_vpc.VPC.id tags = { Name = "${var.tags}-IGW" } } # Subnet resource "aws_subnet" "public-subnet" { vpc_id = aws_vpc.VPC.id cidr_block = "10.1.1.0/24" availability_zone = "ap-northeast-1a" tags = { Name = "${var.tags}-subnet" } } # route table resource "aws_route_table" "public-route" { vpc_id = aws_vpc.VPC.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.GW.id } tags = { Name = "${var.tags}-rtb" } } # routing resource "aws_route_table_association" "puclic-routing" { subnet_id = aws_subnet.public-subnet.id route_table_id = aws_route_table.public-route.id } # SG resource "aws_security_group" "Terraform-EC2-SG" { name = "${var.tags}-ec2" description = "File Server" vpc_id = aws_vpc.VPC.id ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["${var.myIpAdress}"] } ingress { from_port = 445 to_port = 445 protocol = "tcp" cidr_blocks = ["${var.myIpAdress}"] } ingress { from_port = 139 to_port = 139 protocol = "tcp" cidr_blocks = ["${var.myIpAdress}"] } ingress { from_port = 137 to_port = 137 protocol = "udp" cidr_blocks = ["${var.myIpAdress}"] } ingress { from_port = 138 to_port = 138 protocol = "udp" cidr_blocks = ["${var.myIpAdress}"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "${var.tags}-SG" } } # 最新のAMIを取得 # https://dev.classmethod.jp/articles/launch-ec2-from-latest-amazon-linux2-ami-by-terraform/ data "aws_ssm_parameter" "amzn2_ami" { name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2" } resource "aws_key_pair" "aurh" { key_name = "samba-key" public_key = file("./id_rsa.pub") } # EC2 resource "aws_instance" "Terraform-ec2" { ami = data.aws_ssm_parameter.amzn2_ami.value instance_type = "t2.micro" key_name = aws_key_pair.aurh.id vpc_security_group_ids = [ "${aws_security_group.Terraform-EC2-SG.id}" ] subnet_id = aws_subnet.public-subnet.id associate_public_ip_address = "true" root_block_device { volume_type = "gp2" volume_size = "8" # Volumeのサイズは用途に合わせて } tags = { Name = "${var.tags}-EC2" } user_data = file("./userdata.sh") } # 構築後にIPアドレスが表示されるようにする output "publicIp" { value = aws_instance.Terraform-ec2.public_ip } ユーザーデータ(シェルスクリプト) #!/bin/bash yum update -y yum install -y samba which smbd nmbd systemctl start smb nmb systemctl status smb nmb systemctl enable smb nmb cp /etc/samba/smb.conf /etc/samba/smb.conf.old echo -e "[global]\nworkgroup = SAMBA\nsecurity = user\npassdb backend = tdbsam\nload printers = yes\ncups options = raw\n\n[share]\ncomment = Share Folder for All Users\npath = /home/share/\nbrowsable = yes\nread only = no\n\n[homes]\ncomment = Home Directories\nvalid users = %S, %D%w%S\nbrowseable = No\nread only = No\ninherit acls = Yes\n" > /etc/samba/smb.conf mkdir /home/share chmod -R 777 /home/share chmod -R 777 /home/share chown -R nobody:nobody /home/share testparm -s #ユーザー名を設定 useradd test01 #Passwordを設定 echo -e "P@ssw0rd\nP@ssw0rd" | pdbedit -a -t -u test01 systemctl restart smb nmb smbstatus 接続 Win 出力されたIPを置き換えて¥¥XX.XX.XX.XX¥share¥へアクセスし設定したユーザーとパスワードを入れる ネットワークの設定がパブリックネットワークだと設定できない Mac Finder→移動→サーバへ接続→smb://XX.XX.XX.XX→設定したユーザーとパスワードを入れる 参考にしたサイト
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSのClient VPNを用いた社内固定IPの構築

背景 受託案件において実際に構築したサービスの本番環境へのアクセスが会社のルータのIPで制限されており、リモートからの作業に支障をきたすことが多々ありました。そこでClient VPNを用いて相互認証を行い、認証が通った後に固定のIPからインターネットへアクセスできるようにすることで、その固定IPを制限から解除すればリモートからでも本番環境にアクセスできるようにしました。 同じような悩みを持った方や、Client VPNエンドポイントの構築方法がわからない方がいれば一助になるかなと思います! 目次 全体構成 認証方法 構築の流れ 証明書の発行 ACMにサーバ証明書をアップロード 証明書の配布 クライアントの設定 証明書の運用 参考文献 全体構成 こちらの記事と構成は全く同じです。 一番重要なのはNATに固定IPを紐付けて、全てのクライアントがそこを経由することで同じIPからのインターネットアクセスになるということです!ただ、どんな人でもその固定IPにアクセスできると困るので、その前にClient VPNを用いて認証を行うということです。 IPやルートテーブルの一例 - VPC(IPv4 CIDR: 192.168.0.0/16) - サブネット - パブリックサブネット(192.168.2.0/24) - ルートテーブル(192.168.0.0/16→local, 0.0.0.0/0→igw) - NATを配置 - EIP: xxx.xxx.xxx.xxx, プライベート IP アドレス: 192.168.2.163 - プライベートサブネット(192.168.1.0/24) - ルートテーブル(192.168.0.0/16→local, 0.0.0.0/0→nat) - クライアント VPN エンドポイント - IPv4 CIDR: 192.168.4.0/22 - 関連づけられたサブネット: プライベートサブネット - ルートテーブル - 192.168.0.0/16: プライベートサブネット - 0.0.0.0/0: プライベートサブネット 認証方法 認証方法の種類 認証は AWS クラウドへの最初のエントリポイントで実装されます。クライアントがクライアント VPN エンドポイントへの接続を許可されているかどうかを判断するために使用されます。認証が成功すると、クライアントはクライアント VPN エンドポイントに接続して VPN セッションを確立します。認証が失敗すると、接続は拒否され、クライアントは VPN セッションを確立できなくなります。 クライアント VPN では、次のタイプのクライアント認証を使用できます。 Active Directory 認証 (ユーザーベース) 相互認証 (証明書ベース) シングルサインオン (SAML ベースのフェデレーション認証) (ユーザーベース) 今回用いた認証方法は相互認証です! - 相互認証 - 相互認証では、証明書を使用してクライアントとサーバー間の認証を実行します。 - 証明書にはサーバー証明書とクライアント証明書の2種類に分けられて、サーバー証明書は一つでいいけど、クライアント証明書は人数分増えていく - サーバー証明書をACMにアップロードする(エンドポイント作成時に必要だから) - ここで言うサーバー証明証はサーバー証明書とそのキー、ルート証明書を合わせたもの - クライアント証明書はACMにアップロードしなくていい(サーバー証明書とクライアント証明書を同じ認証局で今回は作成しているので) - エンドポイント作成時にクライアント証明書にサーバー証明書を選択したあげればOK - ちなみに自分で認証局を作成するのをオレオレ認証局って言います - クライアント証明書はクライアントに配布する(この時に設定ファイルも一緒に配布する) 認証局を自前で建てるのか、厳格に審査された信用できる認証局を使用するかで悩みました。 セキュリティ的には圧倒的に厳格に審査された信用できる認証局を使用すべきなのですが、AWSでプライベート認証局(CA)を1つ建てると毎月4万円はするので無しになりました。そもそも相互認証ではなく、Active Directory認証を用いる手もありましたが、オレオレ認証局を用いた相互認証の方がまだセキュリティー的に安全なのではないかと考え、オレオレ認証局での相互認証で構築することなりました。ここら辺について詳しい方がいれば教えてください。 構築の流れ - 主な流れ - 証明書の発行 - ACMにサーバ証明書をアップロード - クライアントVPNエンドポイントの作成と各種設定 - エンドポイントから設定ファイルをダウンロード - クライアントにクライアント証明書とそのキー、設定ファイルを配布 - クライアントにVPN接続のクライアントアプリケーションを入れてもらい、配布したものとそのアプリでVPN接続してもらう - 接続しているIPがNATに紐づく固定IPになっていたら大成功 Client VPNエンドポイントの作成方法はこの記事では説明していないので、他記事を参考にして頂ければなと。 証明書の発行 証明書を発行するためのツール EasyRSA-3.0.7 これ使えば認証局の作成から証明書の発行が超絶簡単にできる Open SSLを用いる方法もあリました。 発行方法 EasyRSA-3.0.7の公式ドキュメントに書いてある通りです。 AWS公式 $ wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.7/EasyRSA-3.0.7.tgz $ tar zxfv EasyRSA-3.0.7.tgz $ cd EasyRSA-3.0.7 新しい PKI 環境を初期化します。 $ ./easyrsa init-pki # 認証局の作成 # nopassオプションを使用するとパスフレーズを追加しなくてよくするオプション $ ./easyrsa build-ca nopass # サーバー証明書の作成 $ ./easyrsa build-server-full server nopass # クライアント証明書の作成 # クライアント証明書はクライアントごとに分けるので、名前にするとわかりやすいと思います。 $ ./easyrsa build-client-full isao.katsuoka.tld nopass # 証明書だけを集めたフォルダを作っておくといいかもです。 $ mkdir ~/vpn_folder/ $ cp pki/ca.crt ~/vpn_folder/ $ cp pki/issued/server.crt ~/vpn_folder/ $ cp pki/private/server.key ~/vpn_folder/ $ cp pki/issued/isao.katsuoka.tld.crt ~/vpn_folder/ $ cp pki/private/isao.katsuoka.tld.key ~/vpn_folder/ $ cd ~/vpn_folder/ 次からはサーバ証明書やルート証明書は発行しなくていいので、以下を名前を変えて人数分実行すればいい $ cd ~/EasyRSA-3.0.7 $ ./easyrsa build-client-full yuki.tanaka.tld nopass $ cp pki/issued/isao.katsuoka.tld.crt ~/vpn_folder/ $ cp pki/private/isao.katsuoka.tld.key ~/vpn_folder/ $ cd ~/vpn_folder/ 証明書が保存される場所をまとめてみました。 - 保存場所 - CA証明書 - pki/ca.crt - 証明書(クライアント証明書とサーバー証明書) - pki/issued/ - isao.katsuoka.tld.crt - server.crt - 証明書のキー - pki/private/ - ca.key - isao.katsuoka.tld.key - server.key ACMにサーバ証明書をアップロード アップロードの方法として画面ぽちぽちする方法と、AWS CLIを用いる方法がありますが、今回はAWS CLIを用いる方法を説明したいと思います。 $ cd ~/vpn_folder/ $ aws acm import-certificate \ --certificate file://server.crt \ --private-key file://server.key \ --certificate-chain file://ca.crt \ --region ap-northeast-2 ↓アップロードエラー出たので、file:// -> fileb://に変更する https://zenn.dev/hohner/articles/310453a1121c9b $ aws acm import-certificate \ --certificate fileb://server.crt \ --private-key fileb://server.key \ --certificate-chain fileb://ca.crt \ --region ap-northeast-2 注意点 サーバー証明書のアップロードはクライアントVPNエンドポイントを作成する時の最初の1回だけ必要 クライアント証明書のアップロードはオレオレ認証局だから必要ない(エンドポイント作成時にクライアント証明書を選択する必要があるが、その時はサーバー証明書を選択すれば良い) また、完全に余談になりますが、awspを入れるとプロファイルの切り替えが簡単になるので もし入れてなかったら入れてみてください!! AWS CLIのプロファイルを簡単切り替え 証明書の配布 - クライアントVPNエンドポイントの管理画面から「クライアント設定のダウンロード」を押して設定ファイル(downloaded-client-config.ovpn)を取得 - 配布するファイル - クライアント証明書とそのキー(isao.katsuoka.tld.crt, isao.katsuoka.tld.key) - OVPNファイル(downloaded-client-config.ovpn)←名前は変えてもいい - この3つのファイルをzip化して送る クライアントの設定 VPNのクライアントアプリケーションのインストール Macの場合→Tunnelblick Macの場合(Tunnelblickの設定) Tunnelblick公式ドキュメント Windowsの場合→vpnux ただ、自分はWindowsを使っていないので設定方法がわかりません。 Tunnelblickの使い方 一言で言えば、downloaded-client-config.ovpnに証明書とそのキーを読み込ませてあげればいい 具体的にはcertタグとkeyタグを作成して、そこに証明書とそのキーの情報を差し込む。 ⇩設定の一例 client dev tun proto udp remote cvpn-endpoint-xxxxxxxxxxxx.prod.clientvpn.ap-northeast-x.amazonaws.com 443 remote-random-hostname resolv-retry infinite nobind remote-cert-tls server cipher AES-256-GCM verb 3 <ca> -----BEGIN CERTIFICATE----- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -----END CERTIFICATE----- </ca> <cert> -----BEGIN CERTIFICATE----- bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb -----END CERTIFICATE----- </cert> <key> -----BEGIN PRIVATE KEY----- cccccccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccccccc -----END PRIVATE KEY----- </key> reneg-sec 0 証明書の運用 証明書の失効 特定クライアントのクライアント VPN エンドポイントへのアクセスを取り消すにはどうすればよいですか? 失効リストをオレオレ認証局で作成して、Client VPNエンドポイントにインポート 証明書の有効期限 デフォルトで825日 100年に変更もできる 【Client VPN】OpenVPN easy-rsaでサーバ証明書の有効期限を100年にする 証明書の有効期限が切れたらクライアントに再配布が必要! 参考文献 [AWS Client VPN] VPC を経由して固定のIPでインターネットへアクセスする 相互認証 AWS公式ドキュメント AWS CLIのプロファイルを簡単切り替え Macの場合(Tunnelblickの設定) Tunnelblick公式ドキュメント 【Client VPN】OpenVPN easy-rsaでサーバ証明書の有効期限を100年にする 特定クライアントのクライアント VPN エンドポイントへのアクセスを取り消すにはどうすればよいですか?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSのClient VPNを用いた社内固定IPインターンネットアクセスの構築

背景 受託案件において実際に構築したサービスの本番環境へのアクセスが会社のルータのIPで制限されており、リモートからの作業に支障をきたすことが多々ありました。そこでClient VPNを用いて相互認証を行い、認証が通った後に固定のIPからインターネットへアクセスできるようにすることで、その固定IPを制限から解除すればリモートからでも本番環境にアクセスできるようにしました。 目次 全体構成 認証方法 構築の流れ 証明書の発行 ACMにサーバ証明書をアップロード 証明書の配布 クライアントの設定 証明書の運用 参考文献 全体構成 こちらの記事と構成は全く同じです。 一番重要なのはNATに固定IPを紐付けて、全てのクライアントがそこを経由することで同じIPからのインターネットアクセスになるということです!ただ、どんな人でもその固定IPにアクセスできると困るので、その前にClient VPNを用いて認証を行うということです。 IPやルートテーブルの一例 - VPC(IPv4 CIDR: 192.168.0.0/16) - サブネット - パブリックサブネット(192.168.2.0/24) - ルートテーブル(192.168.0.0/16→local, 0.0.0.0/0→igw) - NATを配置 - EIP: xxx.xxx.xxx.xxx, プライベート IP アドレス: 192.168.2.163 - プライベートサブネット(192.168.1.0/24) - ルートテーブル(192.168.0.0/16→local, 0.0.0.0/0→nat) - クライアント VPN エンドポイント - IPv4 CIDR: 192.168.4.0/22 - 関連づけられたサブネット: プライベートサブネット - ルートテーブル - 192.168.0.0/16: プライベートサブネット - 0.0.0.0/0: プライベートサブネット 認証方法 認証方法の種類 認証は AWS クラウドへの最初のエントリポイントで実装されます。クライアントがクライアント VPN エンドポイントへの接続を許可されているかどうかを判断するために使用されます。認証が成功すると、クライアントはクライアント VPN エンドポイントに接続して VPN セッションを確立します。認証が失敗すると、接続は拒否され、クライアントは VPN セッションを確立できなくなります。 クライアント VPN では、次のタイプのクライアント認証を使用できます。 Active Directory 認証 (ユーザーベース) 相互認証 (証明書ベース) シングルサインオン (SAML ベースのフェデレーション認証) (ユーザーベース) 今回用いた認証方法は相互認証です! - 相互認証 - 相互認証では、証明書を使用してクライアントとサーバー間の認証を実行します。 - 証明書にはサーバー証明書とクライアント証明書の2種類に分けられて、サーバー証明書は一つでいいけど、クライアント証明書は人数分増えていく - サーバー証明書をACMにアップロードする(エンドポイント作成時に必要だから) - ここで言うサーバー証明証はサーバー証明書とそのキー、ルート証明書を合わせたもの - クライアント証明書はACMにアップロードしなくていい(サーバー証明書とクライアント証明書を同じ認証局で今回は作成しているので) - エンドポイント作成時にクライアント証明書にサーバー証明書を選択したあげればOK - ちなみに自分で認証局を作成するのをオレオレ認証局って言います - クライアント証明書はクライアントに配布する(この時に設定ファイルも一緒に配布する) 認証局を自前で建てるのか、厳格に審査された信用できる認証局を使用するかで悩みました。 セキュリティ的には圧倒的に厳格に審査された信用できる認証局を使用すべきなのですが、AWSでプライベート認証局(CA)を1つ建てると毎月4万円はするので無しになりました。そもそも相互認証ではなく、Active Directory認証を用いる手もありましたが、オレオレ認証局を用いた相互認証の方がまだセキュリティー的に安全なのではないかと考え、オレオレ認証局での相互認証で構築することなりました。ここら辺について詳しい方がいれば教えてください。 構築の流れ - 主な流れ - 証明書の発行 - ACMにサーバ証明書をアップロード - クライアントVPNエンドポイントの作成と各種設定 - エンドポイントから設定ファイルをダウンロード - クライアントにクライアント証明書とそのキー、設定ファイルを配布 - クライアントにVPN接続のクライアントアプリケーションを入れてもらい、配布したものとそのアプリでVPN接続してもらう - 接続しているIPがNATに紐づく固定IPになっていたら大成功 Client VPNエンドポイントの作成方法はこの記事では説明していないので、他記事を参考にして頂ければなと。 証明書の発行 証明書を発行するためのツール EasyRSA-3.0.7 これ使えば認証局の作成から証明書の発行が超絶簡単にできる Open SSLを用いる方法もあリました。 発行方法 EasyRSA-3.0.7の公式ドキュメントに書いてある通りです。 AWS公式 $ wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.7/EasyRSA-3.0.7.tgz $ tar zxfv EasyRSA-3.0.7.tgz $ cd EasyRSA-3.0.7 新しい PKI 環境を初期化します。 $ ./easyrsa init-pki # 認証局の作成 # nopassオプションを使用するとパスフレーズを追加しなくてよくするオプション $ ./easyrsa build-ca nopass # サーバー証明書の作成 $ ./easyrsa build-server-full server nopass # クライアント証明書の作成 # クライアント証明書はクライアントごとに分けるので、名前にするとわかりやすいと思います。 $ ./easyrsa build-client-full isao.katsuoka.tld nopass # 証明書だけを集めたフォルダを作っておくといいかもです。 $ mkdir ~/vpn_folder/ $ cp pki/ca.crt ~/vpn_folder/ $ cp pki/issued/server.crt ~/vpn_folder/ $ cp pki/private/server.key ~/vpn_folder/ $ cp pki/issued/isao.katsuoka.tld.crt ~/vpn_folder/ $ cp pki/private/isao.katsuoka.tld.key ~/vpn_folder/ $ cd ~/vpn_folder/ 次からはサーバ証明書やルート証明書は発行しなくていいので、以下を名前を変えて人数分実行すればいい $ cd ~/EasyRSA-3.0.7 $ ./easyrsa build-client-full yuki.tanaka.tld nopass $ cp pki/issued/isao.katsuoka.tld.crt ~/vpn_folder/ $ cp pki/private/isao.katsuoka.tld.key ~/vpn_folder/ $ cd ~/vpn_folder/ 証明書が保存される場所をまとめてみました。 - 保存場所 - CA証明書 - pki/ca.crt - 証明書(クライアント証明書とサーバー証明書) - pki/issued/ - isao.katsuoka.tld.crt - server.crt - 証明書のキー - pki/private/ - ca.key - isao.katsuoka.tld.key - server.key ACMにサーバ証明書をアップロード アップロードの方法として画面ぽちぽちする方法と、AWS CLIを用いる方法がありますが、今回はAWS CLIを用いる方法を説明したいと思います。 $ cd ~/vpn_folder/ $ aws acm import-certificate \ --certificate file://server.crt \ --private-key file://server.key \ --certificate-chain file://ca.crt \ --region ap-northeast-2 ↓アップロードエラー出たので、file:// -> fileb://に変更する https://zenn.dev/hohner/articles/310453a1121c9b $ aws acm import-certificate \ --certificate fileb://server.crt \ --private-key fileb://server.key \ --certificate-chain fileb://ca.crt \ --region ap-northeast-2 注意点 サーバー証明書のアップロードはクライアントVPNエンドポイントを作成する時の最初の1回だけ必要 クライアント証明書のアップロードはオレオレ認証局だから必要ない(エンドポイント作成時にクライアント証明書を選択する必要があるが、その時はサーバー証明書を選択すれば良い) また、完全に余談になりますが、awspを入れるとプロファイルの切り替えが簡単になるので もし入れてなかったら入れてみてください!! AWS CLIのプロファイルを簡単切り替え 証明書の配布 - クライアントVPNエンドポイントの管理画面から「クライアント設定のダウンロード」を押して設定ファイル(downloaded-client-config.ovpn)を取得 - 配布するファイル - クライアント証明書とそのキー(isao.katsuoka.tld.crt, isao.katsuoka.tld.key) - OVPNファイル(downloaded-client-config.ovpn)←名前は変えてもいい - この3つのファイルをzip化して送る クライアントの設定 VPNのクライアントアプリケーションのインストール Macの場合→Tunnelblick Macの場合(Tunnelblickの設定) Tunnelblick公式ドキュメント Windowsの場合→vpnux ただ、自分はWindowsを使っていないので設定方法がわかりません。 Tunnelblickの使い方 一言で言えば、downloaded-client-config.ovpnに証明書とそのキーを読み込ませてあげればいい 具体的にはcertタグとkeyタグを作成して、そこに証明書とそのキーの情報を差し込む。 ⇩設定の一例 client dev tun proto udp remote cvpn-endpoint-xxxxxxxxxxxx.prod.clientvpn.ap-northeast-x.amazonaws.com 443 remote-random-hostname resolv-retry infinite nobind remote-cert-tls server cipher AES-256-GCM verb 3 <ca> -----BEGIN CERTIFICATE----- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -----END CERTIFICATE----- </ca> <cert> -----BEGIN CERTIFICATE----- bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb -----END CERTIFICATE----- </cert> <key> -----BEGIN PRIVATE KEY----- cccccccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccccccc -----END PRIVATE KEY----- </key> reneg-sec 0 証明書の運用 証明書の失効 特定クライアントのクライアント VPN エンドポイントへのアクセスを取り消すにはどうすればよいですか? 失効リストをオレオレ認証局で作成して、Client VPNエンドポイントにインポート 証明書の有効期限 デフォルトで825日 100年に変更もできる 【Client VPN】OpenVPN easy-rsaでサーバ証明書の有効期限を100年にする 証明書の有効期限が切れたらクライアントに再配布が必要! 参考文献 [AWS Client VPN] VPC を経由して固定のIPでインターネットへアクセスする 相互認証 AWS公式ドキュメント AWS CLIのプロファイルを簡単切り替え Macの場合(Tunnelblickの設定) Tunnelblick公式ドキュメント 【Client VPN】OpenVPN easy-rsaでサーバ証明書の有効期限を100年にする 特定クライアントのクライアント VPN エンドポイントへのアクセスを取り消すにはどうすればよいですか?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】EventBridgeでEC2インスタンスIDを指定する時の注意

AWSのEventBrigeとSystemManagerを使用して、 EC2インスタンスを定時で停止するため実装したが、 時間になってもインスタンスが停止されず、原因解決に時間が掛かってしまった。 その原因が分からないと沼りそうだったので、備忘録として記載する。 実装内容 毎日0時にEC2インスタンスを自動停止する EventBrigeで停止スケジュールと停止対象のインスタンスを指定 SystemManagerでインスタンスの停止アクションを選択する。 原因 ダブルコーテーションの記述が間違っていた EventBrige ルールにて、インスタンスIDを記述するダブルコーテーションが 正常に認識されていなかった。 誤った記述(ダブルコーテーション「"」が斜めになっている) 正常な記述 発生理由 slackやメモ帳からコピーすると、ダブルコーテーションが斜めになってしまう可能性がある。 これはフォントの違いによって発生してしまうとのこと。 まとめ 外部アプリからコードをコピーする時は、ダブルコーテーションの違いに気をつけよう
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

サンプルデータモデルをインポートして、DynamoDB にコミットする【NoSQL Workbench】

DynamoDB 専用の NoSQL Workbench には様々なサンプルデータモデルが用意されています。 サンプルデータモデルには、GSI やファセットが定義されているので DynamoDB のテーブル設計の参考になります。 また、NoSQL Workbench にはコミット機能があり、データモデルを DynamoDB にエクスポートすることができます。サンプルデータモデルには Item もいくつか用意されているので、データモデルを DynamoDB にコミットした後には、サンプルデータを用意することなく、そのまま簡単なアプリケーションの作成まで行えそうです。 サンプルデータモデルのインポート 左側ペインの[Amazon DynamoDB]から Sample data models テーブルの中からインポートしたいモデルの行にカーソルを持っていき[Import]を選択します。 インポートが成功すると[Data modeler]にインポートしたテーブルの情報が表示されます。 データをビジュアル化 左側ペインの[Visualizer]を選択すると、メインテーブルや GSI でのデータ表示が可視化されます。 サンプルデータモデルを DynamoDB にコミット データモデルを DynamoDB のテーブルにコミットしてみます。 [Visualizer]から[Commit to Amazon DynamoDB]を選択すると、モーダルが表示されます。 新しいコネクションを作成するか、既存のコネクションを選択します。コネクションを選択できたら[Commit]を押下します。すると、Operation builder のトップページに移ります。 先ほど選択したコネクションの[Open]を選択すると、そのコネクションに紐づいているテーブルの一覧が Tables に表示されます。コミットしたデータモデルのテーブルを選択すると、Visualizer で確認していたデータがテーブルにコミットされているのが確認できます。 おわりに DynamoDB のテーブル設計は、あらかじめアプリケーションのクエリパターンを知っておく必要があるので、NoSQL Workbench の Data modeler と Visualize を使用して、クエリパターンがシミュレーションできるのは、なかなか便利かなと思いました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

curl --aws-sigv4 を使用してAWS SSM ParameterStoreの値を取得する

curl 7.75.0 で AWS SigV4 をサポートしていると教えてもらいました。 どうやって使うのかメモっておく。 AWS Systems Manager Parameter Store $ curl --aws-sigv4 "aws:amz" \ --user "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" \ -H "X-Amz-Target: AmazonSSM.GetParameter" \ -H "Content-Type: application/x-amz-json-1.1" \ -d '{"Name":"/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2","WithDecryption":true}' \ https://ssm.us-east-1.amazonaws.com/ { "Parameter": { "ARN": "arn:aws:ssm:us-east-1::parameter/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2", "DataType": "text", "LastModifiedDate": 1630616412.613, "Name": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2", "Type": "String", "Value": "ami-087c17d1fe0178315", "Version": 51 } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS CLIの操作対象を確認

前提 プロジェクト用と勉強用などAWSアカウントを2つ持っている状態で 1つのPCから操作している場合に現在どのAWSアカウントに対して操作をしているのかを確認したいという前提です。 AWS CLIがどのアカウントを見ているかを確認 以下のコマンドでAWS CLIが現在どのアカウントを操作しているかを確認できます。 getcallaws.sh $ aws sts get-caller-identity 以下のコマンドでs3のリストが表示されるのでそれとAWSコンソールを照らし合わせることで確認もできます。 s3ls.sh $ aws s3 ls 仕組み どのAWSアカウントを使うかというのは何段階かで判断しているようです。オプションが無い場合 macであれば~/.aws/credentialsにファイルが生成されていて開いてみると以下のような記述があります。 ~/.aws/credentials [default] aws_access_key_id=EXAMPLEEXAMPLEEXAMPLEEXAMPLE aws_secret_access_key=EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE [account1] aws_access_key_id=ACCOUNT1ACCOUNT1ACCOUNT1ACCOUNT1 aws_secret_access_key=ACCOUNT1ACCOUNT1ACCOUNT1ACCOUNT1ACCOUNT1 これによりアカウントを判断しているようですね。 コマンドオプションとして指定することも可能です またコマンドオプションとして指定してawsアカウントを切り替えて実行することもできます。 $ aws s3 ls --profile account1 このようにすると~/.aws/credentialsのaccount1の情報を元にコマンドが実行されます。 ~/.aws/credentialsとコマンドオプションで指定された値の優先順位は以下のページのように判断されるとのことでした。 構成設定と優先順位 環境変数を使用することもできました。 環境変数を使う .bash_profileなどに書き込んで適用された場合は明示的にunsetで削除するのを忘れないよう注意です。 注意点 eb cliなどサービスごとのCLIツールはまた独自にどのアカウントかを判断しているのでこのAWS CLIが必ず引き継がれるわけではありませんでした。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

The PutObject operation requires non-empty parameterのエラー対応について

下記の記事を参考にs3へ画像を保存する途中でThe PutObject operation requires non-empty parameterのエラーが出たのでその対処法です。 参考にした記事 確認手順 上記記事を参考にcomposerで必要なものを入れたりバケットを作ったり.envを書き換えます。 その後、 php artisan config:cache もしくは php artisan cache:clear を実行 config/filesystems.phpの設定確認 disk arrayのs3の部分を見る .envと比較して.envをきちんと反映しているか確認 実行してみて下記でデバック MainController.php use Config; 省略---- dd(Config::get('filesystems')); s3の部分が反映されていない場合にはconfig/filesystems.phpに直接記入してみて動けばcacheがうまく消えていない可能性が高いです。 感想 自分は古いcacheがうまく消えていなかったのが問題でした。 php artisan cache:clearだけではうまく消えないらしくphp artisan config:cacheを打つとうまく反映されました
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DynamoDB 用の NoSQL Workbench を使用してみる

DynamoDB に最適化された Workbench が AWS から提供されました。NoSQL Workbench は、ローカルに構築された DynamoDB にも対応しているので、 今まで aws cli でデータ確認していたところが、グラフィカルにデータを確認できるようになります。 今回は、DynamoDB Local に保存されたデータを NoSQL Workbench を使って確認してみたいと思います。 セットアップ [Operation Builder]を押下し[Add connection]を押下します。 モーダルが表示されるので、[DynamoDB local]を選択し、任意の[Connection name]を入力します。[Connection name]を入力したら[Connect]を押してコネクションを追加します。 コネクションが登録されると、Operation builder のトップ画面に表示されます。 追加されたコネクションの[Open]を押下すると、データセットが表示されます。 おわりに NoSQL Workbench は、データのクエリだけでなく、Update や Delete 操作も行うことができます。さらに、データモデルの作成もできます。GUI で DynamoDB を操作できるので、DynamoDB のイメージがつかみやすくなるのではないでしょうか。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

.NET5.0製のREST APIサーバーを、AWS CodePipelineでビルドしてコンテナ化してECSでデプロイする。

先日、個人で開発している.NET5.0製のREST APIサーバーをAWS上で動かすにあたり、コンテナ化してECSで管理することにしました。AWSが用意してくれている仕組みに頼ることで、高い品質と高い作業効率を両立できるためです。 この記事では、その際行った設定の概要と設定について記載します。 概要 構成と作業の流れ APIサーバーの構成は下記のようになります。  Internet → CloudFront → EC2(ECS管理) → RDS 参照専用のAPIのため、CloudFrontでキャッシュが利くようにしています。それ以外はAPIサーバーでよく用いられる構成と思います。 このうちの"EC2(ECS管理)"とある個所で、.NET5.0製のコードを動かす。それが今回の目的です。 作業の流れは次のようになります。 GitHub上のコードを取得する 取得したコードをビルドし、さらにコンテナ化する 作成したコンテナをデプロイする この3点をAWS CodePipelineで実現しました。 設定の実際 CodePipelineについて 前置きとして、CodePipelineについて少し触れます。 GithubにPushしたソースコードをビルドしてデプロイするまでの全作業は、CodePipelineで行えます。ですが、実際はビルドをCodeBuildが、デプロイをECSが行っています。 CodePipeline <>--- CodeBuild <>--- ECS 先に記載した作業も、動いているサービスはそれぞれ次のようになります。 GitHub上のコードを取得する ← CodePipeline 取得したコードをビルドし、さらにコンテナ化する ← CodeBuild 作成したコンテナをデプロイする ← ECS したがってCodePipelineでコンテナを用いた自動ビルドを行うためには、CodeBuildとECSも扱える必要があります。初めて扱う場合、いきなりCodePipelineをフルで動かそうとすると大変なため、まずCodeBuild単体、ECS単体を扱えるようになってから挑戦するほうが良いと思います。 なお、今回の記事ではECSやECR、S3やEC2等の設定について記載しませんが、CodePipelineの設定を開始した時点でそれらはすべて用意済の状態です。 1. GitHub上のコードを取得する まず、CodePipelineの名前・Role・CodePipelineが作業用に使うS3バケットを指定した後、ソースコードの取得方法について設定します。Githubを使っている場合はOAuth経由で簡単に設定できます。手なりに進めるだけのため、ここで詰まることはそうそうないと思います。 ちなみに、CodePipelineでは、インプットにあたるソースコード群もアウトプットにあたる生成物(.Net5.0ならXXX.DLL等ですね)も両方 "アーティファクト"と呼びます。前者がSource Artifactや入力アーティファクト、後者がBuild Artifactや出力アーティファクトと呼ばれるようですが、設定画面上ではただアーティファクトとだけ記載されるため入力なのか出力なのか判別し難い事態にしばしば遭遇します。当然ながら入力と出力を勘違いするとひどい結果になるため、設定中は注意が必要です。 2. 取得したコードをビルドし、さらにコンテナ化する CodeBuildの設定を行います。コードのビルドからコンテナ化、ECRへの保存までCodeBuildで行えます。 今回、CodeBuildの環境イメージ、コードをビルドするためのコンテナ、ビルドした生成物を起動するためのコンテナとして、それぞれ次のものを用いました。 環境イメージ aws/codebuild/amazonlinux2-aarch64-standard:2.0 (AWS公式のまま) ビルド用コンテナ mcr.microsoft.com/dotnet/sdk:5.0.400-focal-arm64v8 実行用コンテナ mcr.microsoft.com/dotnet/aspnet:5.0-alpine-arm64v8 いずれもARMアーキテクチャタイプのコンテナである点にご注意ください。私はt4g系のEC2で動かしているためこうなっていますが、x64のインスタンスを利用している方はx64を使う必要があるはずです。 Dockerfile.arm64 コンテナをビルドするためのDockerfileは次のようになっています。ファイル名はDockerfile.arm64です。 # https://github.com/dotnet/dotnet-docker/blob/main/samples/aspnetapp/Dockerfile.alpine-arm64 FROM mcr.microsoft.com/dotnet/sdk:5.0.400-focal-arm64v8 AS build WORKDIR /source # copy csproj and restore as distinct layers COPY src/WritingApi/*.csproj . RUN dotnet restore -r linux-musl-arm64 # copy and publish app and libraries COPY src/WritingApi/ . RUN dotnet publish -c release -o /app -r linux-musl-arm64 --self-contained false # final stage/image FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine-arm64v8 WORKDIR /app RUN apk --no-cache add curl COPY --from=build /app . # See: https://github.com/dotnet/announcements/issues/20 # Uncomment to enable globalization APIs (or delete) # ENV \ # DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false \ # LC_ALL=en_US.UTF-8 \ # LANG=en_US.UTF-8 # RUN apk add --no-cache icu-libs ENTRYPOINT ["./WritingApi"] 公式のサンプルを参考にしつつ、自分の環境に合わせて作りました。 ディレクトリ構成 ディレクトリ構成は下記となります(抜粋)。 ./ │ buildspec.yml │ Dockerfile.arm64 │ Dockerfile.x64 │ imagedefinitions.json │ └─src │ WritingApi.sln │ └─WritingApi │ appsettings.Development.json │ appsettings.json │ appsettings.Production.json │ Program.cs │ Startup.cs │ WritingApi.csproj │ ..... buildspec.yml CodeBuildで用いるbuildspec.ymlは下記の内容となっています。 version: 0.2 phases: build: commands: - echo Build started on `date` - docker build -t writing-tools-api -f Dockerfile.arm64 --platform linux/arm64 . post_build: commands: - aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 314544748592.dkr.ecr.ap-northeast-1.amazonaws.com - docker tag writing-tools-api:latest 314544748592.dkr.ecr.ap-northeast-1.amazonaws.com/writing-tools-api:latest - docker push 314544748592.dkr.ecr.ap-northeast-1.amazonaws.com/writing-tools-api:latest 余談ながら、開発時は最初からbuildspec.ymlをgithubにpushするのではなく、まず"ビルドコマンドの挿入"を使いました。ある程度固まってからbuildspec.ymlに保存しました。このほうがフィードバックが早くてTry&Errorを繰り返しやすい上、gitの履歴も汚さずにすむためです。 3. 作成したコンテナをデプロイする デプロイの設定を行います。デプロイ作業はECSを通して行われるため、デプロイプロバイダーもECSを選んでいます。 imagedefinitions.json イメージ定義ファイルは下記の内容になっています。今のところlatestで運用しているためimageUriのタグはlatestです。 [ { "name": "WritingToolsApi", "imageUri": "314544748592.dkr.ecr.ap-northeast-1.amazonaws.com/writing-tools-api:latest" } ] nameにはECSのタスクで設定したコンテナ名を入力します。 以上。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む