Posts

AWSコスト配分タグで始めるコスト管理

  • POSTS
1. はじめに AWS上でプロジェクトごとの料金を把握できていますか。 AWSアカウント上に複数のプロジェクトが稼働していて、特定のプロジェクトでどのくらい料金がかかっているか確認する方法を書いていきます。 プロジェクトごとに料金を把握するのに必要な要素は、 Billing and Cost Management の コスト配分タグ です。 コスト配分タグについて学んでいきましょう。 2. コスト配分タグとは? コスト配分タグとは、AWSリソースにタグ付けを行い、コストをタグ単位で分析、可視化できる仕組みのことを言います。 2.1 コスト配分タグの概要 タグは、多くのAWSリソースにKey, Valueの形式で付与可能です。 リソースタイプ キー バリュー Lambda Project cloud-steps S3 Project cloud-steps このようにLambda, S3にProjectキーを付与することができます。 Projectごとにタグを設定するとcloud-stepsで利用しているリソースを抽出することができます。 2.1 「ユーザー定義タグ」と「AWS生成タグ」の違い ユーザー定義タグとAWS生成タグの違いについて説明します。 ユーザー定義タグとは、その名の通りユーザーがAWSリソースに対して定義できるタグのことです。 CloudFormationテンプレート例 VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 192.168.0.0/20 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name - Key: Project 一方で、AWS生成タグとは、AWSが自動的にAWSリソースに付与するタグのことをいいます。 AWSタグ例 aws:cloudformation:stack-id aws:createdBy aws:cloudformation:stack-name 3. コスト配分タグの使い方ステップ 3.1. タグの付与 タグをリソースに付与します。 タグの付与単位は各現場のタグの付与方針によります。 ここでは、プロジェクト単位でタグを付与します。 タグの設定意図は、プロジェクト単位のコストを可視化すとためです。 VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 192.168.0.0/20 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Project Value: cloud-steps 3.2. コスト配分タグ(ユーザー定義タグ)の有効化 AWSマネージメントコンソールの検索フォームから Billing and Cost Management 左メニューのコスト組織>コスト配分タグをクリックする コスト配分タグ画面が表示されたらユーザー定義のコスト配分タグタブを選択 コスト配分タグとして有効化したいタグキーにチェックを入れる。※ここでは、cloud-stepsを選択 有効化ボタンをクリック 3.3. コスト配分タグ(AWS生成コスト配分タグ)の有効化(任意) AWSマネージメントコンソールの検索フォームから Billing and Cost Management 左メニューのコスト組織>コスト配分タグをクリックする コスト配分タグ画面が表示されたらAWS生成コスト配分タブを選択 コスト配分タグとして有効化したいタグキーにチェックを入れる。※ここでは、aws:createdByを選択する 有効化ボタンをクリック 3.4. コストエクスプローラーの利用 AWSマネージメントコンソールの検索フォームから Billing and Cost Management 左メニューのコストと使用状況の分析>Cost Explolerを選択する 右メニューのレポートパラメータのフィルター機能でユーザータグごとのコストを抽出する グループ化の条件>ディメンション>Tag>Project フィルター>タグ>Project>cloud-stepsをクリックする。 5. 躓いたポイント コスト配分タグは有効化直後反映されないことがあります。

複数Lambda × API Gateway をCDKでスマートに構築する方法(IAM分離・JSON管理付き)

  • POSTS
1. はじめに Lambda ✕ ApiGatewayでAPIを構築することが良くあります。 この構成をAWS SAM や CloudForamtionで構築することがありましたが、APIが数十個構築する必要があるとLambdaごとにテンプレートを作成するのが大変になります。 また、手作業でテンプレートをAWS SAM に記載すると追加漏れや修正漏れが発生することが、見受けられました。 こういった場面で CDK を利用するとスマートに構築することができます。 2. やりたいこと Lambdaを複数定義する。 API GatewayとLambdaを紐付ける。 IAM を別スタックに分離する。 CLoudWatch のロググループを明示的に作成する。 前提 AWS CLIインストール済みであること Python3.13インストール済みであること AWS CDKインストール済みであること 3. 構成 3.1. スタックの構成 AppStack IamStack ↓ ↓ [Lambda] [IAM Role] ↓ [LogGroup] ↓ [API Gateway] 3.2. ディレクトリ構造 . └── cdk_test ├── app.py ├── cdk.json ├── functions.json ├── lambda │ ├── lambda_1 │ │ └── handler.py │ ├── lambda_2 │ │ └── handler.py │ └── handler.py ├── requirements-dev.txt ├── requirements.txt ├── source.bat ├── stacks │ ├── __init__.py │ ├── app_stack.py │ └── iam_stack.py 4. Lambdaの定義をjsonで管理するメリット Lambdaの追加や設定の変更時にコードを修正する必要がなくなる。 5. 実装コード紹介 5.1 functions.json Lambdaを追加する際はこのjsonファイルに記述する。

CloudWatchのログをboto3でフィルタリングする

  • POSTS
1. はじめに CloudWatch Logsに出力されるログによってプログラムの処理フローを分岐する必要がある要件がありました。 これまでCloudWatch Logsを操作する機会がなかったため、boto3を用いたログのフィルタリング方法について備忘録として記事を残します。 2. CloudWatch Logsとは CloudWatch Logsは、Lambda、EC2、CloudTrail、Route53などのAWSリソースから出力されるログをモニタリング、保存、検索するためのサービスです。 AWSマネジメントコンソールからログの閲覧や文字列検索が可能なほか、例えば ERROR という文字列を検出したタイミングでCloudWatch Alarmをトリガーし、SNSで通知を行うこともできます。 3. 環境 AWS Lambda(Python 3.13) boto3 リージョン:us-west-2 4. boto3でCloudWatch Logsをフィルタリングする 4.1 boto3とは boto3は、PythonからAWSリソースを操作するための公式SDK(Software Development Kit)です。 ※ Lambdaを利用している場合、boto3はデフォルトで利用することができます。 今回はCloudWatch Logsのfilter_log_events APIを使い、特定のパターンにマッチするログを抽出します。 filter_log_eventsを利用して、Pythonでログの解析、分析に役立てることができます。 4.2 サンプルソースコード 以下のプログラムは、CloudWatch Logs に出力された過去1時間分のログから “START_DATE” と “SUCCESS” を含む JSON 形式のログメッセージを抽出し、START_DATE の中で最新の日付を1件だけ取得・表示する Lambda 関数です。 import boto3 import time from datetime import datetime, timedelta import json import logging logger = logging.getLogger("my_lambda_logger") logger.setLevel(logging.INFO) if not logger.handlers: handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) client = boto3.client('logs', region_name='us-west-2') log_group_name = '/aws/lambda/log-group-name' def lambda_handler(event, context): end_time = int(time.time() * 1000) start_time = int((datetime.utcnow() - timedelta(minutes=60)).timestamp() * 1000) start_dates = [] next_token = None while True: kwargs = { "logGroupName": log_group_name, "startTime": start_time, "endTime": end_time, "filterPattern": '?START_DATE ?SUCCESS' } if next_token: kwargs["nextToken"] = next_token response = client.filter_log_events(**kwargs) for e in response.get("events", []): try: message = json.loads(e["message"]) if "START_DATE" in message: start_dates.append(message["START_DATE"]) except Exception as ex: logger.warning(f"Failed to parse message: {e['message']} -- {ex}") next_token = response.get("nextToken") if not next_token: break logger.info(f"Collected START_DATEs: {start_dates}") if start_dates: dt_dates = [datetime.strptime(d, "%Y-%m-%d") for d in start_dates] dt_dates.sort(reverse=True) latest_one = dt_dates[:1] latest_one_str = [d.strftime("%Y-%m-%d") for d in latest_one] else: latest_one_str = [] 4.3 filter_log_eventsの解説 filter_log_events は、指定したロググループの中から特定の条件にマッチするログイベントを抽出するための boto3 の API です。大量のログデータの中から、必要な情報を取得するのに適しています。

LambdaでクロスアカウントのS3にアクセスする

  • POSTS
1. はじめに Lambdaから別AWSアカウントのリソースにアクセスする要件がたまにあります。 別AWSリソースにアクセスすることをクロスアカウントアクセスといいます。 ただ、私はクロスアカウントアクセスという単語を耳にしたことがありますが、自分自身で設定をおこなったことがなかったので、一度設定をしてみました。 ここでは、LambdaからクロスアカウントのS3にアクセスするための設定をまとめます。 2. 前提 AWSアカウントを2つ用意していること。 LambdaがあるアカウントをAアカウント、S3があるアカウントをBアカウントとする。 3. 関連知識 クロスアカウントアクセスに必要な知識を解説します。 3.1 AWS Security Token Service (AWS STS) とは AWS Security Token Service (以下、AWS STS) とは、AWSリソースへのアクセスコントロールできるサービスで一時的な認証情報発行します。 AWS STSは、クロスアカウントのアクセスや他要素認証などに利用されます。この一時的なクレデンシャルは数分~最大12時間までの有効期限を設定できます。 3.2 Assume Roleとは **Assume Role(アシュームロール)**とは、一時的に別の権限を持ったロールを使えるようにする仕組みです。 AWSでは、通常IAMユーザーやLambdaなどが操作を行いますが、Assume Roleを使うと、 一時的な認証情報を作成して、そのロールを引き受けて、そのロールが持っている権限でAWSサービスにアクセスできます。 この一時的な認証情報は**AWS STS(Security Token Service)**が発行します。 4. AWS構成図 5. クロスアカウントアクセスするための設定 5.1 Aアカウント側のLambdaの実行ロール Lambda実行ロール作成します。 クロスアカウントアクセスするために重要なのが、sts.AssumeRoleを付与しやポリシーを作成することです。 Resourceには、クロスアカウント先のロールを取得します。 ここでは、アカウントBに作成するS3にアクセスするための、ロールを作成し、そのロールを引き受けられるように設定します。 AWSTemplateFormatVersion: '2010-09-09' Resources: LambdaExecutionRole: Type: AWS::IAM::Role Properties: RoleName: 'lambda-execution-role' AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: 'allow-cloud-watchlogs-access' PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogStream - logs:PutLogEvents - logs:DescribeLogStreams - logs:CreateLogGroup Resource: '*' - PolicyName: 'allow-access-s3-bucket' PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: sts:AssumeRole Resource: arn:aws:iam::{アカウントB}:role/CrossAccountLambdaAccessRole 5.2 Lambdaのアプリケーションコード STSでアカウントBのCrossAccountLambdaAccessRoleへの一時的な認証情報を取得し、アカウントAのLambdaがCrossAccountLambdaAccessRoleを引き受けます。

Application Load Balancer をCloudFormationで構築する

  • POSTS
1. はじめに Application Load Balancerを構築を簡単に構築したので、構築手順と構成をまとめておきます。 2. CloudFormationテンプレート 2.1. VPCの作成 VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 192.168.0.0/20 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: 'vpc' 2.2. インターネットゲートウェイの作成 VPCにアタッチするインターネットゲートウェイを作成する InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: 'internet-gateway' AttachGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref InternetGateway 2.3. ルートテーブルの作成 パブリックサブネット用のルートテーブルをサブネットごとに作成する。 Az1PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Az1PublicRoute: Type: AWS::EC2::Route DependsOn: GymManagementAttachGateway Properties: RouteTableId: !Ref Az1PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway Az1PublicSubnetRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref EcsPublicSubnetAZ1 RouteTableId: !Ref Az1PublicRouteTable Az2PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Az2PublicRoute: Type: AWS::EC2::Route DependsOn: GymManagementAttachGateway Properties: RouteTableId: !Ref Az2PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway 2.4. パブリックサブネットの作成 パブリックサブネットは、ALBの使用上、複数作成する必要あります。

EC2 と SessionManager で踏み台サーバーを作成する

  • POSTS
1. はじめに 今回は、AWS Systems Manager の Session Manager を利用して、踏み台サーバー(Bastion Host)の代替手段を構築する方法を紹介します。 Session Manager を活用することで、従来の踏み台サーバーに比べてセキュリティや運用性が向上します。たとえば、SSH鍵の管理や開放ポートの運用から解放され、よりシンプルかつセキュアなアクセス環境を実現できます。 2. Session Managerとは AWS Session Managerは、AWS System Manager の機能の1つで、EC2インスタンスやオンプレミスサーバーに対して、安全にサーバーにアクセス可能にするサービスです。 2.1 Session Managerを利用するメリット ポートを開く必要がない・鍵管理不要 従来の踏み台サーバーには、sshの22番ポートを開く必要がありますが、AWS Session Managerを利用すれば、ポートを開く必要がなくセキュアに踏み台サーバーを運用することが可能になります。また、sshキーの管理が不要になります。 ポート転送 EC2インスタンスで動いているアプリケーションに対して、ローカルPCのローカルポートからアクセスできるようになります。また、ローカルPCからEC2インスタンスを踏み台にして、プライベートサブネットに配置されているRDSなどのデータベースにアクセス可能になります。 3. 実際の構成図 4. AWS Session Managerで踏み台サーバー構築する 4.1. VPCを作成する VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 192.168.0.0/20 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: 'vpc' 4.2. プライベートサブネットを作成する PrivateSubnetAZ1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [0, !GetAZs ''] CidrBlock: 192.168.0.0/24 MapPublicIpOnLaunch: false Tags: - Key: Name Value: 'private-subnet-az1' PrivateSubnetAZ2: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [2, !GetAZs ''] CidrBlock: 192.168.1.0/24 MapPublicIpOnLaunch: false Tags: - Key: Name Value: 'private-subnet-az2' 4.3. データベースを構築する RdsDbCluster: Type: 'AWS::RDS::DBCluster' Properties: AvailabilityZones: - !Select [0, !GetAZs ''] - !Select [2, !GetAZs ''] BackupRetentionPeriod: 7 DBClusterIdentifier: !Sub '${ProjectName}-database' DBClusterParameterGroupName: !Sub '${ProjectName}-aurora-parameter-group' DatabaseName: gym_db DBSubnetGroupName: !Sub '${ProjectName}-aurora-subnet-group' Engine: 'aurora-mysql' Port: 3306 MasterUsername: 'admin_user' MasterUserPassword: "DBのパスワード" PreferredBackupWindow: '17:20-17:50' PreferredMaintenanceWindow: 'sun:15:00-sun:16:00' VpcSecurityGroupIds: - !ImportValue SgDbSecurityGroup StorageEncrypted: true EnableIAMDatabaseAuthentication: false # 通常のAuroraかAurora Serverlessか選択可能 EngineMode: 'provisioned' DeletionProtection: false EnableHttpEndpoint: false AuroraSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: 'subnet group' DBSubnetGroupName: 'aurora-subnet-group' SubnetIds: - !Ref PrivateSubnetAZ1 - !Ref PrivateSubnetAZ2 AuroraClusterParameterGroup: Type: AWS::RDS::DBClusterParameterGroup Properties: Description: Aurora MySQL 8.0 cluster parameter group DBClusterParameterGroupName: 'aurora-parameter-group' Family: aurora-mysql8.0 Parameters: time_zone: Asia/Tokyo character_set_database: utf8mb4 Tags: - Key: Name Value: 'aurora-cluster-param-group' DbInstance: Type: AWS::RDS::DBInstance Properties: AllowMajorVersionUpgrade: false # DBインスタンスの変更を即時反映させるかメンテナンスウィンドウ時に反映させるか ApplyImmediately: true AutoMinorVersionUpgrade: false # 自動バックアップの保持期間 BackupRetentionPeriod: 0 DBClusterIdentifier: !Ref RdsDbCluster DBInstanceClass: db.t3.medium DBInstanceIdentifier: 'db-instance' DBSubnetGroupName: 'aurora-subnet-group' DeleteAutomatedBackups: true Engine: aurora-mysql PreferredMaintenanceWindow: 'sun:17:00-sun:17:30' PubliclyAccessible: false 4.4. EC2を作成する BastionInstance: Type: AWS::EC2::Instance Properties: AvailabilityZone: !Select [0, !GetAZs ''] DisableApiTermination: false IamInstanceProfile: !Ref BastionInstanceProfile ImageId: ami-07b0c09aab6e66ee9 InstanceType: t2.small Monitoring: true SecurityGroupIds: - !Ref BastionSecurityGroup SubnetId: !Ref PrivateSubnetAZ1 Tags: - Key: Name Value: 'bastion-instance' BastionInstanceProfile: Type: "AWS::IAM::InstanceProfile" Properties: Path: "/" Roles: - !Ref SessionManagerRole 4.5. VPCエンドポイント SsmEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssm' VpcId: !Ref VPC VpcEndpointType: Interface SubnetIds: - !Ref PrivateSubnetAZ1 - !Ref PrivateSubnetAZ2 PrivateDnsEnabled: true SecurityGroupIds: - !Ref SsmVpcEndpointSg Tags: - Key: Name Value: 'logs-vpc-endpoint' SsmMeessagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssmmessages' VpcId: !Ref VPC VpcEndpointType: Interface SubnetIds: - !Ref PrivateSubnetAZ1 - !Ref PrivateSubnetAZ2 PrivateDnsEnabled: true SecurityGroupIds: - !Ref SsmVpcEndpointSg Tags: - Key: Name Value: 'logs-vpc-endpoint' 4.6. IAM Resources: SessionManagerRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - 'sts:AssumeRole' Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore Outputs: SessionManagerRole: Value: !Ref SessionManagerRole Export: Name: SessionManagerRole 4.8. セキュリティグループ BastionSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: "Security group for Bastion host using Session Manager" VpcId: !Ref VPC SecurityGroupEgress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 3306 ToPort: 3306 CidrIp: 0.0.0.0/0 SsmVpcEndpointSg: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: "Allow SSM traffic" VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 4.9. SSMプラグインをローカルPCにインストールする 以下のページを参考にSSMプラグインをPCにインストールする。

ECS FargateをCloudForamtionで作成する方法

  • POSTS
1. はじめに 今回は、ECS FargateをCloudformationで構築する方法を説明していきます。 ECSについて、興味があったのですが、学習できていませんでした。最近時間ができたので、ECS Fargateを構築したので、構築手順をまとめました。 2. ECSとは ECS(Amazon Elastic Container)とは、コンテナ化されたアプリケーションをデプロイ、管理、スケーリングするためのコンテナ管理サービスです。 2.1 ECSを構成する構成要素 2.1.1 クラスター クラスターは、サービスとタスクをグループ化する要素です。 2.1.2 サービス サービスは、コンテナ化されたアプリケーションの実行とスケーリングを容易にする、フルマネージド型のコンテナオーケストレーションサービスです。 サービスで設定できる項目 クラスター サービスやタスクを実行するクラスターを設定する タスク定義 実行するコンテナのリソースや環境変数など デプロイメント ローリングアップデートやCode ターゲット数 サービスが維持するタスク数を設定。 ロードバランサ タスクのトラフィックを分散する ヘルスチェック タスクの健全性を監視する AutoScaling タスク数を自動で増減。CPU使用率やメモリの使用率に基づいて増減する。 ローンチタイプ ECS2かFargateを設定する 2.1.3 タスク タスクは、1つ以上のコンテナをまとめて実行する単位です。ECSでは、アプリケーションをデプロイ・実行する最小単位です。 タスクの実行内容は、タスク定義に基づきます。 タスクで設定できる項目 使用するDockerイメージ コンテナごとのCPU/メモリ割当て ポートマッピング 環境変数 ログ設定 4. 構成図 5. 構築手順 プライベートサブネットにECSを作成する方法です。 5.1 VPC VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 192.168.0.0/20 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: 'vpc' EcsPrivateSubnetAZ: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [0, !GetAZs ''] CidrBlock: 192.168.0.0/24 MapPublicIpOnLaunch: false Tags: - Key: Name Value: 'ecs-private-subnet' SgEcsSecurityGroup: Type: AWS::EC2::SecurityGroup DependsOn: AlbSecurityGroup Properties: GroupDescription: 'sg-ecs-security-group' GroupName: 'sg-ecs-security-group' SecurityGroupEgress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 Tags: - Key: Name Value: 'sg-ecs' VpcId: !Ref VPC EcrVpcEndpointSg: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow HTTPS for VPC Endpoints VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 CloudWatchVpcEndpointSg: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow HTTPS for VPC Endpoints VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 SourceSecurityGroupId: !Ref SgEcsSecurityGroup #---------------------------------------------# # VPC Endpoint # #---------------------------------------------# # プライベートサブネットのECSからECRからイメージ取得するために必要 ECRApiEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ecr.api' VpcId: !Ref VPC VpcEndpointType: Interface SubnetIds: - !Ref EcsPrivateSubnetAZ PrivateDnsEnabled: true SecurityGroupIds: - !Ref EcrVpcEndpointSg Tags: - Key: Name Value: 'ecr-api-endpoint' # プライベートサブネットのECSからECRからイメージ取得するために必要 ECRDockerEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ecr.dkr' VpcId: !Ref VPC VpcEndpointType: Interface SubnetIds: - !Ref EcsPrivateSubnetAZ PrivateDnsEnabled: true SecurityGroupIds: - !Ref EcrVpcEndpointSg Tags: - Key: Name Value: 'dcr-endpoint' # プライベートサブネットのECSからCloudwatchにログ出力するために必要 CloudWatchEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Sub 'com.amazonaws.${AWS::Region}.logs' VpcId: !Ref VPC VpcEndpointType: Interface SubnetIds: - !Ref EcsPrivateSubnetAZ PrivateDnsEnabled: true SecurityGroupIds: - !Ref CloudWatchVpcEndpointSg Tags: - Key: Name Value: 'logs-vpc-endpoint' 5.2 クラスター作成 ECSCluster: Type: AWS::ECS::Cluster Properties: ClusterName: cluster CapacityProviders: - FARGATE ClusterSettings: - Name: containerInsights Value: enabled 5.3 サービス作成 ECSService: Type: 'AWS::ECS::Service' Properties: ServiceName: ecs-service Cluster: !Ref ECSCluster TaskDefinition: !Ref FargateTaskDefinition DesiredCount: 1 LaunchType: FARGATE DeploymentController: Type: CODE_DEPLOY NetworkConfiguration: AwsvpcConfiguration: AssignPublicIp: DISABLED SecurityGroups: - !Ref SgEcsSecurityGroup Subnets: - !Ref EcsPrivateSubnetAZ LoadBalancers: - ContainerName: dynamo ContainerPort: 8080 TargetGroupArn: !Ref TargetGroup 5.4 タスク定義作成 FargateTaskDefinition: Type: AWS::ECS::TaskDefinition Properties: ContainerDefinitions: # ECRのリポジトリを指定する - Name: test Image: !Sub '${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/xxxxxxx' Cpu: 0 PortMappings: - Name: test ContainerPort: 8080 HostPort: 8080 Protocol: tcp AppProtocol: http Essential: true LogConfiguration: LogDriver: awslogs Options: awslogs-group: /ecs/tests awslogs-region: !Sub ${AWS::Region} awslogs-stream-prefix: ecs Family: ecs-family-name ExecutionRoleArn: !Sub 'arn:aws:iam::${AWS::AccountId}:role/ecs-task-execution-role' NetworkMode: awsvpc Cpu: 1024 Memory: 3072 5.5 ECSロール作成 EcsTaskExecutionRole: Type: AWS::IAM::Role Properties: RoleName: 'ecs-task-execution-role' AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ecs-tasks.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy Policies: - PolicyName: AllowCloudWatchLogsAccess PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogStream - logs:PutLogEvents - logs:DescribeLogStreams - logs:CreateLogGroup Resource: '*' 6. まとめ ECSをCloudFormationで構築してみました。以前、AWSマネジメントコンソールで作成したことがありました。

AWSのCodeFamilyで静的ページをS3デプロイする方法

  • POSTS
1. はじめに このブログ(Cloud Steps)は、CloudFront+S3の構成で静的サイトを運用しています。 ブログを更新する際、S3にファイルをアップロードする必要がありますが、 ブログ更新の度にS3コマンドやAWSマネジメントコンソールからファイルアップロードするのは、少し面倒です。 なので、GitHubへのpushを検知し、CodeFamilyで自動的にS3にファイルの変更を自動で反映できるようしました。 2. Hugoとは Hugoは、オープンソースの静的サイト生成ツールです。 マークダウンファイルを記述すれば、静的ファイルを生成することができ、簡単に、柔軟に、静的サイトを作成することができます。 サイトのデザインはコントリビューターが作成したテーマを適応すれば、自由に変更することができます。また、自分自身でテーマを作成することも可能なので、デザインにこだわりがある人はテーマを作成するのもいいでしょう。 ※ Hugoの導入方法や利用方法は、この記事では対象外とします。 3. CodeFamilyとは CodeFamilyとは、AWSが提供するソフトウェア開発とデプロイメントのライフサイクルを支援するサービス群の総称です。CodeFamilyは、公式なサービス名ではなく、一般的に以下のような 「Code」から始まるAWSサービス群 を指すことが多いです。 CodeFamily CodePipeline CodeBuild CodeDeploy CodeStar(非推奨) このページでは、CodePipeline, CodeBuildについて書いていきます。 3.1 CodeBuild CodeBuildは、フルマネージドの継続的インテグレーションサービスです。 アプリケーションコードのコンパイル、テストを実行などのビルド環境を提供するサービスです。 CodeBuildは、フルマネージドなサービスのため、ユーザーがビルドサーバーのプロビジョニングの必要なく、サーバーのパッチ適用などのメンテナンス作業を必要としません。 3.2 CodePipeline CodePipeline は、継続的インテグレーション(CI)と継続的デリバリー(CD) を自動化するための パイプライン構築サービス です。アプリケーションのコードの変更が本番環境に届くまでの一連の流れ(ビルド、テスト、デプロイなど)をステージごとに視覚的に構成して自動化できます。 4. 構成図 5. パイプライン構築手順 作成するリソース AWSとGithubの接続 CodePipeline CodeBuild IAM 5.1 GitHubとCodePipelineを接続する GitHubとCodePipelineの接続は、AWSマネージメントコンソールから行います。 AWSマネージメントコンソールの検索欄からCodeBuildと検索>左ペインの設定>接続>接続ボタンをクリック。 プロバイダー選択で「GitHub」を選択する。 「GitHubアプリ接続を作成する」に任意の接続名を入力し、「GitHubに接続する」をクリックする。 GitHubの認証情報をきかれるので入力する。 5.2 CodePipelineを作成する CodePipelineでステージを作成する。 Pipeline: Type: AWS::CodePipeline::Pipeline Properties: Name: !Sub "${ProjectName}-pipeline" RoleArn: !GetAtt PipelineRole.Arn ArtifactStore: Type: S3 Location: !Ref ArtifactBucket Stages: - Name: Source Actions: - Name: GitHub_Source ActionTypeId: Category: Source Owner: AWS Provider: CodeStarSourceConnection Version: 1 OutputArtifacts: - Name: SourceOutput Configuration: ConnectionArn: !Ref CodeStarConnectionArn FullRepositoryId: !Ref GitHubRepo BranchName: main DetectChanges: true RunOrder: 1 - Name: Build Actions: - Name: CodeBuild ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: 1 InputArtifacts: - Name: SourceOutput OutputArtifacts: - Name: BuildOutput Configuration: ProjectName: !Ref CodeBuildProject RunOrder: 1 5.3 CodeBuildを作成する CodeBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub '${ProjectName}-hugo-deploy' ServiceRole: !GetAtt CodeBuildServiceRole.Arn Artifacts: Type: CODEPIPELINE Environment: Type: LINUX_CONTAINER ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/standard:7.0 Source: Type: CODEPIPELINE BuildSpec: buildspec.yml 5.4 buildspec.yamlを作成する buildspec.yamlとは、そもそもなんでしょうか。

プライベートサブネットに配置されたECSからVPCを通じてDynamoDBに接続する方法

  • POSTS
1. はじめに 個人プロジェクトでAWSでインフラを構築してた際にプライベートサブネットからDynamoDBに接続する構成を作成しました。 プライベートサブネットからVPCを接続するには、VPCエンドポイントを作成してVPC外のAWSサービスにアクセスする必要があります。 VPCエンドポイントを通してVPC外のAWSサービスにアクセスする方法を解説します。 ※ NatGatewayを利用する方法がありますが、ここでは対象外とします。 2. なぜVPCエンドポイントを利用するのか VPC のプライベートサブネットからVPC外のリソースにアクセスするには、VPCエンドポイントを作成することで可能です。 なぜVPCエンドポイントが必要かというと、プライベートサブネットからVPC外部のAWSサービスにアクセスするための経路がないためです。 2.1 そもそもVPCエンドポイントとは VPCエンドポイントとは、AWSのVPCから、インターネットを経由せずにAWSサービスに安全にアクセスできる仕組みです。 VPCエンドポイントはインターフェース型とゲートウェイ型があります。 DynamoDBとS3はゲートウェイ型で、それ以外のAWSサービスはインターフェース型です。 2.2 インターフェース型エンドポイント ENI(Elastic Network Interface)を使って、VPC内にENI(仮想ネットワークインターフェース)を作成し、対象のサービスにアクセスします。 特徴 多くのAWSサービスに対応している エンドポイントはVPC内にENIとして作成され、プライベートIPが割り当てられる。 セキュリティグループを設定できる。 2.3 ゲートウェイ型エンドポイント VPCルートテーブルを使用して、特定のAWSサービス(現在はS3とDynamoDBのみ)にゲートウェイ経由でアクセスします。 特徴 S3, DynamoDBに対応します。 ルートテーブルにターゲットとして設定する。 セキュリティグループは使えないが、エンドポイントポリシーでアクセス制御が可能です。 3. 構成図 プライベートサブネットのECSからDynamoDBへアクセスする図です。 4. 実際の手順 ここでは、VPCの作成からエンドポイントの作成までの手順を書いていきます。 ゲートウェイエンド型ポイントを通してDynamoDB接続に必要なリソース VPC プライベートサブネット ルートテーブル VPCエンドポイント VPCを作成する。 VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 192.168.0.0/20 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: 'vpc' プライベートサブネットを作成する。 PrivateSubnet: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [0, !GetAZs ''] CidrBlock: 192.168.0.0/23 MapPublicIpOnLaunch: false Tags: - Key: Name Value: 'ecs-private-subnet' ルートテーブルを作成する。