TECH PLAY

SCSKクラウドソリューション

SCSKクラウドソリューション の技術ブログ

1141

今回は、AWS Systems Manager InventoryによるEC2インスタンスのソフトウェア、設定、ファイル、レジストリ情報の自動収集システムをAWS CDKで実装する方法をまとめました。 はじめに 今回は、AWS Systems Manager Inventoryを使用して、EC2インスタンスのソフトウェア情報、システム設定、インストールされているファイル、Windowsレジストリ情報などを自動収集し、S3バケットに保存するアーキテクチャをAWS CDKで実装していきます。   今回作成するリソース S3バケット : SSMインベントリデータの保存先 バケットポリシー : SSMサービス専用のアクセス権限 SSM Association : インベントリ収集の自動実行設定 Resource Data Sync : インベントリデータの一元化と同期   アーキテクチャ概要   AWS CDK ソースコード S3バケット設定(インベントリ保存) const ssmInventoryBucket = new s3.Bucket(this, 'SsmInventoryBucket', { bucketName: `s3b-ssm-inventory-bucket`,   // バケット名 blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, // パブリックアクセスをすべてブロック encryption: s3.BucketEncryption.S3_MANAGED, // 暗号化タイプ:SSE-S3 autoDeleteObjects: true, // バケット削除時にオブジェクトも削除 デプロイ成功後にfalseに設定 enforceSSL: true, // SSL/TLS暗号化を強制 lifecycleRules: [ // ライフサイクルルール作成 { id: 'Expiration Rule 12 Months', // ライフサイクルルール名 expiration: cdk.Duration.days(366), // 1年間保持 } ], removalPolicy: cdk.RemovalPolicy.DESTROY, // スタック削除時にバケットも削除 デプロイ成功後にRETAINに変更 }); // バケットポリシー追加 ssmInventoryBucket.addToResourcePolicy(new iam.PolicyStatement({ // バケットポリシー追加 sid: 'AWSSSMInventoryWrite', // ステートメントID effect: iam.Effect.ALLOW, // 許可 actions: [ // 許可するアクション 's3:PutObject' // オブジェクトの配置を許可 ], resources: [ // 対象リソース `${ssmInventoryBucket.bucketArn}/AWSLogs/${cdk.Stack.of(this).account}/SSM/*`, // SSMログ用パス ssmInventoryBucket.bucketArn, // バケット自体 ], principals: [new iam.ServicePrincipal('ssm.amazonaws.com')], // SSMサービス conditions: { // 条件 StringEquals: { // 文字列完全一致 's3:x-amz-acl': 'bucket-owner-full-control', // ACL制御 'aws:SourceAccount': cdk.Stack.of(this).account // 送信元アカウント制限 } } })); ポイント: セキュア設計 : パブリックアクセス完全ブロック、SSL強制 長期保存 : コンプライアンス要件に応じた1年間保持 暗号化 : SSE-S3による自動暗号化 コスト管理 : ライフサイクルポリシーによる自動削除 最小権限 : SSMサービスのみにPutObject権限を付与 アカウント制限 : 自アカウントからのアクセスのみ許可 ACL制御 : バケット所有者の完全制御を保証 パス制限 : SSM専用パスのみへのアクセス制限 SSM Association設定 const inventoryAssociation = new ssm.CfnAssociation(this, 'InventoryAssociation', { name: 'AWS-GatherSoftwareInventory', // 実行するSSMドキュメント名 associationName: 'ssm-inventory', // インベントリ名 targets: [{ // ターゲット key: 'InstanceIds', // 対象キー values: ['*'] // 対象値 }], parameters: { 'applications': ['Enabled'], // アプリケーション情報を収集 'awsComponents': ['Enabled'], // AWSコンポーネント情報を収集 'networkConfig': ['Enabled'], // ネットワーク設定情報を収集 'windowsUpdates': ['Enabled'], // Windowsアップデート情報を収集 (Windowsのみ) 'instanceDetailedInformation': ['Enabled'], // インスタンスの詳細情報を収集 'services': ['Enabled'], // サービス設定を収集 (Windowsのみ) 'windowsRoles': ['Enabled'], // Windowsロール設定を収集 (Windowsのみ) 'customInventory': ['Enabled'], // カスタムインベントリデータを収集 'billingInfo': ['Enabled'], // ライセンス含有アプリケーションの課金情報を収集 'files': ['[{"Path":"C:\\Program Files","Pattern":["*.exe"],"Recursive":true}]'], // ファイルを収集 'windowsRegistry': ['[{"Path":"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion","ValueNames":["ProductName"],"Recursive":false}]'], // Windowsレジストリデータを収集 }, scheduleExpression: 'rate(30 minutes)', // インベントリの収集頻度:30分ごと outputLocation: { // 実行結果出力先指定 s3Location: { outputS3BucketName: ssmInventoryBucket.bucketName, // インベントリ用のバケットに出力 outputS3KeyPrefix: `AWSLogs/${cdk.Stack.of(this).account}/SSM/Logs` // ディレクトリを作成 } } }) ポイント: 包括的収集 : ソフトウェア、設定、ファイル、レジストリの全面的な情報収集 定期実行 : 30分間隔での自動収集(要件に応じて調整可能) カスタマイズ : ファイルパスやレジストリキーの設定 構造化出力 : JSON形式での構造化されたデータ保存 Resource Data Sync設定 //resourceデータの同期設定 const resourceDataSync = new ssm.CfnResourceDataSync(this, 'ResourceDataSync', { // リソースデータの同期 syncName: 'resource-data-sync', // 同期名 s3Destination:{ bucketName: ssmInventoryBucket.bucketName, // バケット名 bucketPrefix: `AWSLogs/${cdk.Stack.of(this).account}/SSM/`, // バケットプレフィックス名 bucketRegion: cdk.Stack.of(this).region, // バケットのリージョン:東京リージョン syncFormat: 'JsonSerDe' // 同期形式:JSON } }); // 依存関係の設定 resourceDataSync.node.addDependency(inventoryAssociation); // 先にSSMインベントリ作成 ポイント: データ一元化 : 複数インスタンスのインベントリデータを統合管理 標準形式 : JsonSerDe形式による構造化データ リージョン対応 : マルチリージョン環境での統合管理 依存関係 : Association作成後の実行を保証 インベントリ収集項目と活用方法 収集項目詳細 カテゴリ 収集内容 用途 Applications インストール済みソフトウェア一覧 ライセンス管理、セキュリティ監査 AWS Components AWS CLI、CloudWatch Agent等 AWS管理ツールの導入状況 Network Config ネットワーク設定情報 ネットワーク構成管理 Windows Updates 適用済み更新プログラム パッチ管理、脆弱性対応 Instance Details CPU、メモリ、OS情報 資産管理、容量計画 Services Windowsサービス状態 サービス管理、異常検知 Windows Roles Windowsサーバーロール 機能構成管理 Files 指定パスのファイル情報 セキュリティ監査、変更管理 Registry Windowsレジストリ値 システム設定管理 注意点 Association制限 : インスタンス単位で1つのInventory Associationのみ設定可能です   今回実装したコンストラクトファイルまとめ import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import * as ssm from 'aws-cdk-lib/aws-ssm'; import * as s3 from 'aws-cdk-lib/aws-s3'; import * as iam from 'aws-cdk-lib/aws-iam'; export interface SsmInventoryConstructProps { } export class SsmInventoryConstruct extends Construct { constructor(scope: Construct, id: string, props?: SsmInventoryConstructProps) { super(scope, id); //=========================================== // ssmインベントリ用のS3バケット作成 //=========================================== const ssmInventoryBucket = new s3.Bucket(this, 'SsmInventoryBucket', { bucketName: `s3b-ssm-inventory-bucket`, // バケット名 blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, // パブリックアクセスをすべてブロック encryption: s3.BucketEncryption.S3_MANAGED, // 暗号化タイプ:SSE-S3 autoDeleteObjects: true, // バケット削除時にオブジェクトも削除 デプロイ成功後にfalseに設定 enforceSSL: true, // SSL/TLS暗号化を強制 lifecycleRules: [ // ライフサイクルルール作成 { id: 'Expiration Rule 12 Months', // ライフサイクルルール名 expiration: cdk.Duration.days(366), // 1年間保持 } ], removalPolicy: cdk.RemovalPolicy.DESTROY, // スタック削除時にバケットも削除 デプロイ成功後にRETAINに変更 }); // バケットポリシー追加 ssmInventoryBucket.addToResourcePolicy(new iam.PolicyStatement({ // バケットポリシー追加 sid: 'AWSSSMInventoryWrite', // ステートメントID effect: iam.Effect.ALLOW, // 許可 actions: [ // 許可するアクション 's3:PutObject' // オブジェクトの配置を許可 ], resources: [ // 対象リソース `${ssmInventoryBucket.bucketArn}/AWSLogs/${cdk.Stack.of(this).account}/SSM/*`, // SSMログ用パス ssmInventoryBucket.bucketArn, // バケット自体 ], principals: [new iam.ServicePrincipal('ssm.amazonaws.com')], // SSMサービス conditions: { // 条件 StringEquals: { // 文字列完全一致 's3:x-amz-acl': 'bucket-owner-full-control', // ACL制御 'aws:SourceAccount': cdk.Stack.of(this).account // 送信元アカウント制限 } } })); //=========================================== // SSMインベントリ作成 //=========================================== const inventoryAssociation = new ssm.CfnAssociation(this, 'InventoryAssociation', { name: 'AWS-GatherSoftwareInventory', // 実行するSSMドキュメント名 associationName: 'ssm-inventory', // インベントリ名 targets: [{ // ターゲット key: 'InstanceIds', // 対象キー values: ['*'] // 対象値 }], parameters: { 'applications': ['Enabled'], // アプリケーション情報を収集 'awsComponents': ['Enabled'], // AWSコンポーネント情報を収集 'networkConfig': ['Enabled'], // ネットワーク設定情報を収集 'windowsUpdates': ['Enabled'], // Windowsアップデート情報を収集 (Windowsのみ) 'instanceDetailedInformation': ['Enabled'], // インスタンスの詳細情報を収集 'services': ['Enabled'], // サービス設定を収集 (Windowsのみ) 'windowsRoles': ['Enabled'], // Windowsロール設定を収集 (Windowsのみ) 'customInventory': ['Enabled'], // カスタムインベントリデータを収集 'billingInfo': ['Enabled'], // ライセンス含有アプリケーションの課金情報を収集 'files': ['[{"Path":"C:\\Program Files","Pattern":["*.exe"],"Recursive":true}]'], // ファイルを収集 'windowsRegistry': ['[{"Path":"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion","ValueNames":["ProductName"],"Recursive":false}]'], // Windowsレジストリデータを収集 }, scheduleExpression: 'rate(30 minutes)', // インベントリの収集頻度:30分ごと outputLocation: { // 実行結果出力先指定 s3Location: { outputS3BucketName: ssmInventoryBucket.bucketName, // インベントリ用のバケットに出力 outputS3KeyPrefix: `AWSLogs/${cdk.Stack.of(this).account}/SSM/Logs` // ディレクトリを作成 } } }) //resourceデータの同期設定 const resourceDataSync = new ssm.CfnResourceDataSync(this, 'ResourceDataSync', { // リソースデータの同期 syncName: 'resource-data-sync', // 同期名 s3Destination:{ bucketName: ssmInventoryBucket.bucketName, // バケット名 bucketPrefix: `AWSLogs/${cdk.Stack.of(this).account}/SSM/`, // バケットプレフィックス名 bucketRegion: cdk.Stack.of(this).region, // バケットのリージョン:東京リージョン syncFormat: 'JsonSerDe' // 同期形式:JSON } }); } }   まとめ 今回は、AWS Systems Manager Inventoryを活用した包括的なインベントリ管理システムをAWS CDKで実装しました。 皆さんのお役に立てば幸いです。
アバター
こんにちは、広野です。 2025 年 6 月に Amazon Cognito マネージドログインに AWS WAF の Web ACL をアタッチすることができるようになりました。   https://aws.amazon.com/jp/about-aws/whats-new/2025/06/amazon-cognito-aws-waf-managed-login/   何ら真新しいことではないのですが、気を付けた方がよい点があるので書いておきます。   公式ドキュメント 以下に公式ドキュメントがあります。   Associate an AWS WAF web ACL with a user pool - Amazon Cognito You can associate an AWS WAF web ACL with an Amazon Cognito user pool. A web ACL can block and log unwanted HTTPS reques... docs.aws.amazon.com   アタッチした AWS WAF Web ACL によるチェック対象は以下になります。 Managed login and the classic hosted UI Public API operations つまり、UI と API なんですが。さらっと書かれすぎているので、以降、別ブログ記事の図を引用して説明します。   どこがチェック対象なのか 図に示すと、 以下の赤丸の 2 箇所 がチェック対象になります。   code-server を nginx で HTTPS 化して Amazon Cognito で MFA 認証をさせる - アーキクチャ編 code-server を HTTPS 公開して MFA 認証を付ける構成を試してみました。本記事ではアーキテクチャを紹介します。 blog.usize-tech.com 2025.09.16   もう少し概念レベルで Amazon Cognito ユーザープールを機能分割すると、以下のように表現できます。 Amazon Cognito のマネージドログイン UI と、API がチェック対象になるのですが、それぞれのソースが異なります。   ソース IP アドレス制限をかけるときの注意 このため、Amazon Cognito マネージドログインを使用する環境でソース IP アドレス制限をかけるときには注意事項があります。 ソースは複数箇所あると考えた方がよいです。上記のケースでは、ユーザーデバイスと Amazon EC2 インスタンスの IP アドレスを 両方 許可するようにしてあげないと、認証フローが通りません。   おまけ AWS CloudFormation テンプレート AWS Cognito に AWS WAF をアタッチする AWS CloudFormation テンプレートを参考までに貼り付けます。 今回検証したのは特定のソース IP アドレス (サブネット) を許可する設定です。 アプリケーションクライアントの設定は省略しています。Amazon Cognito ユーザープールと、AWS WAF およびそのログ保存に絞っています。登場する IP アドレスは架空のものです。 AWSTemplateFormatVersion: 2010-09-09 Description: The CloudFormation template that creates a Cognito user pool with Managed Login. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SystemName: Type: String Description: System name. use lower case only. (e.g. example) Default: example MaxLength: 10 MinLength: 1 SubName: Type: String Description: System sub name. use lower case only. (e.g. prod or dev) Default: dev MaxLength: 10 MinLength: 1 SesId: Type: String Description: Amazon SES ID for sending emails. (email addreess or domain) Default: xxxx.xxx MaxLength: 100 MinLength: 5 SesConfigurationSet: Type: String Description: Amazon SES configuration set for sending emails. Default: xxxxxxxxxxxxxxxx MaxLength: 100 MinLength: 5 CognitoReplyTo: Type: String Description: Cognito Reply-to email address. (e.g. xxx@xxx.xxx) Default: xxxxx@xxx.xxx MaxLength: 100 MinLength: 5 CognitoEmailFrom: Type: String Description: Cognito e-mail from address. (e.g. xxx@xxx.xxx) Default: xxxxx@xxx.xxx MaxLength: 100 MinLength: 5 LogRetentionDays: Type: Number Description: The retention period (days) for AWS WAF logs. Enter an integer between 35 to 540. Default: 365 MaxValue: 540 MinValue: 35 SourceIpv4RangeList: Type: CommaDelimitedList Description: The comma delimited list of allowed source IPv4 address range (CIDR) except /0 to access this web site. (e.g. xxx.xxx.xxx.xxx/xx,yyy.yyy.yyy.yyy/yy) Default: "8.8.8.8/32,8.8.4.4/32" Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: "General Configuration" Parameters: - SystemName - SubName - Label: default: "Email Configuration" Parameters: - SesId - SesConfigurationSet - CognitoReplyTo - CognitoEmailFrom - Label: default: "Security Configuration" Parameters: - LogRetentionDays - SourceIpv4RangeList Resources: # ------------------------------------------------------------# # Cognito # ------------------------------------------------------------# UserPool: Type: AWS::Cognito::UserPool Properties: UserPoolName: !Sub ${SystemName}-${SubName} MfaConfiguration: "OFF" Policies: PasswordPolicy: MinimumLength: 8 RequireUppercase: true RequireLowercase: true RequireNumbers: true RequireSymbols: false TemporaryPasswordValidityDays: 180 AccountRecoverySetting: RecoveryMechanisms: - Name: verified_email Priority: 1 AdminCreateUserConfig: AllowAdminCreateUserOnly: true AutoVerifiedAttributes: - email DeviceConfiguration: ChallengeRequiredOnNewDevice: false DeviceOnlyRememberedOnUserPrompt: false EmailConfiguration: ConfigurationSet: !Ref SesConfigurationSet EmailSendingAccount: DEVELOPER From: !Sub "${SystemName}-${SubName} admin <${CognitoEmailFrom}>" ReplyToEmailAddress: !Ref CognitoReplyTo SourceArn: !Sub arn:aws:ses:${AWS::Region}:${AWS::AccountId}:identity/${SesId} EmailVerificationMessage: !Sub "${SystemName}-${SubName} Verification code: {####}" EmailVerificationSubject: !Sub "${SystemName}-${SubName} Verification code" UsernameConfiguration: CaseSensitive: false UserPoolAddOns: AdvancedSecurityMode: "OFF" UserPoolTags: Cost: !Sub ${SystemName}-${SubName} UserPoolTier: ESSENTIALS UserPoolDomain: Type: AWS::Cognito::UserPoolDomain Properties: Domain: !Sub ${SystemName}-${SubName} ManagedLoginVersion: 2 UserPoolId: !Ref UserPool # ------------------------------------------------------------# # WAF Web Acl for Cognito # ------------------------------------------------------------# WebAclCognito: Type: AWS::WAFv2::WebACL Properties: Name: !Sub ${SystemName}-${SubName}-cognito Description: WAFv2 WebACL for Cognito Scope: REGIONAL DefaultAction: Block: {} Rules: - Name: !Sub ${SystemName}-${SubName}-cognito-IpWhiteList Action: Allow: {} Priority: 0 Statement: IPSetReferenceStatement: Arn: !GetAtt WAFv2Ipv4WhiteList.Arn VisibilityConfig: CloudWatchMetricsEnabled: true MetricName: !Sub ${SystemName}-${SubName}-cognito-IpWhiteList SampledRequestsEnabled: true VisibilityConfig: CloudWatchMetricsEnabled: true MetricName: !Sub ${SystemName}-${SubName}-cognito SampledRequestsEnabled: true Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} DependsOn: - WAFv2Ipv4WhiteList WAFv2Ipv4WhiteList: Type: AWS::WAFv2::IPSet Properties: Name: !Sub ${SystemName}-${SubName}-Ipv4WhiteList Description: WAF v2 IPv4 white list for the IP-based restricted access IPAddressVersion: IPV4 Addresses: !Ref SourceIpv4RangeList Scope: REGIONAL Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} WebACLAssociationCognito: Type: AWS::WAFv2::WebACLAssociation Properties: ResourceArn: !GetAtt UserPool.Arn WebACLArn: !GetAtt WebAclCognito.Arn DependsOn: - UserPool - WebAclCognito WebAclLoggingConfigurationCognito: Type: AWS::WAFv2::LoggingConfiguration Properties: ResourceArn: !GetAtt WebAclCognito.Arn LogDestinationConfigs: - !GetAtt S3BucketWafLogs.Arn LoggingFilter: DefaultBehavior: KEEP Filters: - Behavior: KEEP Conditions: - ActionCondition: Action: BLOCK Requirement: MEETS_ANY DependsOn: - S3BucketWafLogs - WebAclCognito # ------------------------------------------------------------# # S3 # ------------------------------------------------------------# S3BucketWafLogs: Type: AWS::S3::Bucket Properties: BucketName: !Sub aws-waf-logs-${SystemName}-${SubName}-cognito LifecycleConfiguration: Rules: - Id: AutoDelete Status: Enabled ExpirationInDays: !Ref LogRetentionDays OwnershipControls: Rules: - ObjectOwnership: BucketOwnerEnforced PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} # ------------------------------------------------------------# # Output Parameters # ------------------------------------------------------------# Outputs: # Cognito CognitoUserPoolId: Value: !Ref UserPool Export: Name: !Sub CognitoUserPoolId-${SystemName}-${SubName} CognitoUserPoolArn: Value: !GetAtt UserPool.Arn Export: Name: !Sub CognitoUserPoolArn-${SystemName}-${SubName} CognitoUserPoolProviderName: Value: !GetAtt UserPool.ProviderName Export: Name: !Sub CognitoUserPoolProviderName-${SystemName}-${SubName} CognitoUserPoolProviderUrl: Value: !GetAtt UserPool.ProviderURL Export: Name: !Sub CognitoUserPoolProviderUrl-${SystemName}-${SubName} まとめ いかがでしたでしょうか。 今回は小ネタでした。Amazon Cognito 周りの通信パスをご存知の方にとっては当たり前と思いましたが、意外と知られていないかもな?と思ったので書きました。 本記事が皆様のお役に立てれば幸いです。
アバター
高い柔軟性とコストパフォーマンスで世界中の企業に導入されているオープンソース統合監視ソフトウェアのZabbix。 そのZabbix Japanが主催する公式ウェビナーに、弊社トップエンジニアの 中野祐輔氏 が登壇する運びとなりました!   本ウェビナーは アプライアンス初期設定とZabbixの基本について と題して、弊社がこれまで培ってきたZabbix活用のノウハウを凝縮し、これからZabbixを始める皆様を力強くサポートする内容となっております!   こんな方におすすめ Zabbixアプライアンスの導入を検討している方 Zabbixという名前は知っているが、具体的に何ができて、どう便利なのかを知りたい方 過去にZabbixを試そうとしたが、監視設定時に挫折してしまった経験がある方 数々の難易度の高いZabbix案件を成功に導いてきた弊社のトップアーキテクトである中野祐輔氏の解説を直接聞いてみたい方   本ウェビナーで得られること 本ウェビナーにご参加いただくことで、単なる知識のインプットに留まらず、「明日から実際にZabbixを使ってみよう」と思える具体的なスキルを得ることができます。 Zabbixを扱う上で必須となる「ホスト」「アイテム」「トリガー」といった基本概念を、実例を交えて体系的に理解できます。 サーバーのCPU使用率やディスク空き容量監視など、すぐに現場で役立つ実践的な監視設定の手順を、デモンストレーションを通じて習得できます。 「Zabbixアプライアンス」の利用法を学び、監視を始めるまでのハードルを劇的に下げることができます。   ウェビナー詳細 項目 内容 タイトル アプライアンス初期設定とZabbixの基本について 開催日時 2025年10月21日  14:00-14:30 形式 Webex 登壇者 中野祐輔 参加費 無料   申し込み方法 こちらのサイトから参加登録をお願いします。 Zabbix Webセミナー - Zabbix Zabbixでは、Zabbix監視ソリューションに関する無料のWebセミナーを開催しています。Webセミナーでは、Zabbix監視ソリューションの機能、選ばれる理由、動作環境、最新版Zabbixの新機能、Zabbix社によって提供されている... www.zabbix.com   さいごに このわずか30分のウェビナーが、皆様の監視業務を大きく変えるきっかけになるかもしれません。 ウェビナーの最後には質疑応答の時間も設けておりますので、日頃から抱えている監視に関する疑問や不安を、弊社エンジニアに直接ぶつける絶好の機会です。 ご興味をお持ちいただけましたら、ぜひお申し込みください!
アバター
こんにちは。SCSKの津田です。 システムの計画的なメンテナンスやトラブル対応時に、サーバの停止や再起動を行うことは少なくないですよね。 LifeKeeperを導入する環境では、こうした場面で「稼働系サーバを停止・再起動した場合にフェイルオーバが発生するのか?」というご質問を利用者の方からよくいただきます。 結論から申し上げますと、サーバ停止時の挙動は、LifeKeeperの設定 (シャットダウンストラテジー) によって選択することが可能です。 本記事では、LifeKeeper導入環境におけるサーバ停止時の動作についてご説明します。   シャットダウンストラテジーについて LifeKeeperでは、「シャットダウンストラテジー(Shutdown Strategy)」の設定によって、通常のサーバ停止時の動作を選択できます。 シャットダウンストラテジーとは、クラスタ内の稼働系サーバが通常のサーバ停止をする際に、待機系サーバへリソースをフェイルオーバするかどうかを制御する LifeKeeper のオプションです。 以下の2つから選択ができます(デフォルトは “Do not Switchover Resources” )。 シャットダウンストラテジー オプション 動作内容 Do not Switchover Resources(デフォルト) 通常のサーバ停止時、待機系サーバでリソースは起動しない(フェイルオーバしない)。 Switchover Resources 通常のサーバ停止時、待機系サーバでリソースが起動する(フェイルオーバする)。 ※ここでの「通常のサーバ停止」とは、サーバ障害時を除いた計画的・意図的なサーバ停止を指します。  LifeKeeperが「通常のサーバ停止」とみなす操作例:  ・Linux:shutdown、rebootコマンド  ・Windows:Windowsメニューからのシャットダウン、再起動  ・クラウド環境:コンソールからのサーバ停止、再起動   通常のサーバ停止と障害によるサーバ停止の判別の仕組み ちなみに、LifeKeeperでは通常のサーバ停止と障害によるサーバ停止を、 バックアップサーバでの「nofailoverフラグ」の有無 によって判別しています。 ・「nofailoverフラグ」あり :通常のサーバ停止と判定し、フェイルオーバしない ・「nofailoverフラグ」なし :障害によるサーバ停止と判定し、フェイルオーバ処理を開始 “Do not Switchover Resources”を設定している場合、 通常のサーバ停止時は、コミュニケーションパスを通じて、バックアップサーバに「nofailoverフラグ」が作成されるため、フェイルオーバは発生しません。 一方、障害によるサーバ停止の場合は「nofailoverフラグ」が作成されないため、フェイルオーバが実施されます。 “Switchover Resources”を設定している場合、 通常のサーバ停止時に「nofailoverフラグ」は作成されません。 そのため、通常のサーバ停止か障害によるサーバ停止かに関わらず、必ずフェイルオーバが発生します。 また、稼働系サーバのリソース状態にかかわらず(一部リソース停止、もしくは全停止状態でも)、待機系サーバ上でリソースが全て起動します。   シャットダウンストラテジー設定変更方法 シャットダウンストラテジーは、 各サーバごとに 設定が可能です。 ①LifeKeeper GUIを開き、[Edit] メニュー で [Server] ⇒ [Properties] をクリックします。   ②[Server Properties] ダイアログが表示されるため、    [General] タブ で、[Server]、 [Shutdown Strategy] の値をプルダウンから選択し、[Apply]をクリックします。   ※上記画像はLinuxの画面イメージですが、Windowsでも同様の手順で設定できます。 ※シャットダウンストラテジーはサーバごとに個別設定が可能です。   どちらを選択すべきか? ・ Do not Switchover Resources    メンテナンスやスケジュールなどによる、意図的なサーバ停止時にリソースの切り替えが不要な場合に適しています。 ・ Switchover Resources    メンテナンス等によるサーバの通常停止時にも、自動でフェイルオーバさせることで必ず待機系サーバでサービス提供を継続したい場合    に適しています。( ※”Do not Switchover Resources” を設定している場合もサーバ停止前に手動で待機系にスイッチオーバすること    で、サービス提供は継続可能です。) 当社で構築してきたシステムでは” Do not Switchover Resources ”を設定するケースが多いです。 運用ポリシーやメンテナンス計画に応じて、適切な設定を選択しましょう。   注意事項 シャットダウンストラテジーの設定には以下の点にご注意ください。 ・ シャットダウンストラテジーが有効に機能するには、正常なシャットダウン時に LifeKeeper のプロセスが起動している必要があり     ます。 ※再起動時は、LifeKeeper のプロセスも自動で起動されます。 ・ LifeKeeper for Windows環境において、DataKeeperのリソースを作成し、シャットダウンストラテジーで“Switchover Resources”を     設定している場合、通常のサーバ停止時にリソースの切り替えに失敗する可能性があります。    (参考: https://lkdkuserportal.sios.jp/hc/ja/articles/360037693491 )   まとめ 今回はLifeKeeperのシャットダウンストラテジーの設定についてご紹介しましたが、いかがでしたでしょうか? 本記事でLifeKeeperでは 通常のサーバ停止時にリソースの切り替えを行うかどうかを選択できるということをご理解いただけましたら幸いです。 シャットダウンストラテジー オプション 動作内容 適したケース Do not Switchover Resources 通常のサーバ停止では、フェイルオーバしない。 (nofailoverフラグがバックサーバに作成されることにより、フェイルオーバが抑止される。) メンテナンスやスケジュール等による意図的なサーバ停止時にリソースの切り替えが不要な場合 Switchover Resources 通常のサーバ停止でも、フェイルオーバする。 (nofailoverフラグがバックサーバに作成されないため、フェイルオーバする。) サーバ障害時だけでなく、通常のサーバ停止時にも自動でリソースの切り替えを行い、サービスを継続させたい場合   詳しい内容をお知りになりたいかたは、以下のバナーからSCSK Lifekeeper公式サイトまで
アバター
当記事は、前回の記事「Ansibleを使用してNW機器設定を自動化する(PaloAlto-アドレスグループ編①)」からの改善となります。 設定情報がベタ書きで使い勝手が悪い点 を 設定情報をまとめてINPUT(JSON)できる使い勝手の良い仕組みとしました!! これにより、Anibleとの連携ができるようになりますので、ご参考になれば幸いです。 ※前回記事: Ansibleを使用してNW機器設定を自動化する(PaloAlto-アドレスグループ編①) – TechHarmony 当記事は、 日常の運用業務(NW機器設定)の自動化 により、 運用コストの削減 および 運用品質の向上  を目標に 「Ansible」 を使用し、様々なNW機器設定を自動化してみようと 試みた記事です。 Ansibleは、OSS版(AWX)+OSS版(Ansible)を使用しております。   PaloAltoの「Objects-アドレスグループ」の登録/変更/削除を実施してみた 事前設定 Templateを作成し、インベントリーと認証情報を設定する。 インベントリー:対象機器(ホスト)の接続先を設定。 ※ホストには以下変数で接続先IPを指定 ansible_host: xxx.xxx.xxx.xxx 認証情報:対象機器へのログイン情報(ユーザ名/パスワード)を設定。 ユーザ名は  変数:ansible_user   に保持される パスワードは 変数:ansible_password に保持される   事前設定2:設定情報をまとめてINPUT(JSON)できるように、「Survey」を活用 テンプレートが読み込むことができる変数(Survey)を設定する。※今回は、各設定のデフォルト値に値を設定する。 実際の値(JSON) ・input_addressgroup1: {"name":"test_addressgroup001","static_value":"test_address001"} ・input_addressgroup2: {"name":"test_addressgroup001","static_value":"test_address002"} ・input_addressgroup3: {"name":"test_addressgroup001","static_value":["test_address001","test_address003"]} ・input_addressgroup4: {"name":"test_addressgroup001","static_value":"test_address003"} ・input_addressgroup5: {"name":"test_addressgroup001","static_value":"test_address003"}   Playbook作成(YAML) 使用モジュール paloaltonetworks.panos.panos_address_group  を使用。 ※参考ページ: Ansible Galaxy galaxy.ansible.com   接続情報(provider)の設定 providerには、ip_address/username/password の指定が必要。 vars: provider:   ip_address: '{{ ansible_host }}'   ← インベントリーのホストで設定   username: '{{ ansible_user }}'    ← 認証情報で設定   password: '{{ ansible_password }}'  ← 認証情報で設定   変数(Survey)の値取得 vars で 各変数(Survey)の値取得。 ※各変数(Survey)の値は、構造化データのように見えて「文字列」なので、ディクショナリ(構造化データ)として正しく扱えるように、from_json フィルターを使用すること!!           vars: wk_input1: '{{ input_addressgroup1 | from_json}}' wk_input2: '{{ input_addressgroup2 | from_json}}' wk_input3: '{{ input_addressgroup3 | from_json}}' wk_input4: '{{ input_addressgroup4 | from_json}} wk_input5: '{{ input_addressgroup5 | from_json}}   Objects-アドレスグループの登録 ★ 変数(Survey)の値をそのまま使用した場合 …エラーとなる 接続情報と アドレスグループとアドレスの関連付け( Survey:input_addressgroup1 )を指定して登録( state: ‘present’ )を行う。 - name: Present AddressGroup1_input_addressgroup1 paloaltonetworks.panos.panos_address_group: provider: '{{ provider }}' name: '{{ input_addressgroup1.name }}'   ← アドレスグループ static_value: '{{ input_addressgroup1.static_value }}'  ← アドレスグループに関連付けするアドレス state: 'present' register: wk_result 実行結果: 構造化データではないので、オブジェクトに項目が無いという エラー となる。 ※Ansibleの実行結果(diff)を抜粋 "msg": "The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'name'. ...   Objects-アドレスグループの登録 ※アドレスグループの新規作成の場合 接続情報と アドレスグループとアドレスの関連付け( ディクショナリ: w k_input )を指定して登録( state: ‘present’ )を行う。 - name: Present AddressGroup1_wk_input paloaltonetworks.panos.panos_address_group: provider: '{{ provider }}' name: '{{ wk_input1.name }}'   ← アドレスグループ static_value: '{{ wk_input1.static_value }}'  ← アドレスグループに関連付けするアドレス state: 'present' register: wk_result 実行結果:対象のアドレスグループが登録された。 ※Ansibleの実行結果(diff)を抜粋 "before": "", "after" : "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_addressgroup001\">\n\t<static>\n\t\t<member>test_address001</member>\n\t</static>\n</entry>\n"   Objects-アドレスグループの登録 ※アドレスグループが既に存在する場合 接続情報と アドレスグループとアドレスの関連付け を指定して登録( state: ‘present’ )を行う。  ※アドレスグループが既に存在する場合は、既存設定の置き換えとなる(state: ‘replaced’と同様)   - name: Present AddressGroup1 paloaltonetworks.panos.panos_address_group: provider: '{{ provider }}' name: '{{ wk_input2.name }}'   ← アドレスグループ static_value: '{{ wk_input2.static_value }}'  ← アドレスグループに関連付けするアドレス state: 'present' register: wk_result 実行結果:既存のアドレスグループが 上書き更新 された。 ※Ansibleの実行結果(diff)を抜粋 "before": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_addressgroup001\">\n\t<static>\n\t\t<member>test_address001</member>\n\t</static>\n</entry>\n", "after" : "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_addressgroup001\">\n\t<static>\n\t\t<member>test_address002</member>\n\t</static>\n</entry>\n"   Objects-アドレスグループの変更 ※登録のつづき(新たなアドレスを関連付けする) 接続情報と アドレスグループとアドレスの関連付け を指定して、アドレスグループの変更( state: ‘replaced’ )を行う。  ※replacedの場合は、既存設定の置き換えとなる (注意:関連付け後の状態を指定すること!!) - name: Replaced AddressGroup1 paloaltonetworks.panos.panos_address_group: provider: '{{ provider }}' name: '{{ wk_input3.name }}' static_value: '{{ wk_input3.static_value }}' ← 関連付け後の状態を指定すること!! state: 'replaced' register: wk_result 実行結果:既存のアドレスグループが 上書き更新 された。 ※Ansibleの実行結果(diff)を抜粋 "before": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_addressgroup001\">\n\t<static>\n\t\t<member>test_address002</member>\n\t</static>\n</entry>\n", "after" : "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_addressgroup001\">\n\t<static>\n\t\t<member>test_address001</member>\n\t\t<member>test_address003</member>\n\t</static>\n</entry>\n"   接続情報と アドレスグループとアドレスの関連付け を指定して、アドレスグループの変更( state: ‘merged’ )を行う。  ※mergedの場合は、既存設定を維持した更新(Append)となる。 その為、特定アドレスの関連付け解除はできない (注意: アドレスの関連付け解除をしたい場合は state: ‘replaced’ を使用する必要がある!!)   - name: Merged AddressGroup1 paloaltonetworks.panos.panos_address_group: provider: '{{ provider }}' name: '{{ wk_input4.name }}' static_value: '{{ wk_input4.static_value }}' ← 関連付けしたいアドレスのみ指定すること!! state: 'merged' register: wk_result 実行結果:既存のアドレスグループが 更新(Append) された。 既存設定が維持されていることを確認 。 ※Ansibleの実行結果(diff)を抜粋 "before": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_addressgroup001\">\n\t<static>\n\t\t<member>test_address002</member>\n\t</static>\n</entry>\n", "after" : "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_addressgroup001\">\n\t<static>\n\t\t<member>test_address002</member>\n\t\t<member>test_address003</member>\n\t</static>\n</entry>\n" Objects-アドレスグループの情報収集 ※変更のつづき 接続情報と アドレスグループ を指定して情報収集( state: ‘gathered’ )を行う。 - name: gathered AddressGroup1 paloaltonetworks.panos.panos_address_group: provider: '{{ provider }}' name: '{{ wk_input1.name }}' state: 'gathered' register: wk_result 実行結果:対象アドレスグループの情報が取得できた。 ※Ansibleの実行結果(gathered_xml)を抜粋 "gathered_xml": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_addressgroup001\">\n\t<static>\n\t\t<member>test_address001</member>\n\t\t<member>test_address003</member>\n\t</static>\n</entry>\n",   Objects-アドレスグループの削除 ※変更のつづき 接続情報と アドレスグループと関連付いているアドレス を指定して、削除(state: ‘absent’)を行う。 ( 注意:関連付いているアドレスが削除されるのではなく、アドレスグループが削除される!!)   - name: Absent AddressGroup1 paloaltonetworks.panos.panos_address_group: provider: '{{ provider }}' name: '{{ wk_input5.name }}'   ← アドレスグループ ※アドレスグループが削除される static_value: '{{ wk_input5.static_value }}'  ← アドレスグループに関連付いているアドレス ※指定の必要なし state: 'absent' register: wk_result 実行結果:対象の アドレスグループ が削除された。 ※Ansibleの実行結果(diff)を抜粋 "before": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_addressgroup001\">\n\t<static>\n\t\t<member>test_address001</member>\n\t\t<member>test_address003</member>\n\t</static>\n</entry>\n", "after" : ""   最後に 今回、変数(Survey)を活用したことで、Ansibleに INPUT(JSON)を設定 できるようになりました。 設定情報がYAMLにベタ書きではなくなったので、使い勝手は増しましたが、 都度 変数(Survey)のデフォルト値に値を設定しての実行の為、まだまだ 使い勝手が悪い。。。              今後 外部からAnsibleの INPUT(JSON)に値を連携し実行させる仕組みを試みたいと思います。
アバター
こんにちは、SCSKの坂木です。 本記事では、 ファイルサーバーのデータを、Amazon FSx へ移行 するシナリオを想定し、 AWS DataSync を使った具体的な設定手順をスクリーンショットを交えながら、一つひとつ丁寧に解説していきます。   検証環境 実際のデータ移行では、オンプレミス環境からAWSへプライベート接続したり、セキュリティ要件でVPCが分離されていたりするケースが多くあります。 そこで本記事では、そうした本番環境に近いシナリオを再現するため、移行元と移行先の環境を別々のVPCに構築して手順を進めます。 構成の全体像は以下の図の通りです。 2つのVPC間はVPCピアリングで接続しています。各VPCに配置するリソースの役割は以下の通りです。 VPC ①:移行元環境 リソース 説明 EC2 移行対象の共有ファイルが格納されている、既存のファイルサーバー DataSyncエージェント EC2ファイルサーバーからデータを読み取り、AWS DataSyncサービスへ転送する役割を担うコンポーネント 今回はEC2インスタンスとしてデプロイする   VPC ②:移行先環境  リソース 説明 FSx 今回のデータの転送先となる、フルマネージドなファイルサーバー VPC エンドポイント DataSyncエージェントが、インターネットを経由せずにAWSのネットワーク内でDataSyncサービスと通信するためのプライベートな接続口   前提条件 本記事では、AWS DataSyncを使ったデータ転送の具体的な手順に焦点を当てて解説を進めます。 そのため、以下の環境がすでに構築済みであることを前提とします。 もし設定がまだの場合は、お手数ですが先に準備を完了させてから次のステップへお進みください。 1. VPCピアリングの設定 今回は移行元と移行先でVPCを分けているため、2つのVPC間が VPCピアリング によって接続され、相互にプライベートIPアドレスでの通信が可能な状態になっている必要があります。   2. 共有フォルダの作成 移行元となるEC2ファイルサーバー上に、移行対象のデータが含まれた共有フォルダが作成されていること。 この記事では、「Share_10.1.1.163」を共有するフォルダとして設定します。   3. FSxの作成 データの転送先となるFSxがデプロイされていること。 この記事ではFSxを作成したときにデフォルトで作成されるフォルダである「Share」をDataSyncの転送先フォルダとして設定します。   DataSync用のエンドポイント作成 DataSyncエージェントとDataSyncサービス間の通信が発生しますが、この通信をインターネット経由ではなく、AWSのプライベートネットワーク内で完結させることで、よりセキュアな通信経路を確保するため、VPCエンドポイントを作成します。 VPC -> エンドポイント -> エンドポイントを作成 からエンドポイントを作成します。 「サービス」の検索ボックスに datasync と入力し、表示されるサービス名を選択します。 リージョンが東京の場合、サービス名は com.amazonaws.ap-northeast-1.datasync となります。 設定を入力すると以下のようにVPCエンドポイントが作成されます。   DataSyncAgentのデプロイ先インスタンスの作成 今回はDataSyncAgentをEC2で作成します。 EC2 -> インスタンスを起動 からインスタンスを作成します。 EC2作成のAMI選択画面から、「aws-datasync」と入力すると、DataSyncAgent用のAMIが表示されるため、最新版のAMIを選択します。 DataSync エージェントを Amazon EC2 インスタンスにデプロイする場合、インスタンスのサイズは少なくとも 2xlarge である必要があるため、今回はm5.2xlargeを選択して作成します。詳細は こちら をご確認ください。 今回セキュリティグループは、VPC①と②のトラフィックを全て許可する設定としています。本番環境で設定する際には、 こちら を参考に必要なポートのみ開放いただければと思います。   DataSyncのアクティベーションキーの取得 作成したインスタンスにセッションマネージャーやSSHなどでログインすると、画像のようにアクティベーションキーの設定画面が表示されます。 ※ログインユーザはec2-userではなく、adminとなります。   アクティベーションキー取得のため、以下のように入力します。 質問項目 入力項目 Enter command 0: Get activation keyを入力 Enter AWS Region 利用しているリージョンを選択 今回は東京リージョンを利用しているため ap-northeast-1を入力 Select service endpoint type or exit 3: VPC Endpoints using AWS PrivateLinkを入力 Private IPv4 or IPv6 address of VPC endpoint 作成したエンドポイントのIPアドレスを入力   上記のように選択すると、「Activation key:XXXXXXXXXXXXXXXXXXX」と表示されます。 XXXXXXXXXXXXXXXXXXXの部分がアクティベーションキーとなりますので、この文字列をメモしておきます。   DataSyncエージェントの作成 DataSyncエージェントとは、データ転送元サーバと同じ環境で動作する仮想マシンであり、転送元のファイルサーバーに接続してデータを読み取り、AWSのDataSyncサービスに向けてデータを転送します。 DataSync -> エージェント -> エージェントの作成 からDataSyncエージェントを作成します。 下表のように設定値を入力します。 項番 項目 設定内容 1 ハイパーバイザー Amazon EC2を選択 2 エンドポイントタイプ AWS Privatelinkを使用したVPCエンドポイントを選択 3 VPCエンドポイント 「DataSync用のエンドポイント作成」で作成したエンドポイントを選択 4 サブネット DataSyncエージェントを作成するサブネットを選択 「DataSyncAgentのデプロイ先インスタンスの作成」で作成したEC2と同じサブネットを選択 5 セキュリティグループ DataSyncエージェントに紐づけるセキュリティグループを選択 EC2と同じセキュリティグループを選択 6 アクティベーションキー エージェントのアクティベーションキーを手動で入力するを選択 「DataSyncのアクティベーションキーの取得」で取得したアクティベーションキーを入力   項目を入力すると、画像のようにDataSyncエージェントが作成されます。   ロケーションの作成 続いてロケーションを作成します。 ロケーションとは、DataSyncがデータを転送する際の「送信元」と「送信先」を定義したものです。 オンプレミスのNFS/SMBサーバーや、AWSのS3バケット、EFS、FSxなどが指定できます。 送信元のロケーションと送信先のロケーションの2つを作成します。 DataSync -> ロケーション -> ロケーションを作成する からロケーションを作成します。 送信元ロケーションの作成 下表のように設定値を入力します。 項番 項目 設定内容 1 ロケーションタイプ 送信元のロケーションタイプを選択 今回はEC2の共有フォルダが送信元となるため、サーバーメッセージブロック(SMB)を選択 2 エージェント 「DataSyncエージェントの作成」で作成したDataSyncエージェントを選択 3 SMBサーバー 送信元のEC2のIPアドレスを入力 4 共有名 共有するフォルダ名を入力(選択するフォルダは共有フォルダに設定しておく) 5 認証タイプ NTLM認証を選択 6 ユーザー EC2の共有フォルダにアクセスできるユーザーを入力 今回はAdministratorを指定 7 パスワード 6で選択したユーザーのパスワードを入力 8 ドメイン 6で選択したユーザーの所属するドメインを入力   設定値を入力すると、画像のようにロケーション(送信元)が作成されます。   送信先ロケーション 下表のように設定値を入力します。 項番 項目 設定内容 1 ロケーションタイプ 送信元のロケーションタイプを選択 今回はFSxが送信先となるため、FSxを指定 2 FSxファイルシステム 送信するFSxのファイルシステム名を選択 今回は事前に作成しておいたFSxのファイルシステム名を選択 3 共有名 FSxの送信先フォルダを入力(選択するフォルダは共有フォルダに設定しておく) 4 セキュリティグループ FSxにアタッチされているセキュリティグループへ通信可能な設定されているセキュリティグループを選択 5 ユーザー FSxの共有フォルダにアクセスできるユーザーを入力 今回はAdministratorを指定 6 パスワード 5で選択したユーザーのパスワードを入力 7 ドメイン 5で選択したユーザーの所属するドメインを入力     設定値を入力すると、画像のようにロケーション(送信先)が作成されます。   タスクの作成 タスクとは、「どのロケーションからどのロケーションへ」データを転送するかを定義する実行ジョブです。 転送スケジュール、帯域幅制限、フィルタリング等の詳細なオプションを設定し、このタスクを実行してデータ同期を開始します。 DataSync -> タスク -> タスクを作成 からタスクを作成します。 下表のように設定値を入力します。 項番 項目 設定内容 1 ロケーション 送信元ロケーションで作成したロケーションを選択 2 ロケーション 送信先ロケーションで作成したロケーションを選択 3 設定を構成する オプションを設定する項目で、データを転送するタイミングやログ出力など設定可能 今回はデフォルトで設定     設定値を入力すると、画像のようにタスクが作成されます。   ファイルの転送確認 作成したタスクから、ファイル転送を実施してみます。 ファイル転送が成功すると、実行ステータスが「成功」と表示されます。   実際にファイルが転送されているか確認します。 FSxのshare配下を確認すると、送信元インスタンスで作成したフォルダとファイルが転送されていることを確認できました。   まとめ 本記事では、 AWS DataSyncを用いてEC2共有フォルダからFSxへデータを移行する手順を解説 しました。 DataSyncは、 DataSyncエージェント 、 ロケーション 、 タスク の簡単な設定だけで、高速かつ安全なデータ転送が可能です。 本記事では紹介していませんが、差分同期やスケジュール機能も備え、移行時のダウンタイムを最小限に抑えられる点も魅力です。 オンプレミスやEC2からのファイルサーバー移行時においては、本記事を参考にDataSyncを利用してみてください!   最後に著者の他のAWS記事を紹介させてください。 【Amazon Bedrock】ナレッジベースを用いた社内資料管理ーめざせ生産性向上ー 社内資料の管理、効率的ですか?様々な形式の文書が散在し、必要な情報を探すのに時間を取られていませんか? ファイルサーバーの奥底に埋もれどこにあるか分からない、バージョン管理が混乱する、などといった課題を抱えていませんか?これらの非効率は、業務の生産性低下に直結します。 今こそ、社内資料の一元管理体制を見直しましょう!ということで、AWS Bedrockのナレッジベースを用いた資料の一括管理およびその検索方法をご紹介します! blog.usize-tech.com 2025.02.14
アバター
こんにちは、SCSK松岡です⛄ Snowflake Intelligenceは、生成AIを利用して自然言語によるデータ検索や要約を可能にしてくれる機能です。 本記事では、その利用を開始するために必要な設定を、アカウント管理者の視点から紹介します。   Snowflake Intelligence   Snowflake IntelligenceとData Science Agent、エンタープライズAI/MLにおける 次世代データエージェントの可能性 ※本報道資料は米国スノーフレイク社が6月3日に発表した内容の抄訳です。 www.snowflake.com Snowflake Intelligenceは先日のSnowflake Summit25で紹介された新機能で、2025年8月からプレビュー機能で利用できるようになりました。 この機能を活用することで、ユーザーはAIとの自然言語でのやり取りを通してSnowflake上のデータにアクセスし、データ活用を行うことができます。 データの検索や要約、可視化、さらにはアナリストのような分析も自動で行ってくれるため、高度なスキルを持たなくても、直感的にデータとの対話が可能になる機能として注目されています。 組織におけるデータ活用の推進において、様々なスキルレベルのユーザーにどう広く使ってもらうか、は課題になりがちな部分かと思います。Snowflake Intelligenceはその一つの解決策になり得る存在として期待しています。   【現地レポート:Day2】Snowflake Summit 25 (Platform Keynoteまとめ) サンフランシスコで開催されている、Snowflake Summit 25速報記事の第二弾です。 今回は、6/3のPlatform Keynoteで紹介された最新のサービスアップデート情報を中心にお届けしたいと思います。 blog.usize-tech.com 2025.06.04   Snowflake Intelligence利用に必要なアカウント設定   Overview of Snowflake Intelligence | Snowflake Documentation docs.snowflake.com Snowflake Intelligenceを利用するためには、大きく4つのSTEPで設定が必要です。 専用のDB・スキーマを作成 生成AIモデルの利用許可 エージェントを作成 エージェントをカスタム 1. 専用のDB・スキーマを作成 --snowflake_intelligence用のDB・スキーマを作成してPUBLICに権限付与 CREATE DATABASE IF NOT EXISTS snowflake_intelligence; GRANT USAGE ON DATABASE snowflake_intelligence TO ROLE PUBLIC; CREATE SCHEMA IF NOT EXISTS snowflake_intelligence.agents; GRANT USAGE ON SCHEMA snowflake_intelligence.agents TO ROLE PUBLIC; まず、エージェントの作成場所となるデータベース、スキーマを作成する必要があります。 DB名は「snowflake_intelligence」スキーマ名は「agents」である必要がありました(※2025/9時点) また、PUBLICにUSAGE権限も付与する必要がありました --エージェントの作成権限を付与 GRANT CREATE AGENT ON SCHEMA snowflake_intelligence.agents TO ROLE [エージェント作成者のロール]; Snowflake Intelligenceの実行単位である「エージェント」は、スキーマ単位のオブジェクトです。 作成したスキーマ上にエージェントを作成するための権限を、作業用のロールに付与します。 2. 生成AIモデルの利用許可 エージェントは、裏側で生成AIモデルを呼び出しながら動作します。そのため、事前にSnowflakeアカウント上で生成AIモデルを利用できるように設定する必要があります。 /* ①Cortex LLM を許可リストに追加 */ ALTER ACCOUNT SET CORTEX_MODELS_ALLOWLIST = 'All'; /* ②AWS_USリージョンにクロスリージョン推論を許可 */ ALTER ACCOUNT SET CORTEX_ENABLED_CROSS_REGION = 'AWS_US'; /* ③モデルの追加設定を反映 */ CALL SNOWFLAKE.MODELS.CORTEX_BASE_MODELS_REFRESH(); Snowflakeアカウントに対し、生成AIモデルへのアクセスを許可します。(①) 例では、すべて(ALL)のモデルへのアクセスを許可しています。 https://docs.snowflake.com/en/user-guide/snowflake-cortex/snowflake-intelligence Snowflake Intelligenceに対応しているモデルは以下の通りです(※2025/9時点) Claude 4.0 Claude 3.7 Claude 3.5 GPT 4.1 次に、クロスリージョン推論の設定を行います。(②) Snowflake Intelligenceに対応しているモデルは日本のAPJリージョンでは直接対応していないため、異なるリージョンを経由して推論を行うようにする必要があります。 リージョンごとに対応している生成AIモデル Snowflake Cortex AISQL (including LLM functions) | Snowflake Documentation docs.snowflake.com モデルの追加設定を行った後は、反映するためにリフレッシュが必要です。(③) 3. エージェントを作成 エージェントの作成はSnowsightから行うことができます。 Snowsightで、1.でCREATE権限を付与したロールを指定し、[AIとML>エージェント]メニューに移動してエージェントの作成を行います。 エージェントを作成すると、[AIとML>Snowflakeインテリジェンス]メニューのチャット画面で作成したエージェントを選択できるようになります。これで、生成AIモデルとの会話が行えるようになります! 作成時以外のロールにエージェントの利用を許可する場合は、作成したエージェントの編集画面から、[アクセス]メニューを選択してロールの追加を行います。 Snowflake Intelligenceのエージェントによる操作は、実行したユーザーの権限が適用されて動作します。 4. エージェントをカスタム エージェントをただ作成しただけでは、Snowflake上に保管したデータへのアクセスは行ってくれません。 (一般的な回答のみを行います) エージェントにSnowflakeのDB上のデータを検索させたり分析させたりしたい場合、「ツール」を紐づけてカスタマイズする必要があります。 エージェントの編集画面の[ツール]では、従来のSnowflakeのAI機能を紐づけることで、エージェントがどのようにデータへアクセスするかを指定できます。 ツールの代表的なものが Cortex Analyst と Cortex Search です。   Cortex Analyst | Snowflake Documentation docs.snowflake.com Cortex Search | Snowflake Documentation docs.snowflake.com Cortex Analystは構造化データの検索に、Cortex Searchは画像やPDFのような非構造化データの検索に対応しています。 ツールを紐づけると、エージェントは単なる回答生成にとどまらずオーケストレーションの役割を担います。ユーザーの問いかけに応じて、必要なツールを柔軟に組み合わせて使いこなすことが可能になります。 たとえば、自然言語での問い合わせに対してまず関連するドキュメントを検索し、そこから得た情報をもとにSQLを自動生成して値を算出するといった、一連の操作を自動化してくれるようになります。   最後に 本記事では、アカウント設定を行ってSnowflake Intelligenceを動作できるようにするところまでをご紹介しました。 ここまではまだAI活用のための入口で、エージェントによるデータ分析や検索を実際の業務に生かせるほどの精度にするためには、セマンティックモデルの作成がカギを握ります。 セマンティックモデルとは、業務上の用語や指標をメタデータとして整理し、AI が解釈できる形に定義する仕組みです。   Cortex Analyst セマンティックモデル仕様 | Snowflake Documentation docs.snowflake.com AI は人と同じように、複雑で整理されていない情報からは力を発揮しづらい一方で、メタデータやセマンティックモデルが整備されているほど、その能力を最大限に発揮します。 Snowflake Intelligenceの力を最大限引き出すために、いろいろと試行錯誤してみたいと思います!
アバター
2025年7月に Catoクラウドのユーザーコミュニティ(ユーザ交流会、ユーザ会)「 Cato Circle(ケイトサークル) 」の発足についての記事を掲載しましたが、今回は 9月18日に開催した初回イベントの記事となります。 Catoクラウド ユーザーコミュニティ「Cato Circle(ケイトサークル)」を発足しました – TechHarmony   参加いただいたお客様の声 イベント内容のご紹介より先に Cato Circle 初回イベントに参加いただいたお客の声、実際のアンケートのフリーコメントを記載します(お客様が特定できるコメントについては除外させていただきました) この度はご招待いただき本当にありがとうございました。貴重なお話をお伺いできる場をご提供いただき感謝申し上げます。とても有意義な時間でした。Cato様より最新の情報やこれからのロードマップをお伺いでき、今後弊社内での方向性を検討するのにとても参考になりました。またCatoを導入されている各社様の生の声を聴くことができ、多くのことに気づかされたり、共感できるところも多く、とても勇気づけられました。SCSK様の技術担当の方ともお話させていただきとても勉強になりました。またブログはいつも本当に参考にさせていただいておりますので、これからも様々なCato関連の情報をご提供いただけると幸いです。 Catoの実ユーザーの方の事例が聞けてとてもよかったです。どこの会社様も同じような経験をされているのだなと、心強く感じました。システム管理部門の方が集まったことで、Catoのお話から発展して各社のシステムの導入状況や運用体制などもお話できてとても参考になりました。Cato社の方から直接ロードマップなどお話いただく機会もありそれもとてもよかったです。直接お会いできたことで身近にも感じられましたし、これからのアップデートも楽しみです。Catoの今後の活用について想像できる機会にもなりましたので、次回の開催がありましたらまた参加したいです。 CATOユーザ同士での情報交換は大変有意義でした。CATO以外のセキュリティ関連の利用状況等(もちろん、CATOとのすみ分け等の情報についても)、興味深い情報交換が出来て充実したユーザ会となりました。次回も是非参加させていただきます。ありがとうございました。 お会いした各社それぞれの導入状況や課題など幅広く聞くことができて大変有意義な会でした。是非、第二回目が開催されることを期待しております。 他社と情報交換できる機会ができて大変有意義でした。ぜひとも今後も定期的に開催いただけると幸いです。 他社様の状況を知ることができ、大変有意義な機会となりました。ありがとうございます。 今後またぜひこういった機会があれば参加させていただけますと幸いです。 各社のオプションの導入状況が分かり、参考になりました(自社も標準的だと分かり、安心した)。 現在PoCを進めている中で、他企業様の具体的な事例を直接伺うことができ、大変有意義な機会となりました。導入・運用の実態に即した事例は理解を深めるうえで非常に参考となり、本番導入に向けた課題の整理にも大いに役立てられると感じております。 セキュリティに関わる部分なので、こういった情報をどこまで共有できるのかは難しいところですが、各社、どのくらいの規模感や国で運用されているのかなど、事前情報として紙一枚あったりするともう少しユーザー間でのコミュニケーションも取りやすいのではないかと感じました。 今回のユーザー会はとても有意義でした。参加させていただいた中で思ったことは、同じ悩みを持つ他社とのマッチング・グループディスカッションがあると良いと思いました。グループディスカッションの中にCato又はSCSKの方が入り、悩みに対して答えや閃きを回答できると更にいいですね。年,半年に1回くらいあると嬉しいです。 パネルディスカッションで参加者からのQAなどのコーナーがあった方が良かったと感じました。 他社様での運用状況などもお話が聞けて参考になりました。(パネルディスカッションも、もう少し時間があると良かったです) パネルディスカッションの時間をもう少し長く確保してあるとありがたいです。ネットワーキングの時間も、運用の面や設定について等話が伺えたため、非常に良かったです。 思った以上に良いイベントでした。事例紹介やディスカッションなど、実際のユーザの声をきくことができて興味深かったです。 ありがとうございました。 個人的には開催規模もちょうどいいと感じました。規模が大きすぎると情報過多になってしまうケースがあり、欲しい情報が埋もれてしまう場合もありますので。 Cato Circleを開催いただきまして、ありがとうございました。CATOユーザー企業様やCATO社様とも様々なお話ができて、学びの多い有意義な1日を過ごすことができました。これからも情報交換させていただき、より良くCATOを活用し、CATO仲間も増やし盛り上げていきたいと思います。 皆さん、アンケートありがとうございました。いただいた意見をもとに、次回はさらに良いイベントにしたいと思います。 フリーコメントから、Cato Circleがどのようなイベントであったかはご理解いただけたのではないかと思います。   Cato Circleイベント内容 さてイベント内容ですが、会場は当社八重洲 SCSK LINK SQUAREで、 20社以上 のお客様に参加いただきました。 Cato Circle 開催の挨拶後、Cato Networks株式会社(アジア太平洋地域フィールドCTO 金子 春信氏)より、Catoクラウドの最新トピックおよびロードマップの説明を行っていただきました。 特に、日本から要望の多い APNIC(JPNIC)問題 、 IPv6(IPoE)対応 、 日本独自のIDaaSサービス連携 などの対応状況から始まり、今後の Catoクラウドのロードマップ の説明があり、皆さんの興味を引いていました。 その後、Catoご利用企業(4社)から、それぞれの導入事例についてご講演をいただきました。 内容としては、会社紹介から、 Catoクラウド採用/導入に至った背景(課題)・経緯、導入時のトラブルや解決方法・工夫したこと、有効な活用方法、これでまで発生した障害や トラブル、Catoおよび当社への改善/要望事項 などをご話いただきました。 参加の皆さんが、最も興味を引いたプログラムだったと思います。 プレゼン内容は、もちろん録音録画不可で、その場限りの非常に貴重な講演となりました。 そして、 講演いただいた4社と、Cato社、SCSKで、パネルディスカッション を行いました。 パネルディスカッションのテーマ(お題)ついては、事前に Cato Circle お申し込み時に「他の利用企業へ聞きたいこと」を事前にお聞きしておりましたので質問が多い順に、事前に10個ほどテーマをピックアップし、それぞれについてディスカッションを実施しました。しかし、残念ながら Cato Circle 初回開催ということもあり、スケジュール計画があまく、時間がかなり押していたため、ディスカッション時間が当初予定より大幅に短縮してしまい、もっと話を聞きたかったのお客様が殆どではないかと思います(大変申し訳ないです) パネルディスカッションの後、少しだけ当社マネージドサービスをご紹介させていただきました。時間の都合上、当社独自のCato AIチャットボットの活用方法の説明ができず残念でしたが、月次報告書のレポート内容について簡単にご紹介させていただきました。 その後、18時から懇親会(軽食、アルコールあり)を行い、参加者の皆さんでネットワーキングを行っていただきました。 お客様同士で、Catoで利用されているオプションや機能(Backhaulingなど)、設定内容、中国・ベトナムなど海外展開における不安事を実際導入されているお客様へ相談されたり、また、Catoに限らず様々な話をされた とお聞きしました。 お帰りの際に「期待していた以上によかったです」「またぜひ開催してください」など嬉しい言葉をたくさんいただきました。 一方で、スケジュール(パネルディスカッションが短い)や段取り、会場セッティング等々、様々な面で多くの不備がありましたが、第1回ということで、何卒ご理解、ご容赦いただけると幸いです。 何よりも数年前から多くのお客様から「Cato利用者同士で会話ができる場を設けて欲しい」と言うご要望にやっとお応えできたのがもっとも良かったことになります。   次回開催に向けて 今回の Cato Circle のアンケート結果から、次回(第2回) Cato Circle について検討を開始しています。 北海道から九州までお客様がいらっしゃるので、東京以外でのイベント開催のご要望、イベント規模(参加人数・時間含め)をもっと大きくして欲しい(時間を長くして欲しい)という声と、逆に人数(規模)を少なくして欲しいと言う声もありました。開催頻度は年に1回、半年に1回の希望が多くあり、フリーコメントにあったようにグループディスカッションの希望も多くいただいております。   Cato Socket X1500 と PoP の 特注アイシングクッキー(Cato Network社からの差し入れ) 次回イベントは、今回と同じく当社(SCSK)主催するのか、あるいは Cato Networks社が主催するのか、から検討します。 Cato Networks社(Japan)で、お客様が参加できるイベントを開催するのであれば、Catoクラウドの最新トピックや機能紹介、ロードマップ説明は、そちらで実施できると思います。 そもそも Cato Circle は、 ユーザーコミュニティ ですので、通常のセミナーのように、一方的に説明を行う「説明型」イベントを行うのではなく、 利用者であるお客様が、Catoクラウドの自社での活用方法や、利用上の課題を発表し、利用者同士が情報を共有する「双方向型」のイベントを目指しております 。お客様同士の交流、ネットワーク構築から、情報交換のきっかけをご提供し、課題や悩みを共有し、解決するヒントを得ていただくことが Cato Circle の目的です(一方、Cato Networks社や、SCSKのサービスに関するフィードバックをいただき、サービス開発や改善に役立てることが、もう一つの目的にあります) そのため Cato Circle では、お客様自身の導入事例紹介による情報発信(共有)、パネルディスカッションやグループディスカッション、お客様同士のネットワーキングを中心としたイベントを計画する予定です。 Catoクラウドをご利用のお客様は、ぜひ Cato Circle へご参加ください。もし、当社のお客様で初回イベントはスケジュールの都合で参加できなかったが次回はぜひ参加したい、Cato Circle の案内がまだ来ていない、と言う方がいらっしゃれば、当社担当者までお問い合わせください。   まとめ 最後に、日本国内でも、 SASE (Secure Access Service Edge、サッシー)、 Cato Networks 、 Catoクラウド (正式名称は、Cato SASE Cloud Platform)の認知度は徐々に上がっていますが、まだまだ高いとは言えない状況です。 SCSKでは、2021年からSASEの主要な4ソリューション(Cato、Palo Alto、Netskope、Cisco)を一同に紹介を行うオンラインセミナー「 SCSK SASE Solution Summit(通称 S4 エスフォー) 」を定期的に開催しております。S4は、これまで述べ2,400名以上の方に参加いただいております。 また、Catoクラウドは、 初心者向けの簡単セミナー から、Cato管理ポータルを利用し主要機能をデモ形式で説明する デモセミナー 、全国各地にて対面で開催する ハンズオンセミナー も定期的に開催しておりますので、ご興味ある方は、ぜひご参加ください。すべて無料です。 Catoクラウド イベント・セミナー情報 | よくあるご質問 | Cato Cloud ケイトクラウド - SCSK 定期的にCatoクラウドをご紹介するセミナーを開催しております。・2025年9月24日(水)Catoクラウド デモセミナー  ・2025年10月10日(金)... cato-scsk.dga.jp 各種セミナー以外にも、Catoクラウドの お客様導入事例 の制作、 FAQサイト の運営、この  TechHarmony(技術ブログ) で、Catoクラウドの日本語の情報を提供し、少しでもCatoクラウドの認知度向上と、皆様のお役に立てればと考えております。 当社とご契約のお客様には、Catoのメルマガ配信や、Cato Circleへの案内も行います。 Cato Circle を含め、Catoクラウドに少しでも興味をお持ちになられた方は、ぜひ当社まで お問い合わせ ください。 Catoクラウド エンジニアブログまとめ記事 Catoクラウドのエンジニアブログ(TechHarmony)でのまとめ記事となります。 blog.usize-tech.com 2024.02.27
アバター
AWS CDK で開発しながら、最終的には AWS CloudFormation テンプレートでデプロイしたいケースに対応するため、CDK 特有の余計なメタデータ情報を含まない CloudFormation テンプレートを生成する方法を紹介します。 AWS CloudFormation テンプレート生成時の設定方法 1. AWS CDK コード作成 例として Amazon EC2 を作成するコードで説明します。 bin/app.tsにて、CDKからCloudFormationテンプレートを作成する際の設定をcdk.DefaultStackSynthesizerで定義します。 bin/app.ts  synthesizer設定: const app = new cdk.App(); new Ec2Stack(app, 'EC2Stack', {  synthesizer: new cdk.DefaultStackSynthesizer({   generateBootstrapVersionRule: false // CDK BootstrapVersionチェックを無効化  }) }); オプション: generateBootstrapVersionRule: false : BootstrapVersionパラメータとルールを除外する   lib/EC2Stack.ts : import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; export class Ec2Stack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const subnetId = "subnet-123456789abc"; // EC2インスタンス作成 const ec2Instance = new cdk.aws_ec2.CfnInstance(this, 'Ec2Instance01a', { imageId: 'ami-0bdebfdf585253328', instanceType: 't3.micro', subnetId: subnetId, securityGroupIds: ['sg-abcdefg1234'], iamInstanceProfile: 'instance_profile', keyName: 'keypair-name', disableApiTermination: false, // EBSボリューム設定 blockDeviceMappings: [ { deviceName: '/dev/xvda', ebs: { volumeSize: 30, volumeType: 'gp3', encrypted: true, deleteOnTermination: true } } ], ebsOptimized: true, monitoring: false, metadataOptions: { httpTokens: 'required', }, // タグ設定 tags: [ { key: 'Name', value: 'CDK-Generation-Ec2Instance' }, ] }); } } 2. synthコマンドで AWS CloudFormation テンプレート生成 以下のコマンドを実行し、CloudFormationテンプレートを生成します。 テンプレートは cdk.out 配下に出力されます。 cdk synth <スタック名> --no-path-metadata --no-version-reporting オプション: --no-path-metadata : リソースのMetadata内の aws:cdk:path 情報を除外する --no-version-reporting : CDKバージョン情報を除外する   cdk.out/Ec2Stack.template.json : Resources: Ec2Instance01a: Type: AWS::EC2::Instance Properties: BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: DeleteOnTermination: true Encrypted: true VolumeSize: 30 VolumeType: gp3 DisableApiTermination: false EbsOptimized: true IamInstanceProfile: instance_profile ImageId: ami-0bdebfdf585253328 InstanceType: t3.micro KeyName: keypair-name MetadataOptions: HttpTokens: required Monitoring: false SecurityGroupIds: - sg-abcdefg1234 SubnetId: subnet-123456789abc Tags: - Key: Name Value: CDK-Generation-Ec2Instance 参考 オプションをつけずにコマンドを実行すると、27行目以降にメタデータ情報が記載されたテンプレートが作成されます。 Resources: Ec2Instance01a: Type: AWS::EC2::Instance Properties: BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: DeleteOnTermination: true Encrypted: true VolumeSize: 30 VolumeType: gp3 DisableApiTermination: false EbsOptimized: true IamInstanceProfile: instance_profile ImageId: ami-0bdebfdf585253328 InstanceType: t3.micro KeyName: keypair-name MetadataOptions: HttpTokens: required Monitoring: false SecurityGroupIds: - sg-abcdefg1234 SubnetId: subnet-123456789abc Tags: - Key: Name Value: CDK-Generation-Ec2Instance Metadata: aws:cdk:path: Ec2Stack/Ec2Instance01a CDKMetadata: Type: AWS::CDK::Metadata Properties: Analytics: v2:deflate64:H4sIAAAAAAAA/zPSMzI01jNQTCwv1k1OydbNyUzSqw4uSUzO1kksL45PTTbSc07L88wrLknMS06t1cnLT0nVyyrWLzMy0jM01jNUzCrOzNQtKs0rycxN1QuC0ACVaq8YVQAAAA== Metadata: aws:cdk:path: Ec2Stack/CDKMetadata/Default Condition: CDKMetadataAvailable Conditions: CDKMetadataAvailable: Fn::Or: - Fn::Or: - Fn::Equals: - Ref: AWS::Region - af-south-1 - Fn::Equals: - Ref: AWS::Region - ap-east-1 - Fn::Equals: - Ref: AWS::Region - ap-northeast-1 - Fn::Equals: - Ref: AWS::Region - ap-northeast-2 - Fn::Equals: - Ref: AWS::Region - ap-northeast-3 - Fn::Equals: - Ref: AWS::Region - ap-south-1 - Fn::Equals: - Ref: AWS::Region - ap-south-2 - Fn::Equals: - Ref: AWS::Region - ap-southeast-1 - Fn::Equals: - Ref: AWS::Region - ap-southeast-2 - Fn::Equals: - Ref: AWS::Region - ap-southeast-3 - Fn::Or: - Fn::Equals: - Ref: AWS::Region - ap-southeast-4 - Fn::Equals: - Ref: AWS::Region - ca-central-1 - Fn::Equals: - Ref: AWS::Region - ca-west-1 - Fn::Equals: - Ref: AWS::Region - cn-north-1 - Fn::Equals: - Ref: AWS::Region - cn-northwest-1 - Fn::Equals: - Ref: AWS::Region - eu-central-1 - Fn::Equals: - Ref: AWS::Region - eu-central-2 - Fn::Equals: - Ref: AWS::Region - eu-north-1 - Fn::Equals: - Ref: AWS::Region - eu-south-1 - Fn::Equals: - Ref: AWS::Region - eu-south-2 - Fn::Or: - Fn::Equals: - Ref: AWS::Region - eu-west-1 - Fn::Equals: - Ref: AWS::Region - eu-west-2 - Fn::Equals: - Ref: AWS::Region - eu-west-3 - Fn::Equals: - Ref: AWS::Region - il-central-1 - Fn::Equals: - Ref: AWS::Region - me-central-1 - Fn::Equals: - Ref: AWS::Region - me-south-1 - Fn::Equals: - Ref: AWS::Region - sa-east-1 - Fn::Equals: - Ref: AWS::Region - us-east-1 - Fn::Equals: - Ref: AWS::Region - us-east-2 - Fn::Equals: - Ref: AWS::Region - us-west-1 - Fn::Equals: - Ref: AWS::Region - us-west-2 まとめ 今回は AWS CDK を使ってメタデータ情報がない AWS CloudFormation テンプレートを生成してみました。 皆さんのお役に立てば幸いです。
アバター
SCSK LifeKeeper担当 池田です。 LifeKeeperを使ったHAクラスタシステムを構成したい時、皆さんは誰にお願いしますか? 社内の情報システム部、普段お世話になっているSIer、メーカーであるサイオステクノロジー社の公式サイトに掲載されているパートナー企業などいろいろあるかと思います。 数多ある選択肢のなかでも、SCSKがなぜLifeKeeperの構築に強く、そしてお客様に選んでいただけるのかを5つの視点でお伝えします。 LifeKeeperの構築は簡単? LifeKeeperのインストールを経験したことのあるかたはご存じかもしれませんが、実はインストール自体は、専用のGUIから比較的簡単に実施することができます。 ところが、LifeKeeperに限らず、HAクラスタ製品の難しいところは、その周辺の環境を正しく理解し、LifeKeeperの導入に適した状況にする「 設計 」にあります。 この 設計フェーズ における 準備 をいかにきちんと実施し、 OSやネットワーク、セキュリティ等々の設定を 設計通りに実装できるか が、 LifeKeeper導入の 成功のカギ となります 。 WHY SCSK? なぜSCSKはLifeKeeperに強いのか? それでは、ここからは本題の「 WHY SCSK? なぜSCSKはLifeKeeperに強いのか? 」という質問にひとつひとつお応えしていこうと思います。 SCSKはLifeKeeperの構築実績が豊富 まず第一に、SCSKはLifeKeeperの 構築実績が豊富 であるということが挙げられます。 SCSKでは、2004年から 20年以上 に渡ってLifeeeperのご提案、設計、構築、サポートを行ってきました。お客様の数では100社を超えます。 その中で、オンプレミス構成、vSphereにおける仮想構成、パブリッククラウド構成といった様々なプラットフォームはもとより、データレプリケーション構成、共有ディスク構成など、ありとあらゆる構成の設計と構築を経験しています。 SCSKにはミドルウェアの専門部隊がある 第二に、SCSKには、 ミドルウェアの専門部隊 があるということです。 LifeKeeperは、何らかのミドルウェアの可用性を高めたいという目的で導入することから、その対象となるミドルウェアを熟知している必要があります。LifeKeeperと組み合わせる為にはサーバ1台の場合とは異なり、 独特のクセ があります。それはインストールの順番であったり、ディレクトリ構成であったり様々です。 その癖をミドルウェアメーカーやLifekeeperの公式サイトから正確に読み取ることは、なかなか至難の業で、 深い見識とノウハウがものをいう 部分でもあります。 SCSKでは、長年に渡りミドルウェア部隊とLifeKeeper部隊で豊富な経験と技術の蓄積をもとに阿吽の呼吸で協力しながら取り進められることから、 高品質な構成をお届けできる体制が整っています 。 SCSKはインフラ環境の特性に合わせた設計・構築に強い 第三に、SCSKはインフラ環境の特性に合わせた設計が得意です。もう少し具体的に申し上げますと、例えばAmazon Web Services(AWS)における構成一つとっても、通信要件によって様々な接続方式があります。例えば自社オンプレサーバとの接続でDirectConnectを用いた接続や、TransitGateway経由のルートテーブルを用いた接続、Route53を用いた接続、Network Load Balancer (NLB) からの接続などのパターンがありますが、通信要件に合わせ最適な接続方式の実装実績とご提案が可能です。 SCSKは技術者認定資格保有数が世界一 第四に、SCSKには、サイオステクノロジー社の技術者認定資格(2024年10月31日提供開始)の保有数が120以上を超え、 世界一 (2025年3月末時点) となっています。これはLifeKeeperをどのSIerよりも詳しいということを意味しております。 現在、提供されている技術者認定資格としては、以下2つの内容となります。 LifeKeeper for Linux 技術者認定資格(BASIC) LifeKeeper for Windows 技術者認定資格(BASIC) SCSKはサイオステクノロジーとの関係が深い 第五に、SCSKはLifeKeeperのメーカーである サイオステクノロジー社との関係が深い 点が挙げられます。 1でもお伝えした通り、20年以上に渡って、サイオステクノロジー社とは、営業責任者、開発責任者、サポート責任者とも頻繁に打合せを重ねており、密な情報連携を図っています。 その為、構築中に不測の事態が発生した際に、即座にサイオステクノロジー社と連携を取り、双方協力しながら解決に導くことが可能です。 これは長年に渡って、「お客様により良い製品をお届けしたい」というSCSKとサイオステクノロジー社の熱い想いを持って喧々諤々の議論を重ねていることによる、信頼関係によるところが大きいと自負しています。 まとめ 今回、 WHY SCSK? ~ なぜSCSKはLifeKeeperに強いのか? という問いに対してする5つのご回答を挙げました。 1.豊富な構築実績 2.ミドルウェアの専門部隊とのタッグ 3.インフラ環境の特性に合わせた設計・構築が得意 4.技術者認定資格保有数が世界一 5.サイオステクノロジー社との関係の深さ LifeKeeperの導入を誰にお願いするか迷われた際には 、本記事をご参考にしていただき、 是非経験豊富なSCSKにお任せください 。 LifeKeeperについて、詳しい内容をお知りになりたいかたは、以下のバナーからSCSK LifeKeeper公式サイトまで
アバター
こんにちは。SCSKの山口です。 今回は、Google Cloud認定資格の受験レポート その②です。 はじめに 先日投稿した受験前レポートをまだご覧になっていない方はまずはこちらをご覧ください。 【Google Cloud】Generative AI Leader 受験前レポート Google CloudのGenerative AI Leader資格対策を徹底解説。試験ガイドに基づいた重要キーワード(ファインチューニング、RAGなど)と主要サービス(Gemini, Vertex AIなど)の概要、特徴、ユースケースを網羅。 blog.usize-tech.com 2025.06.09   受験前レポートの投稿からちょっと時間が空いてしまったのですが、実は一発目のチャレンジ(英語試験)で落ちてしまいました。。 内容が難しかったというより、英文の問題文をうまく読み解けていなかった気がします。 久々の不合格でショックを受けていたのですが、 「Google CloudのAll Certificationが始まるから落ち込んでられない、、」 と何とか立ち直りました。 Google Cloud Partner All Certification Holders 2025 応募開始 | Google Cloud 公式ブログ cloud.google.com   そんな中、タイミングよく 日本語版の試験がリリース されました。 二度目の挑戦(日本語試験)では無事合格できたので、受験後レポートを書こうと思います。   受験前とのギャップ その①ブログでも書いている通り、Google Cloudの生成AI関連サービスが多く問われそうな印象でしたが、ここはまさにその通りでした。 ただし、問題文に要件が書いてあって、選択肢から適切なサービスを選択するようなシンプルな問題もあれば、 ○○の要件に合わせて、△△サービスを選定しましたが、これは△△サービスのどの特徴を活かしたものですか? のような問題も多くでました。 選択肢がすべて正しいこと(サービスの特徴)を言っているものもあったので、ちょっと時間をかけて考えました。 初級の資格ではありますが、 各サービスの特徴/長所 のような一歩踏み込んだ内容についても抑えておくとかなり有利です。   各サービスの特徴/長所に関しては、その①ブログにも「特徴」「ユースケース」としてまとめているのでそちらをご覧ください。 【Google Cloud】Generative AI Leader 受験前レポート Google CloudのGenerative AI Leader資格対策を徹底解説。試験ガイドに基づいた重要キーワード(ファインチューニング、RAGなど)と主要サービス(Gemini, Vertex AIなど)の概要、特徴、ユースケースを網羅。 blog.usize-tech.com 2025.06.09   個人的頻出ワード 今回は、その①に登場したサービス・概念を、個人的な主観と記憶を頼りにランク付けしていきます。   機械学習の基礎概念 キーワード ランク(★が多いほど頻出) 教師あり学習 ★★ 教師なし学習 ★★★ 深層学習(ディープラーニング) ★ 強化学習 ★★★ 問われ方としては、「この学習方法はどれですか?」という基本的な問われ方が多かったです。 個人的に、「教師なし学習」と「強化学習」を選択させるような問題が多かったので、★3つにしました。 深層学習は登場していなかった気がします。(もしかしたらダミー選択肢に居たかも。)   Generative AIの応用とカスタマイズ+運用 キーワード ランク ファインチューニング ★ プロンプトエンジニアリング ★★★ RAG ★★★ グラウンディング ★★ ヒューマンインザループ ★ プロンプトエンジニアリング、RAGがとにかく出題された気がします。 企業が生成AI活用で直面している問題に対してどの手法を用いるか?という観点で選択肢を選ぶ問題が頻出です。 プロンプトエンジニアリング、RAGそれぞれで解決できるケースをイメージできるようにしておきましょう。   基盤モデル・ソリューション キーワード ランク Gemini ★★★ Gemma ★★ Veo ★★ Imagen ★★★ NotebookLM ★★★ Gemini for Google Workspace ★ Agentspace ★★★ Conversational Agents ★★ Contact Center as a Service ★★ ここが問われる問題が一番多かった印象です。 特にGemini、Agentspaceあたりは★10個くらいつけたいくらい問われます。 その他のキーワードに関しても、概要が頭に浮かぶようにしておいた方が良いです。   まとめ 英語版の試験で一度落ちてしまいましたが、日本語版で再度受験し、難易度的には初級に近いなという印象を受けました。 今回ご紹介したキーワードの概要がイメージでき、説明レベルになっていれば十分戦えるのではないかと思います。(※あくまで202509時点の筆者の主観です。) 個人的には、最先端を走るGoogleのAI関連サービスを知ることができる良い試験だと思います。 まだGoogle Cloudの認定資格にチャレンジしたことがない方も是非チャレンジしていただきたいと思います。
アバター
こんにちは SCSKの庄司です。 今回はServiceNowの修復スクリプト(Fix Script)について紹介していきます。 本記事は執筆時点(2025年9月)の情報になります。最新の内容は製品ドキュメントを参考にしてください。 修復スクリプト(Fix Script)とは Fix Script は、アプリのインストール/アップグレード後に走らせて、データや設定の補正・初期化・移行を行うためのサーバサイド JavaScript です。 更新セットやアプリ更新だけでは反映しきれない、 既存データの補正 特定条件のデータの作成・更新 など、大量のデータを一回のみ、自動更新・作成することに向いています。 逆に「任意タイミングで複数回実行するスクリプト」や「定期的なスクリプト実行」はスケジュール済みジョブなどが適しているので、そちらの利用を検討してください。 修復スクリプトレコードはsys_script_fixテーブルに格納されており、 すべて > システム定義 > 修復スクリプト から遷移可能です。   修復スクリプトレコードのオプション   読み込み不能 :チェックをするとスクリプト実行時に顧客アップデートレコードを作成する。必要に応じて顧客アップデートレコードを更新セットに格納し、移送することも可能に。 ロールバック用に記録 :ロールバック用にスクリプトの実行を記録し、必要に応じて元に戻すことが可能になる。 前 :アプリのインストールまたはアップグレード前にスクリプトを実行することができる。   実行前の注意事項 事前検証 :本番前に開発環境やPDIでテスト ロールバックを有効化 :ロールバック用に記録にチェックをしてから実行 バックアップ :更新対象のレコードを事前にCSVエクスポート 負荷配慮 :業務時間帯の実施は環境に負荷を与えるため控える(特に大量のレコードを更新する場合)   修復スクリプトの実践 では、ここからは簡単な修復スクリプトを実際に使ってみようと思います。 すべて > システム定義 > 修復スクリプトに遷移し、[新規]を押下します。 今回は以下の条件で実施します。 読み込み不能 :true ロールバック用に記録 :true 前 :false 以下のスクリプトを記載します。 指定したカタログ配下にあるアクティブなすべてのカタログアイテムに対して、「利用可能」のユーザー基準を作成するスクリプトです。 // ===== 設定 ===== var catalogSysId = '742ce428d7211100f2d224837e61036d'; // 本番対象カタログ sys_id var userCriteriaSysId = '322f2efa83bb6210b7e5f9a6feaad35d'; // 付与する User Criteria の sys_id // ================= // 対象アイテムを取得 var grItem = new GlideRecord('sc_cat_item'); // カタログ配下の全アイテム grItem.addQuery('sc_catalogs', catalogSysId); gs.info('=== カタログ ' + catalogSysId + ' 配下のアイテムすべて ==='); grItem.addQuery('active', true); grItem.query(); var count = 0; while (grItem.next()) {   // 既存レコードの重複チェック   var grCheck = new GlideRecord('sc_cat_item_user_criteria_mtom');   grCheck.addQuery('sc_cat_item', grItem.sys_id);   grCheck.addQuery('user_criteria', userCriteriaSysId);   grCheck.query();   if (!grCheck.hasNext()) {       var grNew = new GlideRecord('sc_cat_item_user_criteria_mtom');       grNew.initialize();       grNew.setValue('sc_cat_item', grItem.sys_id);       grNew.setValue('user_criteria', userCriteriaSysId);       grNew.insert();       count++;       gs.info('ユーザー基準を追加: ' + grItem.name);   } else {       gs.info('すでに存在: ' + grItem.name);   } } gs.info('合計 ' + count + ' 件のレコードを作成しました。'); 今回 の対象となるユーザー基準とカタログは以下になります。 ユーザー基準:fix script test user criteria カタログ:Technical Catalog 利用可能なカタログアイテムテーブルとロールバックコンテキストテーブルに該当するレコードが存在しないことを確認します。 では、[スクリプト修復の実行]を押下し、今回は[続行]を押下します。     修復スクリプトが実行され、ログが表示されています。 今回はスクリプト内で記載していたため、ユーザー基準を追加したカタログアイテム名と合計レコード作成数がログに表示されています。 では、実行結果を確認しに行きます。 まず、 利用可能なカタログアイテムテーブルを見ると実際に6レコード分のレコードが作成されています。 次に、今回は「読み込み不能」をtrueにしているので顧客アップデートテーブルも確認しに行きます。 先ほど作成したレコードの顧客アップデートレコードが作成されています。   必要に応じてこちらのレコードを顧客アップデートレコードに追加することで、別環境に移送することが出来ます。 今回は「ロールバック用に記録」もtrueにしているのでロールバックコンテキストテーブルにもレコードが作成されています。 ロールバックコンテキストレコードを開くと、「ロールバックレコード」関連リストに今回のスクリプト実行に際して作成されたレコード(sc_cat_item_user_criteria_mtomレコード、sys_update_xmlレコード、sys_update_versionレコードsys_metadata_customizationレコード)が紐づけられています。   せっかくなので、今回はロールバックまで実行してみようと思います。 [ロールバック]関連リンクを押下すると、「Execute Rollback?」というポップアップが表示されるので、「yes」と入力し、[OK]を押下します。 ロールバックが完了しました。 先ほどと同じ条件で利用可能なカタログアイテムテーブル、顧客アップデートテーブルを確認すると、レコードが表示されません。     まとめ 以上、今回はServiceNowの修復スクリプト(fix script)を紹介しました。 あまり使う機会はないかもしれませんが、特定のシチュエーションでは大きく力を発揮する機能です。 ぜひ参考にしてみてください。
アバター
こんにちは。SCSKの清水です。 2025/9/10(水)に開催された「Microsoft AI Tour Osaka」に参加しましたので、その参加レポートを投稿します。本記事では、 基調講演の内容を中心に、イベントの雰囲気や得られた気づき をレポートしていきます。 はじめに イベント概要 Microsoft AI Tourは、世界各地で開催されているMicrosoft主催のAIイベントシリーズで、最新のAI技術や活用事例を紹介する場として注目を集めています。今回の大阪開催は、日本国内では東京に続く2回目の開催となり、関西圏の技術者・ビジネス関係者に向けて、AIによる業務変革や組織づくりに関する知見が共有されました。 イベントでは、Microsoftの最新AIソリューションに関する講演やデモが行われ、基調講演から技術セッション、展示ブースまで幅広いコンテンツが展開されました。 Microsoft AI Tour Osaka 「Microsoft AI Tour Osaka」は、AI の最新イノベーションを体験し、業界のソートリーダーや専門家とつながることができる、ビジネスリーダーと開発者のためのイベントです。キーノート、ブレイクアウトセッション、ハンズオン ワ... www.microsoft.com 参加目的 私はPowerPlatform関連、特にCopilot Studio目当てで参加しました。 Microsoft Build 2025でも多くのアップデートが発表されて、それらの機能がパブリックされていっています。機能としては理解しているものの、どのように活用するかのアイデアを収集したいと考え、参加を決めました。 基調講演 基調講演のタイトルは「 Becoming Frontier: AI で実現するフロンティア組織への進化とビジネス変革 」です。基調講演では、日本マイクロソフトの代表取締役社長である津坂 美樹氏が登壇されました。ここでは、基調講演の内容を少し紹介します。(内容の解釈に一部誤りがあるかもしれません。ご参考までに。) 基調講演は2025/9/21現在、Youtubeにてアーカイブ配信されています。ぜひ実際の講演内容をご覧ください。 - YouTube YouTube でお気に入りの動画や音楽を楽しみ、オリジナルのコンテンツをアップロードして友だちや家族、世界中の人たちと共有しましょう。 aka.ms なお、基調講演とは「 イベントの冒頭に行われる中心的な講演で、テーマや方向性を示す講演 」のことです。 フロンティア組織への進化 フロンティア組織とは「 AIを活用して様々な課題を解決するためにAIトランスフォーメーションを推進している企業 」と定義されました。フロンティア組織になるために、Microsoftがどのように支援ができるか、というのが基調講演のメイントピックです。 基調講演では、フロンティア組織になるための成功の枠組みとして、以下の4点が挙げられていました。この4点の枠組みに対して、CopilotなどのAIソリューションを用いてアプローチすることでフロンティア組織への進化に至るということでした。 従業員エクスペリエンスの強化 顧客エンゲージメントの強化 ビジネスプロセスの再構築 イノベーションの加速 以降ではフロンティア組織の具体例として、 Zavaという架空の企業を題材に、MicrosoftのAIソリューションのデモを交えながら、戦略立案~開発までのシナリオ が説明されました。 最近のAIイベントでは、技術の仕組みや機能紹介よりも、「業務にどう活かすか」「どのような成果が出ているか」といった活用事例の紹介が中心になってきている印象を受けます。 Copilotを代表としたAIが“使えるサービス”として展開されている今、企業や組織が次に向き合うべきは“どう使うか”という問いなのだと改めて感じます。 それでは、4点の成功の枠組みに対してもう少し詳しく話していきます。 ①従業員エクスペリエンスの強化 AIを活用して社員の業務効率や創造性を高め、働き方そのものを進化させることです。 AIが単なるツールではなく、社員の判断力や創造性を引き出す存在として機能します。 ここで登場したのがM365 Copilotです。M365 Copilotが情報収集だけでなく分析といった複雑な思考を担ってくれます。M365 Copilotのリサーチャーエージェントやアナリストエージェントは2025/6に公開された機能のため、まだ業務に活用していない人も多いのではないでしょうか。 また、Copilot Studioではより社内の規定といった特定の社内情報のみを参照するカスタムエージェントを作成できます。M365 Copilotのみでは手の届かない領域もCopilot Studioを使用することで幅広い領域をCopilotに任せることができます。 活用されたソリューション Zavaでの活用シーン M365 Copilot リサーチャーエージェントによってZavaの脅威となる競合他社の情報を収集。 アナリストエージェントによってローンチ戦略を分析。 Copilot Studio 社内の様々な規定情報を参照したカスタムエージェントを作成。 Zavaの情報を参照してローンチ計画を策定。 ②顧客エンゲージメントの強化 人間が従来行っていた作業をAIが代理で担うことで、これまでにない顧客体験を創造することです。 例えば、コールセンター業務などはこれまで人間が担っていたことで、応対時間や応対数に制限がありました。これをAIに置き換えることにより24時間365日で即時対応可能なサービスを提供することができます。 また、AIを活用することで顧客のニーズを製品開発やマーケティングに迅速に反映させることができます。GitHub Copilotでは自然言語によるプロトタイプ開発から本番リリースまでのプロセスを短縮します。今回は特にVibe Codingの代表的な機能であるGitHub Sparkが紹介されていました。 さらには、AIを製品に組み込むためにAzure AI Foundryを使用します。1000を超えるモデルを選択可能で、独自のAIを柔軟にカスタマイズしてアプリケーションに配置することができます。 活用されたソリューション Zavaでの活用シーン GitHub Copilot 開発チームがマーケティング部門によるテストを想定した新アプリを迅速に発案及び試作 Azure AI Foundry 開発チームがアプリを改良し、大規模展開に向けて強化 ③ビジネスプロセスの再構築 エージェントを活用することを前提として、既存のビジネスプロセスを再構築することです。 ここではM365 Copilot+Excelでの財務調整エージェントが登場し、このトピックの主役でした。この機能は2025年リリース サイクル2でリリース予定の機能になっており、イベント開催時点ではリリース前の機能です。 (具体的な機能性については私の理解が及んでいない点がありますが)Excel上にエージェントが搭載され、データ分析やレポート作成の負荷が大幅に軽減されます。 活用されたソリューション Zavaでの活用シーン M365 Copilot+Excel 財務調整エージェントを自律的に動作するように訓練 Dynamics 365 財務部門がエージェントを活用し、期末締め処理を自動化 Microsoft 365 2025 年リリース サイクル 2 の財務エージェントの概要 Microsoft 365 2025 年リリース サイクル 2 の財務エージェントの概要 learn.microsoft.com ④イノベーションの加速 ここでは特に、 蓄積された膨大なデータを活用して新たなプロダクトを創造すること(を継続していくこと) 、とされています。 当然ですが開発された製品・サービスはリリースされたのちに改善活動を繰り返していきます。このとき、ユーザーから収集したデータをどのように活用できるかが継続的なイノベーションに欠かせません。 ここでMicrosoft Fabricが登場します。Microsoft Fabricはデータ統合プラットフォームとして多様な機能を有しています。 今回は特にデータの可視化としてデジタルツインの機能が目玉だったかと思います。Microsoft Fabricで様々なチャネルから蓄積されたデータをもとにデジタルツインを構築します。デジタルツインを活用することで対話型に、よりユーザーが親しみやすい形でデータを活用することができます。 活用されたソリューション Zavaでの活用シーン Microsoft Fabric 研究開発部門がFabricのデジタルツインを活用し、反復的改善、イノベーション、パフォーマンスの監視を実施 Microsoft Azure 研究開発部門がAzureを活用し、データの可視化とエージェントによるデータ活用を実施 基調講演の感想 特に印象的だったのは、事例を用いるのではなく、MicrosoftがZavaという架空の企業を用いて、AIソリューションによる業務変革の流れを具体的に描いていた点です。マーケティング、開発、財務といった部門ごとにCopilotやFabricなどのツールがどのように活用され、組織全体が“フロンティア化”していく様子が示されていました。単なる機能の紹介ではなく、 AIによる組織進化の“解像度”が高まった と感じました。 以上、簡単に基調講演のまとめになります。 この他に大阪府の吉村知事などフロンティア組織のリーダーが各組織での取り組みを紹介する内容もありますので、ぜひYoutubeのアーカイブ配信をご覧ください。 さいごに 全体の感想 今回のMicrosoft AI Tour Osakaは、技術者としての視点からも、実務に携わる立場からも、非常に充実した体験となりました。 イベント全体を通して、MicrosoftがもたらすAIの可能性を肌で感じることができ、何より純粋に楽しく、刺激的な時間でした。 特に楽しめた要因は、紹介された内容が自分のスキル領域と高い親和性を持っていたこと。PowerPlatformやCopilot Studio、Azure AI Foundryなど、日々関わっている技術がどのように フロンティア組織 の構築に活かされているかを明確にイメージできました。 また、Microsoftの吉田大貴さん、ギークフジワラさん、増田雄一さんといった著名な技術者・エバンジェリストの方々の話を直接聞けたことも大きな収穫です。彼らの語るビジョンや現場感は、資料や動画だけでは感じられない熱量を伴っていて、ただ話を聞くだけでなく実感としての理解が得られたように思います。 このイベントを通じて得た知見や気づきを、今後の業務や社内発信にどう活かしていくかが次のチャレンジです。 Microsoft AI Tour 2026に参加するには 東京開催の日付が公開されており、2026/3/24のようです。最新の情報は以下のサイトからご確認ください。 Microsoft AI Tour Osaka 2025では事前登録が必要でした。1か月ほど前から満席になり、キャンセル待ちになっていましたので、お申し込みはお早めに! Microsoft AI Tour Take the inside track to the AI frontier at the Microsoft AI Tour. Learn from experts, explore real-world strategies, an... aitour.microsoft.com
アバター
こんにちは。SCSK渡辺(大)です。 今年は秋らしい涼しさが続いて、とても過ごしやすいですね。 エアコンなしで快適に過ごせるようになりました。 作ったもの(作られたもの) Kiro から Claude Opus 4 と直接会話できる MCP サーバー を作りました。 たった  5 時間ほど で完成し、 Kiro の Specモード で開発が完結しました。 今回作成したMCPサーバーの使用にはBedrockモデルアクセスの有効化が必要です。 デモンストレーション 動画でご覧ください。 ▼ Claude Opus 4 と会話 document.createElement('video'); https://blog.usize-tech.com/contents/uploads/2025/09/DAI31.mp4 ▼ Claude Sonnet 4 と会話 https://blog.usize-tech.com/contents/uploads/2025/09/DAI32.mp4 ▼ Amazon Nova Micro と会話 https://blog.usize-tech.com/contents/uploads/2025/09/DAI33.mp4 各種構成図 システム概要図(by要件定義書) データフロー図(by要件定義書) 技術仕様フロー(by要件定義書) エラー処理フロー(by要件定義書) 総合アーキテクチャ(by要件定義書) テスト用モデル設定フロー(by要件定義書) パッケージ構造とコンポーネント関係(by設計文書) 実践レベルでのデータフロー(by設計文書) システム全体アーキテクチャ(by設計文書) エラー分類と処理戦略(by設計文書) AWS認証フロー(by設計文書) Specs 要件定義書(requirements.md) # 要件定義書 ## 概要 この仕様書は、Kiro IDE ユーザーが Model Context Protocol (MCP) を通じて AWS Bedrock の Amazon Nova + Claude の 3 つの AI モデルと用途別に対話できる Claude MCP サーバーの要件を定義します。このサーバーは、コスト効率を考慮した適切なモデル選択、エラーハンドリング、セキュリティ対策を維持しながら、テキストベースの会話のためのシンプルで信頼性の高いインターフェースを提供します。 ## システム概要図 ```mermaid flowchart TD A[Kiro IDE ユーザー] --> B[MCP クライアント Kiro IDE 内蔵] B --> C[MCP サーバー claude_opus_mcp] C --> D[AWS Bedrock API] D --> E[Amazon Nova Micro 超低コスト] D --> F[Claude Sonnet 4 バランス型] D --> G[Claude Opus 4 最高性能] E --> D F --> D G --> D D --> C C --> B B --> A H[AWS プロファイル 認証情報] --> C I[mcp.json 設定ファイル] --> B style A fill:#64b5f6,stroke:#1976d2,color:#000 style B fill:#4caf50,stroke:#2e7d32,color:#000 style C fill:#ff9800,stroke:#f57c00,color:#000 style D fill:#9c27b0,stroke:#7b1fa2,color:#fff style E fill:#00bcd4,stroke:#0097a7,color:#000 style F fill:#4caf50,stroke:#2e7d32,color:#000 style G fill:#4caf50,stroke:#2e7d32,color:#000 ``` ## 技術前提知識 本仕様書は以下の技術知識を前提とします: - **AWS Bedrock**: Foundation Model サービスの基本概念 - **IAM**: ロールとポリシーの設定経験 - **Python**: 中級レベルのプログラミング経験 - **JSON**: 設定ファイルの読み書き - **CLI**: コマンドライン操作の基本 - **API**: REST API の基本概念 ## データフロー図 ```mermaid sequenceDiagram participant U as Kiro ユーザー participant K as Kiro IDE participant M as MCP サーバー participant B as AWS Bedrock participant C as AIモデル (Nova/Sonnet/Opus) U->>K: "Claude に質問して" K->>M: chat_with_claude_opus(message, temperature) M->>M: AWS 認証情報取得 M->>B: invoke_model() API 呼び出し B->>C: メッセージ送信 C->>B: 応答生成 B->>M: API レスポンス M->>M: レスポンス処理 M->>K: MCP レスポンス K->>U: Claude の回答表示 Note over M,B: IAM 権限: bedrock:InvokeModel Note over B,C: モデル ID: anthropic.claude-opus-4-20250514-v1:0 ``` ## 要件 ### 要件 1: 用途別 AI モデルとの会話機能 **ユーザーストーリー:** Kiro IDE ユーザーとして、MCP ツールを通じて用途に応じて最適な AI モデル(Amazon Nova Micro, Claude Sonnet 4, Claude Opus 4)にメッセージを送信したい。これにより、コスト効率を考慮しながら開発環境内で直接各モデルの特性を活用できるようになる。 #### 技術仕様フロー ```mermaid flowchart TD A[ユーザー入力 メッセージ + temperature] --> B{入力検証} B -->|有効| C[AWS Bedrock API 呼び出し] B -->|無効| D[エラーレスポンス] C --> E{API 成功?} E -->|成功| F[Claude レスポンス取得] E -->|失敗| G[API エラー処理] F --> H[5秒以内レスポンス] G --> I[エラーメッセージ返却] H --> J[ユーザーに結果表示] I --> J style A fill:#64b5f6,stroke:#1976d2,color:#000 style C fill:#9c27b0,stroke:#7b1fa2,color:#fff style F fill:#4caf50,stroke:#2e7d32,color:#000 style H fill:#00bcd4,stroke:#0097a7,color:#000 ``` #### 受け入れ基準 1. ユーザーが chat_casual ツールを呼び出した時、システムは Amazon Nova Micro モデルにメッセージを送信すること 2. ユーザーが chat_professional ツールを呼び出した時、システムは Claude Sonnet 4 モデルにメッセージを送信すること 3. ユーザーが chat_expert ツールを呼び出した時、システムは Claude Opus 4 モデルにメッセージを送信すること 4. 各モデルが応答した時、システムは 5 秒以内にユーザーに応答テキストを返すこと 5. メッセージが 4000 トークンを超えた時、システムはトークン制限超過を示すエラーメッセージを返すこと 6. ユーザーが temperature パラメータ(0.0-1.0)を提供した時、システムは応答生成にその値を使用すること 7. temperature が提供されない場合、システムはデフォルト値として 0.7 を使用すること ### 要件 2: エラーハンドリングとトラブルシューティング **ユーザーストーリー:** Kiro IDE ユーザーとして、何か問題が発生した時に明確なエラーメッセージが欲しい。これにより、MCP サーバーの問題を迅速に理解し解決できるようになる。 #### エラー処理フロー ```mermaid flowchart TD A[エラー発生] --> B{エラー種別判定} B -->|認証エラー| C[AWS 認証失敗 IAM/プロファイル確認] B -->|API エラー| D[Bedrock API エラー 権限/モデルアクセス確認] B -->|ネットワークエラー| E[接続エラー ネットワーク確認] B -->|その他| F[予期しないエラー ログ記録] C --> G[ユーザー向けメッセージ] D --> G E --> G F --> G G --> H[デバッグログ出力] H --> I[エラーレスポンス返却] style A fill:#ff5722,stroke:#d32f2f,color:#fff style C fill:#ff9800,stroke:#f57c00,color:#000 style D fill:#ff9800,stroke:#f57c00,color:#000 style E fill:#ff9800,stroke:#f57c00,color:#000 style F fill:#ff9800,stroke:#f57c00,color:#000 style I fill:#64b5f6,stroke:#1976d2,color:#000 ``` #### 受け入れ基準 1. AWS 認証が失敗した時、システムは「AWS 認証に失敗しました。認証情報と AWS プロファイル設定を確認してください。」を返すこと 2. Bedrock API がエラーを返した時、システムは「Bedrock API エラー: [具体的なエラー]。Bedrock アクセス権限を確認してください。」を返すこと 3. ネットワーク接続が失敗した時、システムは「ネットワーク接続に失敗しました。インターネット接続を確認してください。」を返すこと 4. AI モデルアクセスが拒否された時、システムは「AI モデルアクセスが拒否されました。AWS Bedrock コンソールでモデルアクセス(Amazon Nova Micro, Claude Sonnet 4, Claude Opus 4)を有効にしてください。」を返すこと 5. 任意のエラーが発生した時、システムはデバッグ目的で詳細なエラーをログに記録すること ### 要件 3: Kiro IDE 統合とセットアップ **ユーザーストーリー:** Kiro IDE ユーザーとして、MCP サーバーが Kiro の設定とシームレスに統合されることを望む。これにより、複雑なセットアップ手順なしに使用できるようになる。 #### 統合アーキテクチャ ```mermaid flowchart TD A[mcp.json 設定ファイル] --> B[Kiro IDE MCP クライアント] B --> C[MCP サーバー起動 python -m claude_opus_mcp] D[AWS プロファイル ~/.aws/credentials] --> E[環境変数 MCP_AWS_PROFILE] E --> C C --> F[MCP プロトコル ハンドシェイク] F --> G[ツール登録 chat_with_claude_opus] G --> H[Kiro でツール利用可能] I[autoApprove 設定] --> B style A fill:#4caf50,stroke:#2e7d32,color:#000 style B fill:#64b5f6,stroke:#1976d2,color:#000 style C fill:#ff9800,stroke:#f57c00,color:#000 style D fill:#9c27b0,stroke:#7b1fa2,color:#fff style H fill:#00bcd4,stroke:#0097a7,color:#000 ``` #### 受け入れ基準 1. MCP サーバーが mcp.json で設定された時、Kiro は利用可能な MCP サーバーとして認識すること 2. サーバーが開始された時、適切な JSON スキーマで chat_with_claude_opus ツールを登録すること 3. ユーザーが autoApprove を設定している時、ツールは手動承認プロンプトなしで実行されること 4. サーバーが MCP_AWS_PROFILE 環境変数を使用する時、指定された AWS プロファイルを使用して認証すること 5. MCP_AWS_PROFILE が設定されていない場合、システムはデフォルトの AWS プロファイルを使用すること ### 要件 4 **ユーザーストーリー:** 開発者として、MCP サーバーが Python のベストプラクティスと MCP プロトコル標準に従うことを望む。これにより、保守可能で信頼性の高いものになる。 #### 受け入れ基準 1. サーバーがインストールされた時、`python -m claude_opus_mcp` で実行可能であること 2. サーバーが開始された時、適切な MCP プロトコルハンドシェイクを実装すること 3. サーバーがツール呼び出しを受信した時、JSON スキーマに従って入力パラメータを検証すること 4. サーバーが例外に遭遇した時、クラッシュすることなく適切に処理すること 5. サーバーがリクエストを処理する時、通常の条件下で 95% の成功率を維持すること ### 要件 5 **ユーザーストーリー:** システム管理者として、MCP サーバーが AWS 認証情報を安全に処理することを望む。これにより、機密情報が露出したり悪用されたりしないようになる。 #### 受け入れ基準 1. AWS 認証情報が必要な時、システムは AWS プロファイルまたは環境変数のみを使用すること 2. 認証情報が読み込まれた時、システムは平文でログに記録したり露出したりしないこと 3. AWS プロファイルを使用する時、システムは AWS CLI 認証情報の優先順位を尊重すること 4. IAM 権限が不十分な時、システムは必要な権限について明確なガイダンスを提供すること 5. サーバーが実行される時、3 つの AI モデル(Amazon Nova Micro, Claude Sonnet 4, Claude Opus 4)に対する bedrock:InvokeModel 権限のみを必要とすること ### 要件 6: テスト要件とコスト最適化 **ユーザーストーリー:** 開発者として、コスト効率的にテストを実行したい。これにより、開発コストを抑制しながら品質を確保できるようになる。 #### テスト用モデル設定フロー ```mermaid flowchart TD A[テスト実行] --> B{テスト種別} B -->|単体テスト| C[モック使用 コスト: $0] B -->|統合テスト| D[Claude Sonnet 4 コスト効率重視] B -->|本番確認| E[Claude Opus 4 最終検証のみ] D --> F[基本機能確認 anthropic.claude-sonnet-4-20250514-v1:0] E --> G[高度推論確認 anthropic.claude-opus-4-20250514-v1:0] style C fill:#4caf50,stroke:#2e7d32,color:#000 style D fill:#ff9800,stroke:#f57c00,color:#000 style E fill:#9c27b0,stroke:#7b1fa2,color:#fff ``` #### 受け入れ基準 1. システムは設定可能なモデル ID をサポートし、テスト時は Claude Sonnet 4 (anthropic.claude-sonnet-4-20250514-v1:0) を使用できること 2. 単体テストでは AWS API 呼び出しをモック化し、実際のコストを発生させないこと 3. 統合テストでは Claude Sonnet 4 を使用して基本的な会話機能を検証すること 4. 本番リリース前の最終確認でのみ Claude Opus 4 を使用し、日常的なテストでは Amazon Nova Micro や Claude Sonnet 4 を使用すること 5. テスト設定は環境変数 MCP_TEST_MODEL_ID で切り替え可能であること ## AWS 技術要件 ### 必要な AWS サービス知識 #### AWS Bedrock - **Foundation Models**: Amazon Nova Micro, Claude Sonnet 4, Claude Opus 4 モデルの特性理解 - **API 呼び出し**: invoke_model() メソッドの使用方法 - **モデル ID**: - Amazon Nova Micro: amazon.nova-micro-v1:0 - Claude Sonnet 4: us.anthropic.claude-sonnet-4-20250514-v1:0 - Claude Opus 4: us.anthropic.claude-opus-4-20250514-v1:0 - **リージョン**: us-east-1, us-east-2, us-west-2 での利用可能性 #### IAM 権限設定 ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["bedrock:InvokeModel"], "Resource": "arn:aws:bedrock:*::foundation-model/anthropic.claude-opus-4-20250514-v1:0" } ] } ``` #### AWS CLI プロファイル設定 ```ini # ~/.aws/credentials [your-profile] aws_access_key_id = YOUR_ACCESS_KEY aws_secret_access_key = YOUR_SECRET_KEY # ~/.aws/config [profile your-profile] region = us-east-1 ``` ### パフォーマンス要件 #### レスポンス時間 - **目標**: 5 秒以内 - **測定方法**: API 呼び出し開始から MCP レスポンス返却まで - **タイムアウト**: 30 秒でタイムアウト処理 #### スループット - **同時接続**: 1 接続(Kiro IDE からの単一セッション) - **リクエスト頻度**: 制限なし(AWS Bedrock の制限に従う) ### セキュリティ要件 #### 認証情報管理 - AWS プロファイルまたは環境変数のみ使用 - 認証情報の平文ログ出力禁止 - IAM 最小権限の原則に従う #### ネットワークセキュリティ - HTTPS 通信のみ(AWS Bedrock API) - ローカル実行(外部からのアクセス不要) ## 参考ドキュメント ### AWS 公式ドキュメント - [Amazon Nova Models in Amazon Bedrock](https://aws.amazon.com/bedrock/nova/) - Amazon Nova Micro モデル ID と利用可能リージョンの確認 - [Introducing Claude 4 in Amazon Bedrock - AWS News Blog](https://aws.amazon.com/blogs/aws/claude-opus-4-anthropics-most-powerful-model-for-coding-is-now-in-amazon-bedrock/) - Claude Sonnet 4 / Opus 4 モデル ID と利用可能リージョンの確認 - [InvokeModel - Amazon Bedrock API Reference](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModel.html) - Bedrock API の基本仕様 - [Bedrock Converse API](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_Converse.html) - 推奨される統一 API インターフェース ### MCP プロトコル仕様 - [MCP Release Notes - Speakeasy](https://www.speakeasy.com/mcp/release-notes) - 2025 年最新仕様(Streamable HTTP、OAuth 2.1 対応) - [Model Context Protocol (MCP) - GeeksforGeeks](https://www.geeksforgeeks.org/artificial-intelligence/model-context-protocol-mcp/) - MCP の基本概念と標準化フレームワーク ### 技術実装参考 - [Model context protocol (MCP) - OpenAI Agents SDK](https://openai.github.io/openai-agents-python/mcp/) - Python SDK の実装例とベストプラクティス 設計文書(design.md) # 設計文書 ## 概要 Claude MCP サーバーは、Kiro IDE と AWS Bedrock の Amazon Nova + Claude の 3 つの AI モデルを橋渡しする軽量なプロキシサーバーです。MCP プロトコルに準拠し、用途別モデル選択によるコスト効率化を実現しながら、シンプルで信頼性の高い会話インターフェースを提供します。 ## アーキテクチャ ### パッケージ構造とコンポーネント関係 ```mermaid graph TB subgraph "プロジェクトルート" A[setup.py パッケージ設定・依存関係] B[requirements.txt Python依存関係定義] end subgraph "claude_opus_mcp パッケージ" D[__init__.py パッケージ初期化・エクスポート] E[__main__.py エントリーポイント・起動制御] F[server.py MCPプロトコル実装] G[bedrock_client.py AWS Bedrock API クライアント] H[config.py 設定管理・環境変数処理] I[tool_handlers.py ツール実行ロジック] J[exceptions.py カスタム例外定義] end A --> D A -.-> B E --> F F --> I I --> G G --> H F --> H G --> J I --> J style D fill:#64b5f6,stroke:#1976d2,color:#000 style E fill:#4caf50,stroke:#2e7d32,color:#000 style F fill:#ff9800,stroke:#f57c00,color:#000 style G fill:#9c27b0,stroke:#7b1fa2,color:#fff style H fill:#00bcd4,stroke:#0097a7,color:#000 ``` ### 実装レベルでのデータフロー ```mermaid sequenceDiagram participant U as Kiro ユーザー participant K as Kiro MCP クライアント participant S as server.py participant T as tool_handlers.py participant B as bedrock_client.py participant C as config.py participant A as AWS Bedrock API U->>K: チャット入力 K->>S: MCP call_tool(name, arguments) S->>S: ツール名検証 S->>T: handle_chat_xxx(arguments) T->>C: get_model_by_purpose(purpose) C-->>T: model_id T->>B: chat_with_model(message, model_id, temperature) B->>C: get_aws_session() C-->>B: boto3.Session B->>B: _build_request_body_for_model() B->>A: invoke_model(modelId, body) A-->>B: API Response B->>B: _parse_response_for_model() B-->>T: response_text T-->>S: TextContent(text=response_text) S-->>K: MCP Response K-->>U: AI応答表示 ``` ### システム全体アーキテクチャ ```mermaid graph TB subgraph "Kiro IDE 環境" A[Kiro IDE ユーザー] B[MCP クライアント] C[mcp.json 設定] end subgraph "ローカル MCP サーバー" D[chat_mcp] E[MCP プロトコル ハンドラー] F[Bedrock クライアント] G[設定管理] H[エラーハンドラー] end subgraph "AWS クラウド" I[AWS Bedrock API] J[Amazon Nova Micro 超低コスト] K[Claude Sonnet 4 バランス型] L[Claude Opus 4 最高性能] end subgraph "認証・設定" M[AWS プロファイル] N[環境変数] end A --> B B --> D C --> B D --> E E --> F F --> I I --> J I --> K I --> L J --> I K --> I L --> I I --> F F --> E E --> D D --> B B --> A M --> D N --> D J --> G K --> G L --> G G --> F D --> H style D fill:#ff9800,stroke:#f57c00,color:#000 style F fill:#9c27b0,stroke:#7b1fa2,color:#fff style I fill:#00bcd4,stroke:#0097a7,color:#000 style J fill:#4caf50,stroke:#2e7d32,color:#000 ``` ### コンポーネント設計 #### 1. MCP サーバーコア (server.py) **責務:** - MCP プロトコルの実装 - ツール登録とリクエスト処理 - エラーハンドリングとレスポンス管理 **主要メソッド:** ```python async def main() -> None: """MCP サーバーのメインエントリーポイント""" async def list_tools() -> List[Tool]: """利用可能なツールのリストを返す""" async def call_tool(name: str, arguments: dict) -> ToolResult: """指定されたツールを実行する""" ``` #### 2. Bedrock クライアント (bedrock_client.py) **責務:** - AWS Bedrock API との通信 - 3 つの AI モデル(Amazon Nova Micro, Claude Sonnet 4, Claude Opus 4)の呼び出し - 用途別モデル選択ロジック - レスポンスの解析と変換 **主要メソッド:** ```python async def chat_with_model(message: str, model_id: str, temperature: float = 0.7) -> str: """指定されたAIモデルとの会話を実行""" def _build_request_body(message: str, temperature: float) -> dict: """Bedrock API リクエストボディを構築""" def _parse_response(response: dict) -> str: """Bedrock API レスポンスを解析""" ``` #### 3. 設定管理 (config.py) **責務:** - 環境変数と AWS プロファイルの管理 - 設定値の検証とデフォルト値の提供 - 認証情報の安全な取得 **設定項目:** ```python @dataclass class Config: aws_region: str = "us-east-1" aws_profile: Optional[str] = None nova_micro_model_id: str = "amazon.nova-micro-v1:0" claude_sonnet_model_id: str = "us.anthropic.claude-sonnet-4-20250514-v1:0" claude_opus_model_id: str = "us.anthropic.claude-opus-4-20250514-v1:0" max_tokens: int = 4000 timeout_seconds: int = 30 def get_model_by_purpose(self, purpose: str) -> str: """用途に応じたモデル ID を取得""" model_mapping = { 'casual': self.nova_micro_model_id, # 軽量会話 'professional': self.claude_sonnet_model_id, # 技術的会話 'expert': self.claude_opus_model_id # 高度な設計 } return model_mapping.get(purpose, self.claude_sonnet_model_id) ``` ## データモデル ### MCP ツール定義 ```json { "name": "chat_casual", "description": "日常会話や簡単な質問に答える(Amazon Nova Micro使用・超低コスト)", "inputSchema": { "type": "object", "properties": { "message": { "type": "string", "description": "Claude に送信するメッセージ", "minLength": 1, "maxLength": 10000 }, "temperature": { "type": "number", "description": "応答の創造性を制御 (0.0-1.0)", "minimum": 0.0, "maximum": 1.0, "default": 0.7 } }, "required": ["message"] } } ``` ### Bedrock API リクエスト形式 ```json { "anthropic_version": "bedrock-2023-05-31", "max_tokens": 4000, "temperature": 0.7, "messages": [ { "role": "user", "content": "ユーザーメッセージ" } ] } ``` ### MCP レスポンス形式 ```json { "content": [ { "type": "text", "text": "Claude からの応答テキスト" } ], "isError": false } ``` ## インターフェース設計 ### 1. MCP プロトコル インターフェース #### ツール登録 ```python @app.list_tools() async def list_tools(): return [ { "name": "chat_casual", "description": "日常会話や簡単な質問に答える(Amazon Nova Micro使用・超低コスト)", "inputSchema": TOOL_SCHEMA_CASUAL }, { "name": "chat_professional", "description": "技術的な質問や詳細な説明が必要な会話(Claude Sonnet 4使用・バランス型)", "inputSchema": TOOL_SCHEMA_PROFESSIONAL }, { "name": "chat_expert", "description": "複雑な設計、アーキテクチャ、実装に関する高度な相談(Claude Opus 4使用・最高性能)", "inputSchema": TOOL_SCHEMA_EXPERT } ] ``` #### ツール実行 ```python @app.call_tool() async def call_tool(name: str, arguments: dict): if name == "chat_with_claude_opus": return await handle_chat_request(arguments) else: raise ValueError(f"Unknown tool: {name}") ``` ### 2. AWS Bedrock インターフェース #### API 呼び出し ```python async def invoke_bedrock_model( client: BedrockRuntimeClient, model_id: str, request_body: dict ) -> dict: """Bedrock モデルを呼び出す""" response = await client.invoke_model( modelId=model_id, body=json.dumps(request_body) ) return json.loads(response['body'].read()) ``` ## エラーハンドリング設計 ### エラー分類と処理戦略 ```mermaid flowchart TD A[エラー発生] --> B{エラー種別} B -->|ClientError| C[AWS API エラー] B -->|ValidationError| D[入力検証エラー] B -->|TimeoutError| E[タイムアウトエラー] B -->|Exception| F[予期しないエラー] C --> G{エラーコード判定} G -->|AccessDenied| H[認証・権限エラー] G -->|ModelNotFound| I[モデルアクセスエラー] G -->|ThrottlingException| J[レート制限エラー] G -->|その他| K[一般的な API エラー] D --> L[入力値エラーメッセージ] E --> M[タイムアウトエラーメッセージ] F --> N[システムエラーメッセージ] H --> O[ユーザー向けエラーレスポンス] I --> O J --> O K --> O L --> O M --> O N --> O O --> P[ログ出力] P --> Q[MCP エラーレスポンス返却] style A fill:#ff5722,stroke:#d32f2f,color:#fff style O fill:#ff9800,stroke:#f57c00,color:#000 style Q fill:#64b5f6,stroke:#1976d2,color:#000 ``` ### エラーメッセージマッピング ```python ERROR_MESSAGES = { "AccessDenied": "AWS 認証に失敗しました。認証情報と AWS プロファイル設定を確認してください。", "ModelNotFound": "AIモデルアクセスが拒否されました。AWS Bedrock コンソールでモデルアクセス(Amazon Nova Micro, Claude Sonnet 4, Claude Opus 4)を有効にしてください。", "ThrottlingException": "リクエスト制限に達しました。しばらく待ってから再試行してください。", "ValidationException": "入力パラメータが無効です。メッセージ内容を確認してください。", "TimeoutError": "リクエストがタイムアウトしました。ネットワーク接続を確認してください。", "NetworkError": "ネットワーク接続に失敗しました。インターネット接続を確認してください。" } ``` ## セキュリティ設計 ### 認証情報管理 #### AWS 認証フロー ```mermaid sequenceDiagram participant S as MCP サーバー participant C as Config participant A as AWS SDK participant P as AWS プロファイル participant E as 環境変数 S->>C: 設定初期化 C->>C: MCP_AWS_PROFILE 確認 alt プロファイル指定あり C->>P: プロファイル読み込み P->>A: 認証情報設定 else プロファイル指定なし C->>E: 環境変数確認 E->>A: デフォルト認証情報 end A->>S: 認証済み Bedrock クライアント ``` #### セキュリティ原則 1. **最小権限の原則** - `bedrock:InvokeModel` 権限のみ要求 - 特定モデルへのアクセスに限定 2. **認証情報の保護** - 平文での認証情報ログ出力禁止 - メモリ内での認証情報の適切な管理 3. **入力検証** - JSON スキーマによる厳密な入力検証 - SQL インジェクション等の攻撃対策 ## パフォーマンス設計 ### レスポンス時間最適化 #### 目標値 - **通常応答**: 3 秒以内 - **最大応答**: 5 秒以内 - **タイムアウト**: 30 秒 #### 最適化戦略 1. **非同期処理** ```python async def chat_with_claude(self, message: str, temperature: float) -> str: """非同期での Bedrock API 呼び出し""" async with self.session.post(url, json=body, timeout=30) as response: return await self._parse_response(response) ``` 2. **接続プール** ```python # HTTP セッションの再利用 self.session = aiohttp.ClientSession( timeout=aiohttp.ClientTimeout(total=30), connector=aiohttp.TCPConnector(limit=10) ) ``` 3. **エラー時の早期リターン** ```python # 入力検証での早期エラー検出 if len(message) > MAX_MESSAGE_LENGTH: raise ValidationError("メッセージが長すぎます") ``` ## 監視・ログ設計 ### ログレベル定義 ```python import logging # 本番環境: INFO レベル # 開発環境: DEBUG レベル logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) ``` ### ログ出力項目 1. **リクエストログ** - タイムスタンプ - ツール名 - メッセージ長 - temperature 値 2. **レスポンスログ** - 処理時間 - レスポンス長 - 成功/失敗ステータス 3. **エラーログ** - エラー種別 - エラーメッセージ - スタックトレース(DEBUG 時のみ) ## テスト戦略 ### テストレベル #### 1. 単体テスト - 各コンポーネントの独立テスト - モック使用による外部依存の排除 #### 2. 統合テスト - MCP プロトコルの動作確認 - AWS Bedrock API との実際の通信テスト #### 3. エンドツーエンドテスト - Kiro IDE での実際の動作確認 - エラーシナリオの検証 ### テスト環境 ```python # テスト用の設定 TEST_CONFIG = { "aws_region": "us-east-1", "claude_model_id": "anthropic.claude-sonnet-4-20250514-v1:0", # コスト効率重視 "max_tokens": 100, # テスト用に短縮 "timeout_seconds": 10 } # 本番確認用の設定 PRODUCTION_TEST_CONFIG = { "aws_region": "us-east-1", "claude_model_id": "anthropic.claude-opus-4-20250514-v1:0", # 最終確認のみ "max_tokens": 4000, "timeout_seconds": 30 } ``` ## デプロイメント設計 ### パッケージ構造 ``` claude_opus_mcp/ ├── __init__.py ├── __main__.py # python -m エントリーポイント ├── server.py # MCP サーバー実装 ├── bedrock_client.py # AWS Bedrock クライアント ├── config.py # 設定管理 ├── tool_handlers.py # ツールハンドラー実装 └── exceptions.py # カスタム例外 ``` ### インストール要件 ```txt # requirements.txt mcp>=1.0.0 boto3>=1.34.0 aiohttp>=3.8.0 pydantic>=2.0.0 python-dotenv>=1.0.0 ``` ### Kiro 統合設定 ```json { "mcpServers": { "chat-mcp": { "command": "python", "args": ["-m", "chat_mcp"], "env": { "MCP_AWS_PROFILE": "sts", "MCP_AWS_REGION": "us-east-1", "MCP_USE_TEST_MODEL": "true", "MCP_LOG_LEVEL": "INFO" }, "disabled": false, "autoApprove": ["chat_casual", "chat_professional", "chat_expert"], "disabledTools": [] } } } ``` ## 参考ドキュメント ### AWS 公式ドキュメント - [Amazon Nova Models in Amazon Bedrock](https://aws.amazon.com/bedrock/nova/) - Amazon Nova Micro の技術仕様とコスト効率 - [Introducing Claude 4 in Amazon Bedrock - AWS News Blog](https://aws.amazon.com/blogs/aws/claude-opus-4-anthropics-most-powerful-model-for-coding-is-now-in-amazon-bedrock/) - Claude Sonnet 4 / Opus 4 の技術仕様とベストプラクティス - [InvokeModel - Amazon Bedrock API Reference](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModel.html) - Bedrock API の詳細仕様とパラメータ - [Bedrock Converse API](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_Converse.html) - 推奨される統一 API インターフェース(将来対応) ### MCP プロトコル仕様 - [MCP Release Notes - Speakeasy](https://www.speakeasy.com/mcp/release-notes) - 2025 年最新仕様(Streamable HTTP、OAuth 2.1 対応) - [Model Context Protocol (MCP) - GeeksforGeeks](https://www.geeksforgeeks.org/artificial-intelligence/model-context-protocol-mcp/) - MCP アーキテクチャの基本概念 ### 技術実装参考 - [Model context protocol (MCP) - OpenAI Agents SDK](https://openai.github.io/openai-agents-python/mcp/) - Python SDK の実装パターンとベストプラクティス ### セキュリティ・認証 - [AWS IAM Best Practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) - 最小権限の原則と認証情報管理 - [AWS SDK for Python (Boto3) Configuration](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html) - AWS 認証情報の設定方法 実装タスク一覧(tasks.md) # 実装計画 - [x] 1. プロジェクト構造とコア設定の作成 - プロジェクトディレクトリ構造を作成する - requirements.txt と setup.py を作成する - 基本的な **init**.py ファイルを作成する - _要件: 要件 4(Python ベストプラクティス)_ - [x] 2. 設定管理システムの実装 - [x] 2.1 Config クラスの実装 - Pydantic を使用した設定クラスを作成する - AWS プロファイル、リージョン、モデル ID の管理を実装する - テスト用モデル切り替え機能を実装する - _要件: 要件 6(テスト要件とコスト最適化)_ - [x] 2.2 環境変数とプロファイル管理 - MCP_AWS_PROFILE、MCP_AWS_REGION の環境変数サポートを実装する - AWS プロファイルの自動検出機能を実装する - デフォルト設定の適用ロジックを実装する - _要件: 要件 3(Kiro IDE 統合)、要件 5(セキュリティ)_ - [x] 3. AWS Bedrock クライアントの実装 - [x] 3.1 BedrockClient クラスの基本実装 - boto3 を使用した Bedrock クライアントを作成する - 認証情報の安全な管理を実装する - 基本的な接続テストメソッドを実装する - _要件: 要件 5(セキュリティと認証情報管理)_ - [x] 3.2 Claude との会話機能実装 - chat_with_claude メソッドを実装する - Bedrock API リクエストボディの構築を実装する - API レスポンスの解析と変換を実装する - temperature パラメータの処理を実装する - _要件: 要件 1(Claude Opus 4 との会話機能)_ - [x] 3.3 エラーハンドリングの実装 - AWS API エラーの分類と処理を実装する - ユーザーフレンドリーなエラーメッセージの生成を実装する - ログ出力機能を実装する - タイムアウト処理を実装する - _要件: 要件 2(エラーハンドリング)_ - [x] 4. MCP サーバーコアの実装 - [x] 4.1 MCP プロトコルハンドラーの実装 - MCP Server クラスの基本構造を作成する - プロトコルハンドシェイクを実装する - ツール登録機能を実装する - _要件: 要件 4(MCP プロトコル標準準拠)_ - [x] 4.2 chat_with_claude_opus ツールの実装 - ツールの JSON スキーマ定義を実装する - 入力パラメータの検証を実装する - BedrockClient との連携を実装する - MCP レスポンス形式での結果返却を実装する - _要件: 要件 1(Claude Opus 4 との会話機能)_ - [x] 4.3 メインエントリーポイントの実装 - **main**.py でのサーバー起動処理を実装する - 設定の初期化とバリデーションを実装する - 適切な終了処理を実装する - _要件: 要件 4(Python ベストプラクティス)_ - [x] 5. テストスイートの実装 - [x] 5.1 単体テストの作成 - Config クラスのテストを作成する - BedrockClient のモックテストを作成する - エラーハンドリングのテストを作成する - _要件: 要件 6(テスト要件)_ - [x] 5.2 統合テストの作成 - Claude Sonnet 4 を使用した実際の API テストを作成する - MCP プロトコルの動作テストを作成する - エンドツーエンドの会話テストを作成する - _要件: 要件 6(コスト最適化テスト)_ - [x] 5.3 本番確認テストの作成 - Claude Opus 4 を使用した最終確認テストを作成する - パフォーマンステスト(5 秒以内レスポンス)を作成する - _要件: 要件 1(パフォーマンス要件)_ - [x] 6. パッケージングとドキュメント - [x] 6.1 パッケージ設定の完成 - setup.py の詳細設定を完成させる - requirements.txt の最終調整を行う - .env.example ファイルを作成する - _要件: 要件 4(保守可能性)_ - [x] 6.2 ドキュメントの作成(オプション) - README.md を作成する - インストール手順を記述する - Kiro 統合手順を記述する - トラブルシューティングガイドを作成する - _要件: 要件 3(Kiro IDE 統合)_ - **注記**: 実用的には完成済み。共有・公開時に必要に応じて作成 - [x] 7. Kiro IDE 統合テスト - [x] 7.1 ローカル統合テスト - mcp.json 設定ファイルを作成する - Kiro でのサーバー認識テストを実行する - autoApprove 機能のテストを実行する - _要件: 要件 3(Kiro IDE 統合とセットアップ)_ - [x] 7.2 実際の会話テスト - Kiro から Claude Sonnet 4 との会話テストを実行する - エラーケースの動作確認を実行する - パフォーマンス測定を実行する - _要件: 要件 1(Claude Opus 4 との会話機能)、要件 2(エラーハンドリング)_ - [x] 7.3 本番モデル確認 - Claude Opus 4 での最終動作確認を実行する - 高度な推論タスクでの動作確認を実行する - _要件: 要件 6(本番確認テスト)_ - [x] 8. 実運用での問題解決と機能拡張 - [x] 8.1 MCP プロトコル互換性の修正 - CallToolResult から List[TextContent] への戻り値形式変更 - GitHub Issue #987 の調査結果に基づく修正実装 - MCP プロトコル API 変更への対応 - _要件: 要件 4(MCP プロトコル標準準拠)_ - [x] 8.2 多モデル対応機能の実装 - Amazon Nova Micro モデルの追加実装 - Claude Sonnet 4 との使い分け機能実装 - 用途別モデル選択機能(casual/professional/expert) - コスト効率化のためのモデル切り替え実装 - _要件: 要件 6(コスト最適化)_ - [x] 8.3 AWS リソース管理機能の実装 - IAM ユーザー管理機能の追加 - EC2、S3、Lambda 情報取得機能の追加 - AWS セッション管理の改善 - 統合的な AWS 操作ツールの実装 - _要件: 要件 5(セキュリティと認証情報管理)_ - [x] 8.4 機能の簡素化とリファクタリング - ツール数を 10 個から 3 個(chat 系のみ)に削減 - サーバー名を claude-opus-mcp から claude-mcp に短縮 - ツールハンドラーの分離とモジュール化 - コードの保守性向上 - _要件: 要件 4(保守可能性)_ - [x] 9. 最終動作確認とコスト分析 - [x] 9.1 3 モデル会話テスト - Claude Opus 4 での高度な技術相談テスト - Claude Sonnet 4 での専門的会話テスト - Amazon Nova Micro での軽量会話テスト - 各モデルの応答品質とコスト効率の確認 - _要件: 要件 1(Claude Opus 4 との会話機能)、要件 6(コスト最適化)_ - [x] 9.2 実際のコスト測定 - 3 回のラリー会話でのコスト計算(約 5 円) - Nova Micro での軽量会話コスト測定(約 0.005 円) - モデル別コスト比較分析 - コスト効率の実証 - _要件: 要件 6(コスト最適化)_ MCPサーバーのコード関連 GitHub - wd902/claude-mcp-server: 用途別AIモデル使い分け対応のMCPサーバー - AWS Bedrock統合 用途別AIモデル使い分け対応のMCPサーバー - AWS Bedrock統合. Contribute to wd902/claude-mcp-server development by creating an account on GitH... github.com その他 MCPサーバー設定(mcp.json) { "mcpServers": {   "chat-mcp": {     "command": "python",     "args": [       "-m",       "claude_opus_mcp"     ],     "env": {       "MCP_AWS_PROFILE": "sts",       "MCP_AWS_REGION": "us-east-1",       "MCP_USE_TEST_MODEL": "false",       "MCP_MAX_TOKENS": "2000",       "MCP_TIMEOUT_SECONDS": "60"     },     "disabled": false,     "autoApprove": [       "chat_casual",       "chat_professional",       "chat_expert"     ],     "disabledTools": [       "chat_expert",       "chat_professional"     ]   } } } 補足すると、上記の場合、chat_casualだけ使えるようになっています。 chat_casual : Amazon Nova Micro(超低コスト) chat_professional : Claude Sonnet 4(バランス型) chat_expert : Claude Opus 4(最高性能)   背景 Kiro について調べていると 実装力に課題がある という声が多く見受けられました。 そこで、 Claude Opus 4 の実装力を Kiro に統合 できないかと考えたことが今回のきっかけです。 用途に応じて 3 つの AI モデルを使い分け できるようにした理由は、Claude Opus 4 は費用が高いため、気軽にテストできないためです。 開発プロセス Kiro の Spec モードだけで完結 しました。外部ツールは一切使用していません。 開発の流れ : 事前準備 – Vibe モードで実現性を確認し、Spec 用の要件を整理 Spec 作成 – 要件を自然言語で記述 設計 – Spec から自動的にアーキテクチャを生成 実装 – Spec に基づいて Kiro が自動実装 テスト – Kiro 内で動作確認 短時間で完成できた理由 : 事前の実現性確認: Vibe モードで技術的な実現可能性を事前検証 Spec の構造化アプローチ : 仕様駆動開発を最大限に活用 Kiro の自動実装 : 手動コーディングを大幅削減 統合開発環境 : 外部ツールの切り替え時間ゼロ もちろん一発で開発できたわけではありません。 Kiro と一緒にトライアンドエラーを繰り返して完成させました。 結果 この MCP サーバーにより、 Kiro における開発体験が大きく変わる可能性 があります。 外部ツールに切り替えることなく、Kiro 内で直接 Claude Opus 4 に相談できるため、開発の流れが中断されにくくなると考えられます。 特に以下のような場面で効果が期待できます: 複雑なアルゴリズムの実装 : Claude Opus 4 の高い推論能力を活用した段階的な問題解決 設計の相談 : 継続的な対話による設計案の洗練 技術的な疑問の解決 : 即座に専門的な知識にアクセス可能 これにより、従来は時間がかかっていた問題解決プロセスがスムーズになり、開発効率の向上につながると期待されます。 人によっては、費用がAWSの請求に計上されるという点もメリットかと思います。 感想 MCPサーバーを作ることよりも、実装した内容とドキュメントの整合性を合わせる作業が大変でした…。 それくらいに Kiro の Specモード はサクサクとMCPサーバーを開発してくれました。 途中、何度かエラーに見舞われましたが、なんとか解決することができました。 一方で、Specモード に限らず Kiro の気になる点がいくつかありました。 例えば、Workingの文字が表示されず動いているのかどうなのか分からない状態になることが何度かありました。 その場合には、「動いていますか?」と投げかけると動き出してくれました。 また、Kiro とのやりとりが長く続くと新規チャットを開くように促されるので開くのですが、Kiro は以前のセッションのことを忘れてしまっていました。 上記の点は改善されると嬉しいです。 ちなみに、当記事のたたき台は Kiro に作ってもらいました。 まとめ Kiro の Specモード で、たった 5 時間ほどで実用的な MCP サーバーが完成 しました。 これにより: Kiro の実装力を大幅に強化 必要な時にだけ最高性能を活用 Kiro 内で完結する開発環境 が実現できたかと思います。 Kiro に興味を持った方は、ぜひ  Kiro 公式サイト  をチェックしてみてください。 参考記事 KiroとAmazon Q CLIでゲームを作成した結果を比較してみた KiroとAmazon Q CLIでどのように簡単なゲーム開発で違いが出るのかを試してみました! blog.usize-tech.com 2025.09.05 KiroでTerraformコードのテストをする 先日AWSからリリースされたKiroは、AIが仕様書やタスクリストを作成しながら実装を行ってくれる「仕様駆動開発」が特徴です。Terraformのテストコードの作成とテストを実施しようと思います。 blog.usize-tech.com 2025.08.25 Hey Kiro, Spotifyのプレイリストで打線組んで。 AWSが発表した次世代エージェント型IDE「Kiro」を実際に触ってみて、Webアプリケーションを構築してみた体験記となります。 blog.usize-tech.com 2025.08.14
アバター
こんにちは、広野です。 IDE を AWS Cloud9 から code-server に切り替えている最中に長時間ハマったことがありまして。同じ事象でハマった人のために備忘録を残しておこうと思います。 環境 React 19.1.1 Vite 7.1.6 IDE は code-server アプリで使用するポートは 8080 とする 事象 code-server 上で React アプリを Vite で npm run dev したときに code-server の ポートフォワード URL が機能しない (404 エラーが出まくる) 何を言おうとしているかと言うと。スクリーンショットで示します。   まずは、npm run dev します。 これで、code-server の OS 上 (localhost) で、8080 番ポートでアプリが起動しました。しかし、code-server への直接アクセスはこの環境では 443 ポートでしかアクセスできません。※環境によります。 この状況を回避するために、code-server はポートフォワードする機能を持っています。npm run dev をすると、自動で自身の公開用 FQDN に /proxy/ローカル起動アプリのポート番号/ のパスを付けて公開してくれます。 例えば、code-server の URL が https://codeserver.example.com だったとすると、ローカル起動アプリ (8080) の URL は以下になります。 https://codeserver.example.com /proxy/8080/  → http://localhost:8080 に転送! これ自体は大変ありがたい機能なのですが、実際にこの URL にアクセスすると大量に 404 not found エラーが発生します。 おそらくですが、ビルドしたアプリが認識しているパスと、自動付加された /proxy/8080/ との間で整合性が取れていないものと思われます。この問題が無かったとしても、この機能を使用する前提としてアプリコードの中で使用するパスは相対パスである必要があります。相対パスにしていたとしてもこのエラーは発生します。   解決策 vite.config.js に base の設定を追加する。 追加する base の値は /absproxy/ポート番号/ 変更前 の vite.config.js は以下でした。 import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [react()], server: { port: 8080, allowedHosts: true } }); 変更後 は、 base を追加します。 import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ base: '/absproxy/8080/', plugins: [react()], server: { port: 8080, allowedHosts: true } }); この状態で npm run dev を実行すると。 http://localhost:8080 の後に /absproxy/8080/ のパスが追加され、ポートフォワードされるようになりました!発生していたエラーも無くなりました。 ただし。 アクセス先のパスは以下のようになります。 https://codeserver.example.com /proxy/8080/absproxy/8080/ /proxy/8080/ と /absproxy/8080/ が二重になりますが、これで正しいようです。気持ち悪いですが。 base を環境変数にする場合、一例ですが以下のように vite.config.js を書くことができます。code-server 上のローカル起動でなければ base は “/” にしておき、code-server のときは “/absproxy/8080/” を入れておけばよいです。 import { defineConfig, loadEnv } from 'vite'; import react from '@vitejs/plugin-react'; const env = loadEnv('development', process.cwd(), 'VITE_'); export default defineConfig({ base: env.VITE_BASE, plugins: [react()], server: { port: 8080, allowedHosts: true } }); 今回のケースですと .env ファイルには以下のように書いておきます。 VITE_BASE=/absproxy/8080/   終わってみると大したことないのですが、本当にハマってました。   まとめ いかがでしたでしょうか? 他にもスマートなやり方はあったのかもしれませんが。さんざん苦労した挙句、見つけた方法でした。 本記事が皆様のお役に立てれば幸いです。 雑談 CORS ってほんと迷惑ですね・・・。本記事のテーマとは異なりますが。 セキュリティのために必要なのは理解するんですけど、もう少し設定の柔軟さは用意しといて欲しかったです。ワイルドカード設定の柔軟性を。全体 * でいいや!って開き直りたいんですけど、そこまで強心臓になりきれず。* だと会社のセキュリティ監査で必ず引っ掛かるし・・・。
アバター
皆さんこんにちは。 秋といったら焼き芋。いとさんです。 さて今回Lambda関数のコードをインポート・エクスポートする方法をご紹介いたします。 はじめに コードの作成時にメモ帳などのテキストエディタを利用し、コピー&ペーストによるコード移行を行う際、まれにコンテキストエラーが発生する場合があります。このようなエラーは、意図しない文字列の変換や改行コードの違い、隠れた文字やフォーマットの不一致などが原因となることがあり、正常に動作していたコードが突如としてエラーを引き起こすリスクとなります。 このような現象を確実に回避するためには、テストが正常に完了した関数やプログラムを、Zipファイルなどのアーカイブ形式でエクスポートし、必要な環境へインポートする方法が非常に有効です。ファイル単位でのエクスポート・インポートを行うことで、元のコードの構造や文字コード、フォーマットが保全され、手動でのコピペ作業による予期せぬエラーの発生を防止しましょう。   ファンクションコード.zipファイルとAWS SAMファイルの違い ダウンロード形式には『AWS SAMファイル』『ファンクションコード.zipファイル』の2種類があります。 AWS SAMファイルは「どういうサーバーレスアプリをAWS上で動かしたいか」をひとまとめに記述する 設計図 です。 コード(zip)本体ではなく、“どんなリソースを、どんな繋がり・設定で”作るかを管理するファイルです AWS CLI(コマンドラインツール)を使いSAMコマンドを実行すると中身がCloudFormationテンプレートとしてAWSに送信され自動でAWS本番/テスト環境を構築・更新することが出来ます。 (コード例) # この AWS SAM テンプレートは、関数の設定から生成されました。関数に 1 つ以上のトリガーがある場合は、これらのトリガーに関連付けられている AWS # リソースがこのテンプレートで完全に指定されておらず、プレースホルダ値も含まれていないことに注意してください。AWS Infrastructure # Composer またはお気に入りの IDE でこのテンプレートを開き、他の AWS リソースでサーバーレスアプリケーションを指定するように変更します。 AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: An AWS Serverless Application Model template describing your function. Resources: Testlambdafunction: Type: AWS::Serverless::Function Properties: CodeUri: . Description: '' MemorySize: 128 Timeout: 3 Handler: lambda_function.lambda_handler Runtime: python3.13 Architectures: - x86_64 EphemeralStorage: Size: 512 EventInvokeConfig: MaximumEventAgeInSeconds: 21600 MaximumRetryAttempts: 2 PackageType: Zip Policies: - Statement: [] RecursiveLoop: Terminate SnapStart: ApplyOn: None RuntimeManagementConfig: UpdateRuntimeOn: Auto   今回はコードのみを移行する方法として、zipファイルでのダウンロードを行います。   やってみよう それでは早速やってみましょう。 使用したいLambda関数に移動しファンクションコード.zipをダウンロードを選択します。 ファンクションコード.zipファイルは実行プログラムを、zip形式でまとめた圧縮ファイルであり中身はLambda関数として稼働するコードとなっています。 他のLambdaで再利用・バックアップ・ローカル編集用として使用できます。 今回エクスポートしたzipファイルの中身はこのようになっております。 テキストエディタやVScodeで確認ができるので自分の使用したい関数が出ているか確認しましょう。 import boto3 import json import re import os ses = boto3.client('ses') FROM = os.environ['FROM_ADDRESS'] # SES認証済みアドレス TO = [os.environ['TO_ADDRESS']] # 宛先アドレス(複数可) def lambda_handler(event, context): message = event['Records'][0]['Sns']['Message'] # 特定のリンクを除去(例:全リンク) sanitized_message = re.sub(r'https?://[^\s]+', '[リンク削除]', message) response = ses.send_email( Source=FROM, Destination={'ToAddresses': TO}, Message={ 'Subject': {'Data': '[SecurityHub] 検出通知', 'Charset': 'UTF-8'}, 'Body': {'Text': {'Data': sanitized_message, 'Charset': 'UTF-8'}} } ) return { 'statusCode': 200, 'body': json.dumps('Email sent') }  zipファイルがダウンロードされますのでこれをLambda関数でインポートします。 インポートしたいLambda関数に移動しアップロード元>zipファイルを選択します。 アップロードを押下し使用したいzipファイルを選択します。 これでLambda関数のコードをインポート・エクスポートが完了しました。   最後に 検証環境と本番環境といった異なる環境間で同じコードを使用する場合は、このZipファイルによるパッケージング・移行機能の活用が非常に重要です。こうした工夫を取り入れることで、環境ごとの差異に起因する不具合を未然に防ぎ、安定した運用体制を構築することができます。 コードの移行や環境を跨いだ運用に際しては、是非この方法を取り入れ、より安全かつ効率的な開発・検証を実現しましょう。
アバター
こんにちは。SCSK渡辺(大)です。 今年は秋刀魚が非常に美味しいですね。 水揚げ量が昨年の2倍らしいので、まだまだ楽しめそうです。 何をつくったのか Kiroに自然言語で依頼するだけでAWSリソース一覧を取得することができる環境 をつくりました。 サンプル:実行画面   完了するとMarkdown形式のテキストファイルが出来上がります。   サンプル:IAMユーザーの一覧 Kiroへの依頼は「IAMユーザーの一覧を取得して」というだけです。 注意事項を教えてくれました。 サンプル:EC2インスタンスの一覧(全リージョン) Kiroへの依頼は「全リージョンのEC2インスタンスの一覧を取得して」というだけです。 リージョンのアクセス制限まで結果として出力してくれました。 テーブル形式で出力するようsteeringで指定しているのですが上手くいきませんでした。 内容は整理されていますね。 こちらも注意事項を教えてくれました。 サンプル:特定タグが付いたリソースの一覧 Kiroへの依頼は「[key]=[value]タグのリソース一覧を取得して」というだけです。 プロジェクト分析してくれました。   嬉しいポイント ほぼ自然言語で設定できるのでノンエンジニアの人でも安心 本機能を利用するためにAWS上でシステム環境を構築する必要がない AWSCLIのコマンドリファレンスの内容が変わっても対応できる やったこと Kiroで以下を設定しました。 Agent Steering Trusted commands MCP Servers その他、以下も設定しました。 listHistoryフォルダの作成 AWSCLIのcredentialsファイルを設定 Kiroの各種設定 Agent Steering KiroでTerraformコードのテストをする 先日AWSからリリースされたKiroは、AIが仕様書やタスクリストを作成しながら実装を行ってくれる「仕様駆動開発」が特徴です。Terraformのテストコードの作成とテストを実施しようと思います。 blog.usize-tech.com 2025.08.25 STS一時認証情報を1コマンドでcredentialsファイルに保存する AWSアカウントポリシーで多要素認証が強制される場合、アクセスキーとシークレットキーのみではAWS CLIを使用することができず、MFAによる認証を経て一時的なセッションキーを取得する必要があります。それらの情報を取得しcredentialsファイルに簡単に保存するpythonスクリプトをご紹介します。 blog.usize-tech.com 2022.05.09 ファイル名は任意です。 私は「instructions.md」にしました。 「–profile sts」を付けるように指示している理由は 参考記事 をご参照ください。 --- inclusion: always --- # AWS CLI 利用ガイドライン ## 1. 概要 AWS を使用した開発プロジェクト全般に適用するガイドライン。 ## 2. 操作規則 ### 2.1 基本設定 | 項目         | 設定値                          | 説明                                             | | ------------ | ------------------------------- | ------------------------------------------------ | | プロファイル | `--profile sts`                 | MFA 生成用プロファイル(固定)                   | | リージョン   | `--region <region>`             | 必須パラメータ(グローバルサービスは us-east-1) | | 出力形式     | `--no-cli-pager --output table` | リストコマンド用                                 | ### 2.2 コマンド履歴管理 **保存場所**: `listHistory/` ディレクトリ **ファイル名形式**: `YYYYMMDDHHMMSS_service-resource_region.md`(日時は'echo %date% %time%'で取得する) **構成**: サマリー → 実行コマンド → 出力結果(AWS CLI 出力は必ずテーブル形式のまま保存) **重要**: AWS CLI の`--output table`で取得した結果は、テーブル形式のまま履歴ファイルに記録すること **履歴ファイル記録ルール**: 1. 実行したコマンドをそのまま記録 2. AWS CLI のテーブル出力結果を整形せずそのままコピー 3. サマリーは別途作成するが、元の出力も必ず保持 4. 注意すべきことなどのコメントを付ける ### 2.3 実行前検証プロセス **必須**: AWS CLI コマンド実行前に以下を **必ず順番通りに** 実行する: #### ステップ 1: コマンド調査(必須) - **ツール**: `mcp_tavily_remote_mcp_tavily_search` - **目的**: 最新のコマンド情報、ベストプラクティス、既知の問題を確認 - **実行例**: `"AWS CLI iam list-users command latest syntax examples"` #### ステップ 2: 構文確認(必須) - **ツール**: `mcp_awslabs_aws_documentation_mcp_server_search_documentation` → `mcp_awslabs_aws_documentation_mcp_server_read_documentation` - **目的**: AWS 公式ドキュメントで正確な構文とパラメータを検証 - **確認項目**: 必須パラメータ、オプションパラメータ、出力形式 #### ステップ 3: パラメータ検証(必須) - **確認項目**: - 必須パラメータの有無 - リージョン要件(IAM はグローバルサービス = us-east-1) - プロファイル設定(`--profile sts`) - 出力形式(`--output table --no-cli-pager`) #### ステップ 4: 影響範囲確認(必須) - **確認項目**: - 対象リソースの範囲 - 実行に必要な権限 #### ステップ 5: 実行許可(必須) - **条件**: 上記ステップ 1-4 が全て完了した場合のみ実行 - **実行形式**: `aws <service> <operation> --profile sts --region <region> --output table --no-cli-pager` **重要**: この検証プロセスを省略した場合、コマンド実行は禁止 2.2でテーブル形式で記録するよう依頼しているのですが上手くいかないことがあります。 2.3のステップ5で実行形式を指定していても稀に違う形式でKiroが実行しようとします。その場合はKiroが実行しようとしたコマンドをユーザーが手動でTrustしてあげてください。 Trusted commands 設定>Trusted Commands から登録するよりも、Ctr+Shift+P(Windows)を押して「>基本設定: ユーザー設定を開く (JSON)」と入力して開き、”kiroAgent.trustedCommands”に以下を追加するほうが早いです。 すべてのコマンドを網羅できていない可能性がありますので、必要に応じて追加してご利用ください。 "kiroAgent.trustedCommands": [   "cd *",   "ls",   "dir",   "pwd",   "cat *",   "type *",   "echo *",   "aws ec2 describe-instances *",   "aws ec2 describe-vpcs *",   "aws ec2 describe-subnets *",   "aws ec2 describe-security-groups *",   "aws ec2 describe-key-pairs *",   "aws ec2 describe-images *",   "aws ec2 describe-regions *",   "aws ec2 describe-snapshots *",   "aws ec2 describe-volumes *",   "aws ec2 list-images *",   "aws ec2 get-console-output *",   "aws s3 ls *",   "aws s3 head-object *",   "aws s3 get-object-attributes *",   "aws s3api list-buckets *",   "aws s3api head-bucket *",   "aws s3api get-bucket-location *",   "aws s3api get-bucket-region *",   "aws s3api get-bucket-versioning *",   "aws s3api get-bucket-encryption *",   "aws s3api get-bucket-cors *",   "aws s3api get-bucket-lifecycle-configuration *",   "aws s3api get-bucket-policy *",   "aws s3api get-bucket-policy-status *",   "aws s3api get-bucket-acl *",   "aws s3api get-bucket-website *",   "aws s3api get-bucket-logging *",   "aws s3api get-bucket-notification-configuration *",   "aws s3api get-bucket-replication *",   "aws s3api get-bucket-request-payment *",   "aws s3api get-bucket-tagging *",   "aws s3api get-bucket-accelerate-configuration *",   "aws s3api get-bucket-analytics-configuration *",   "aws s3api get-bucket-inventory-configuration *",   "aws s3api get-bucket-metrics-configuration *",   "aws s3api get-bucket-ownership-controls *",   "aws s3api get-bucket-intelligent-tiering-configuration *",   "aws s3api get-public-access-block *",   "aws s3api get-account-public-access-block *",   "aws s3api list-objects *",   "aws s3api list-objects-v2 *",   "aws s3api list-object-versions *",   "aws s3api list-multipart-uploads *",   "aws s3api list-parts *",   "aws s3api head-object *",   "aws s3api get-object-attributes *",   "aws s3api get-object-acl *",   "aws s3api get-object-legal-hold *",   "aws s3api get-object-lock-configuration *",   "aws s3api get-object-retention *",   "aws s3api get-object-tagging *",   "aws s3api presign *",   "aws s3api list-bucket-analytics-configurations *",   "aws s3api list-bucket-inventory-configurations *",   "aws s3api list-bucket-metrics-configurations *",   "aws s3api list-bucket-intelligent-tiering-configurations *",   "aws lambda list-functions *",   "aws lambda get-function *",   "aws lambda get-function-configuration *",   "aws iam list-users *",   "aws iam list-roles *",   "aws iam list-policies *",   "aws iam get-user *",   "aws iam get-role *",   "aws iam get-policy *",   "aws rds describe-db-instances *",   "aws rds describe-db-clusters *",   "aws rds describe-db-snapshots *",   "aws cloudformation list-stacks *",   "aws cloudformation describe-stacks *",   "aws cloudformation describe-stack-resources *",   "aws logs describe-log-groups *",   "aws logs describe-log-streams *",   "aws dynamodb list-tables *",   "aws dynamodb describe-table *",   "aws apigateway get-rest-apis *",   "aws apigateway get-resources *",   "aws sns list-topics *",   "aws sqs list-queues *",   "aws route53 list-hosted-zones *",   "aws cloudwatch list-metrics *",   "aws cloudwatch describe-alarms *",   "aws sts get-caller-identity *",   "aws resourcegroupstaggingapi get-resources *",   "aws resourcegroupstaggingapi get-tag-keys *",   "aws resourcegroupstaggingapi get-tag-values *",   "aws elbv2 describe-load-balancers *",   "aws elbv2 describe-target-groups *",   "aws autoscaling describe-auto-scaling-groups *",   "aws ssm describe-parameters *",   "aws ssm get-parameter *",   "aws ssm get-parameters *",   "aws secretsmanager list-secrets *",   "aws secretsmanager describe-secret *",   "aws kms list-keys *",   "aws kms describe-key *",   "aws cloudtrail describe-trails *",   "aws config describe-configuration-recorders *",   "aws organizations list-accounts *",   "aws organizations describe-organization *",   "aws support describe-cases *",   "aws pricing get-products *",   "aws ce get-cost-and-usage *",   "aws budgets describe-budgets *"   ], 「IAMで参照権限だけにして、Trusted commands は aws * だけ設定すれば良いのでは?」とも考えたのですが、それだとIAMに想定外の権限が付与されてしまっていた場合に、想定外のリソース操作が行われてしまうので採用しませんでした。Trusted commandsで参照系のコマンドだけを設定しておけば、IAMで参照権限以外の権限が付与されていても、Kiroが実行しようとしたコマンドをユーザーが手動でTrustしない限りは、想定外のリソース操作が行われることはないはずです。 MCP Servers Amazon Q Developer ちゃんと征くツール開発 Amazon Q Developer を使い始めて、使い始める前の想像以上に「できる」と感じました。皆様にもオススメできるようなAI支援ツールになっているので、ぜひ使っていただきたいな、との思いを込めて、今回はその楽しいやり取りをご紹介します。 blog.usize-tech.com 2025.08.30 面倒な仕事はMCPにやらせよう 〜AIはどこまで仕事ができるのか?〜 MCP(Model Context Protocol)は、AIと仕事の関係をどう変えるのか?架空の会社の業務シナリオを通じて、AIが複数のツールを連携させて複雑なタスクを自動化する過程を実証。具体的な設定方法や課題、未来の展望までを解説します。 blog.usize-tech.com 2025.08.20 Amazon Q Developer CLIにAWS MCP Serversを使ってもらいゲーム作り向け資料を作成してみた 「Amazon Q CLI でゲームを作ろうキャンペーンの報告と最新情報 update & Kiro のご紹介」というイベントにオンラインから参加した後、AWSを利用することが楽しくなるゲームが欲しくなりました。 blog.usize-tech.com 2025.08.18 tavily-mcp はAPIキーの取得が必要です。 環境変数で渡すほうが安全です。 { "mcpServers": {   "aws-knowledge-mcp-server": {     "command": "uvx",     "args": [       "mcp-proxy",       "--transport",       "streamablehttp",       "https://knowledge-mcp.global.api.aws"     ],     "env": {       "FASTMCP_LOG_LEVEL": "ERROR",       "AWS_PROFILE": "default",       "AWS_REGION": "us-east-1",     },     "disabled": false,     "autoApprove": ["aws___search_documentation", "aws___read_documentation"]   },   "tavily-remote-mcp": {     "command": "npx",     "args": [       "-y",       "mcp-remote",       "https://mcp.tavily.com/mcp/?tavilyApiKey=[取得したAPIキー]"     ],     "disabled": false,     "autoApprove": ["tavily_search", "tavily_extract"]   } } } 関連記事 KiroとAmazon Q CLIでゲームを作成した結果を比較してみた KiroとAmazon Q CLIでどのように簡単なゲーム開発で違いが出るのかを試してみました! blog.usize-tech.com 2025.09.05 Hey Kiro, Spotifyのプレイリストで打線組んで。 AWSが発表した次世代エージェント型IDE「Kiro」を実際に触ってみて、Webアプリケーションを構築してみた体験記となります。 blog.usize-tech.com 2025.08.14 感想 本記事の内容はKiroにプログラミングを組んでもらったというわけではないので、AWSが意図した使い方になっているのか分かりませんが、ソフトウェア開発以外の使い道があるのは良いですね。 いつかKiroがAgent Hooksなどでスケジュール起動できるようになったら、本記事の内容を1時間おきに実行させるようにすることで、ほぼリアルタイムで最新の一覧が取得できるようになりますね。夢が広がります。
アバター
こんにちは、広野です。 AWS Cloud9 に代わる、使い勝手の良い IDE on AWS を作れないものか、、、日々模索しています。 今回は、 code-server を HTTPS 公開して MFA 認証を付ける構成の実装編として AWS CloudFormation テンプレートを紹介します。 前回の記事 背景やアーキテクチャ説明については、前回記事をご覧ください。   code-server を nginx で HTTPS 化して Amazon Cognito で MFA 認証をさせる - アーキクチャ編 code-server を HTTPS 公開して MFA 認証を付ける構成を試してみました。本記事ではアーキテクチャを紹介します。 blog.usize-tech.com 2025.09.16   アーキテクチャ 前回記事からの再掲で、図を載せておきます。   AWS CloudFormation テンプレート テンプレートは大きく 2 つに分かれています。 ユーザー共通で使用する Amazon Cognito ユーザープール 【既存ユーザープールも条件付きで使用可】 ユーザー単位で作成する Amazon EC2 インスタンス、他 以下は本テンプレートを使用する際に前提として必要となるリソースです。 Amazon Route 53 パブリックホストゾーン: 証明書作成やレコード登録に必要 Amazon VPC: 既存のものを使用する想定、パブリックサブネットが必要 Amazon SES ID および 設定セット: Amazon SES で Amazon Cognito からの通知メールを送るために必要 本記事のテンプレートを加工すれば 既存の Amazon Cognito ユーザープールを使用可能ですが、メールアドレスを属性として持っていること、Amazon Cognito マネージドログインのドメイン設定ができていることが前提となります。Amazon Cognito ID プールは不要です。 Amazon SES に関する説明は以下の記事をご覧ください。   Amazon SES の送信ログを取得・通知する [AWS CloudFormation 利用] Amazon SES の送信ログを保存・通知する仕組みを AWS CloudFormation で簡単に作れるようにしました。 blog.usize-tech.com 2024.12.20   AWS CloudFormation テンプレートの記述に関する補足は # コメントでインラインで追加します。 【ユーザー共通】Amazon Cognito ユーザープール 他の記事でも紹介していますが、より簡略化した設定になっています。セルフサインアップ可能なメールアドレスをドメイン名で制限するための AWS Lambda 関数を組み込んでいます。 AWSTemplateFormatVersion: 2010-09-09 Description: The CloudFormation template that creates a Cognito user pool with Managed Login, self-signup by email, and forced MFA. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SystemName: Type: String Description: System name. use lower case only. (e.g. example) Default: example MaxLength: 10 MinLength: 1 SubName: Type: String Description: System sub name. use lower case only. (e.g. prod or dev) Default: dev MaxLength: 10 MinLength: 1 SesId: Type: String Description: Amazon SES ID for sending emails. (email addreess or domain) Default: xxxx.xxx MaxLength: 100 MinLength: 5 SesConfigurationSet: Type: String Description: Amazon SES configuration set for sending emails. Default: xxxxxxxxxxxxxxxx MaxLength: 100 MinLength: 5 CognitoReplyTo: Type: String Description: Cognito Reply-to email address. (e.g. xxx@xxx.xxx) Default: xxxxx@xxx.xxx AllowedPattern: "[^\\s@]+@[^\\s@]+\\.[^\\s@]+" CognitoEmailFrom: Type: String Description: Cognito e-mail from address. (e.g. xxx@xxx.xxx) Default: xxxxx@xxx.xxx AllowedPattern: "[^\\s@]+@[^\\s@]+\\.[^\\s@]+" AllowedUserEmailDomains: Description: Domain list to allow user sign up. Each domains must be comma delimited and double quoted. Type: String Default: '"xxx.xxx"' Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: "General Configuration" Parameters: - SystemName - SubName - Label: default: "Email Configuration" Parameters: - SesId - SesConfigurationSet - CognitoReplyTo - CognitoEmailFrom - Label: default: "Security Configuration" Parameters: - AllowedUserEmailDomains Resources: # ------------------------------------------------------------# # Lambda (triggered from Cognito) Role (IAM) # ------------------------------------------------------------# LambdaTriggeredFromCognitoRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${SystemName}-LambdaTriggeredFromCognitoRole-${SubName} Description: This role grants Lambda functions triggered from Cognito basic priviledges. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess - arn:aws:iam::aws:policy/AmazonCognitoPowerUser # ------------------------------------------------------------# # Cognito Lambda Invocation Permission # ------------------------------------------------------------# CognitoLambdaInvocationPermissionPresignup: Type: AWS::Lambda::Permission Properties: FunctionName: !GetAtt LambdaCognitoPresignup.Arn Action: lambda:InvokeFunction Principal: cognito-idp.amazonaws.com SourceAccount: !Sub ${AWS::AccountId} SourceArn: !GetAtt UserPool.Arn DependsOn: - LambdaCognitoPresignup - UserPool CognitoLambdaInvocationPermissionPostconfirm: Type: AWS::Lambda::Permission Properties: FunctionName: !GetAtt LambdaCognitoPostconfirm.Arn Action: lambda:InvokeFunction Principal: cognito-idp.amazonaws.com SourceAccount: !Sub ${AWS::AccountId} SourceArn: !GetAtt UserPool.Arn DependsOn: - LambdaCognitoPostconfirm - UserPool # ------------------------------------------------------------# # Cognito # ------------------------------------------------------------# UserPool: Type: AWS::Cognito::UserPool Properties: UserPoolName: !Sub ${SystemName}-${SubName} MfaConfiguration: "ON" EnabledMfas: - SOFTWARE_TOKEN_MFA Policies: PasswordPolicy: MinimumLength: 8 RequireUppercase: true RequireLowercase: true RequireNumbers: true RequireSymbols: false TemporaryPasswordValidityDays: 180 AccountRecoverySetting: RecoveryMechanisms: - Name: verified_email Priority: 1 AdminCreateUserConfig: AllowAdminCreateUserOnly: false AutoVerifiedAttributes: - email DeviceConfiguration: ChallengeRequiredOnNewDevice: false DeviceOnlyRememberedOnUserPrompt: false EmailConfiguration: ConfigurationSet: !Ref SesConfigurationSet EmailSendingAccount: DEVELOPER From: !Sub "${SystemName}-${SubName} admin <${CognitoEmailFrom}>" ReplyToEmailAddress: !Ref CognitoReplyTo SourceArn: !Sub arn:aws:ses:${AWS::Region}:${AWS::AccountId}:identity/${SesId} EmailVerificationMessage: !Sub "${SystemName}-${SubName} Verification code: {####}" EmailVerificationSubject: !Sub "${SystemName}-${SubName} Verification code" LambdaConfig: PreSignUp: !GetAtt LambdaCognitoPresignup.Arn PostConfirmation: !GetAtt LambdaCognitoPostconfirm.Arn UsernameAttributes: - email UsernameConfiguration: CaseSensitive: false UserPoolAddOns: AdvancedSecurityMode: "OFF" UserPoolTags: Cost: !Sub ${SystemName}-${SubName} # この UserPoolDomain 設定は、Amazon Cognito マネージドログインを使用するために必要です。 # Version 2 つまりマネージドログインを使用する設定にしています。 # Version 1 だと旧型の hosted UI になります。 UserPoolDomain: Type: AWS::Cognito::UserPoolDomain Properties: Domain: !Sub ${SystemName}-${SubName} ManagedLoginVersion: 2 UserPoolId: !Ref UserPool UserPoolGroupBasic: Type: AWS::Cognito::UserPoolGroup Properties: Description: The User Group for standard users. GroupName: BASIC Precedence: 101 UserPoolId: !Ref UserPool # ------------------------------------------------------------# # Lambda # ------------------------------------------------------------# LambdaCognitoPresignup: Type: AWS::Lambda::Function Properties: FunctionName: !Sub ${SystemName}-CognitoPresignup-${SubName} Description: !Sub Lambda Function triggered from Cognito before user self signup to check the user's email domain for ${SystemName}-${SubName} Runtime: python3.13 Timeout: 3 MemorySize: 128 Role: !GetAtt LambdaTriggeredFromCognitoRole.Arn Handler: index.lambda_handler Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} Code: ZipFile: !Sub | import re def lambda_handler(event, context): try: print(event) triggersource = event['triggerSource'] email = event['request']['userAttributes']['email'] print(email) if triggersource == 'PreSignUp_SignUp': print('via self signup') domain = email.split('@')[1] allowedDomains = [ ${AllowedUserEmailDomains} ] if domain in allowedDomains: print('allowed domain and email account') return event else: print('prohibited domain') return None else: print('via admin console') return event except Exception as e: print(str(e)) DependsOn: LambdaTriggeredFromCognitoRole LambdaCognitoPostconfirm: Type: AWS::Lambda::Function Properties: FunctionName: !Sub ${SystemName}-CognitoPostconfirm-${SubName} Description: !Sub Lambda Function triggered from Cognito after user confirmation to add the user in BASIC group for ${SystemName}-${SubName} Runtime: python3.13 Timeout: 3 MemorySize: 128 Role: !GetAtt LambdaTriggeredFromCognitoRole.Arn Handler: index.lambda_handler Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} Code: ZipFile: !Sub | import boto3 client = boto3.client('cognito-idp', '${AWS::Region}') def lambda_handler(event, context): USERPOOLID = event['userPoolId'] USERNAME = event['userName'] try: print(event) res = client.admin_add_user_to_group( UserPoolId=USERPOOLID, Username=USERNAME, GroupName='BASIC' ) return event except Exception as e: print(str(e)) DependsOn: LambdaTriggeredFromCognitoRole # ------------------------------------------------------------# # Output Parameters この出力は次のテンプレートで使用します。 # ------------------------------------------------------------# Outputs: # Cognito CognitoUserPoolId: Value: !Ref UserPool Export: Name: !Sub CognitoUserPoolId-${SystemName}-${SubName} CognitoUserPoolArn: Value: !GetAtt UserPool.Arn Export: Name: !Sub CognitoUserPoolArn-${SystemName}-${SubName} CognitoUserPoolProviderName: Value: !GetAtt UserPool.ProviderName Export: Name: !Sub CognitoUserPoolProviderName-${SystemName}-${SubName} CognitoUserPoolProviderUrl: Value: !GetAtt UserPool.ProviderURL Export: Name: !Sub CognitoUserPoolProviderUrl-${SystemName}-${SubName}   【ユーザー単位】Amazon EC2 インスタンス、他付属リソース ユーザー単位で Amazon EC2 インスタンスを作成するとともに、その EC2 インスタンス専用の Amazon Cognito ユーザープール「アプリケーションクライアント」を作成します。アプリケーションクライアントは上述のテンプレートで作成した Amazon Cognito ユーザープールに関連付けます。ここで作成したアプリケーションクライアントにはクライアントシークレットを作成しており、その Amazon EC2 インスタンスしか知りません。(まあ、マネジメントコンソールを見てしまえばわかるんですが、外部の人が簡単にわかるものではない) それを知ろうとするために、Amazon Cognito ユーザープールを参照可能な IAM ロール権限を付与しています。 Amazon EC2 インスタンスには Elastic IP アドレスを割り当て、それを指定した Amazon Route 53 パブリックホストゾーンに A レコード登録します。FQDN に合わせた SSL 証明書を Let’s Encrypt で作成します。Let’s Encrypt に証明書を作成依頼するときの認証方法は DNS-01 という方式を選定しています。これは Amazon Route 53 パブリックホストゾーンに登録した認証用レコードを Let’s Encrypt のシステム側が確認することでドメインの所有者確認をする方法です。そのため、この EC2 インスタンスの IAM ロールにレコード登録可能な権限を付与しています。 などなど、いろいろと複合技を仕掛けています。内容が盛り沢山で既に私もおなかいっぱいです。 テンプレート内にインラインの説明コメントが多くなると思いますが、ご容赦ください。 AWSTemplateFormatVersion: "2010-09-09" Description: The CloudFormation template that creates an Amazon Linux 2023 x86_64 EC2 instance with code-server and Cognito authentication. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SystemName: Type: String Description: System name. use lower case only. (e.g. example) Default: example MaxLength: 10 MinLength: 1 SubName: Type: String Description: System sub name. use lower case only. (e.g. prod or dev) Default: dev MaxLength: 10 MinLength: 1 DomainName: Type: String Description: Domain name for URL. xxxxx.xxx Default: example.com AllowedPattern: "^(?!-)(?:[a-zA-Z0-9-]{0,62}[a-zA-Z0-9])(?:\\.(?!-)(?:[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]))*$" # VPC やパブリックサブネットは既存のものを選択してください。 VpcId: Type: AWS::EC2::VPC::Id Description: Choose a existing VPC ID you deploy the EC2 instance in. InstanceSubnet: Type: AWS::EC2::Subnet::Id Description: Choose an existing Public Subnet ID you deploy the EC2 instance in. # EC2 インスタンスタイプは適宜変更してください。節約のため t3a にしているだけです。medium でもやや重いと思います。 InstanceType: Type: String Description: EC2 instance type (AMD/t3a) Default: t3a.medium AllowedValues: - t3a.medium - t3a.large - t3a.xlarge # EBS のサイズも適宜変更してください。 InstanceVolumeSize: Type: Number Description: The volume size in GB Default: 20 # アクセスを許可するソースグローバル IP アドレスのサブネットを指定してください。 AllowedSubnet: Type: String Description: Allowed source IPv4 subnet and subnet mask. (e.g. xxx.xxx.xxx.xxx/32) Default: 111.111.111.111/32 AllowedPattern: "^((25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})\\.){3}(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})\\/([0-9]|[1-2][0-9]|3[0-2])$" TimeZone: Type: String Description: The specified time zone. Default: Asia/Tokyo AllowedPattern: "^(Africa|America|Antarctica|Arctic|Asia|Atlantic|Australia|Europe|Indian|Pacific)/[A-Za-z0-9_/-]+$" Route53HostZoneId: Type: String Description: Route 53 public host zone ID for the SSL certificate. Default: XXXXXXXXXXXXXXXXXXXX MaxLength: 30 MinLength: 1 YourId: Type: String Description: The individual instance id (or number) specified from the administrator. Default: client01 MaxLength: 20 MinLength: 1 # ここで指定したメールアドレスで Amazon Cognito ユーザーを作成する必要があります。 YourEmail: Type: String Description: Your email address for the access control. Default: xxx@xxx.xxx AllowedPattern: "[^\\s@]+@[^\\s@]+\\.[^\\s@]+" # OAuth2 Proxy のバージョンを入れてください。7.12.0 で動作確認済みですが、 # バージョンが変わるとコマンド仕様が変わる恐れがあります。 Oauth2ProxyVersion: Type: String Description: oauth2-proxy version. Default: 7.12.0 MaxLength: 10 MinLength: 4 Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: "General Configuration" Parameters: - SystemName - SubName - YourId - YourEmail - Label: default: "Domain Configuration" Parameters: - DomainName - Route53HostZoneId - Label: default: "Network Configuration" Parameters: - VpcId - InstanceSubnet - AllowedSubnet - Oauth2ProxyVersion - Label: default: "EC2 Configuration" Parameters: - InstanceType - InstanceVolumeSize - Label: default: "OS Configuration" Parameters: - TimeZone Resources: # ------------------------------------------------------------# # EC2 Launch template # ------------------------------------------------------------# EC2LaunchTemplate: Type: AWS::EC2::LaunchTemplate Properties: LaunchTemplateName: !Sub codeserver-${SystemName}-${SubName}-${YourId} LaunchTemplateData: InstanceType: !Ref InstanceType # 使用する AMI は Amazon Linux 2023 x86_64 の最新版なのですが、スタックを変更するときに # 新しい AMI ID がリリースされていると EC2 インスタンスを再作成してしまうので注意が必要です。 # 正直この指定は良くないと思っていますが楽さに負けて使ってしまいます。 ImageId: >- {{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64}} BlockDeviceMappings: - Ebs: VolumeSize: !Ref InstanceVolumeSize VolumeType: gp3 DeleteOnTermination: true Encrypted: true DeviceName: /dev/xvda NetworkInterfaces: - SubnetId: !Ref InstanceSubnet Groups: - !Ref Ec2SecurityGroup DeviceIndex: 0 AssociatePublicIpAddress: true MetadataOptions: HttpTokens: required Monitoring: Enabled: true TagSpecifications: - ResourceType: volume Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} DependsOn: - Ec2SecurityGroup # ------------------------------------------------------------# # EC2 Security Group # ------------------------------------------------------------# Ec2SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VpcId GroupDescription: Allow HTTPS access from specified subnets SecurityGroupIngress: # セキュリティグループは 443 だけ開けていますが、必要に応じて変更してください。 - Description: Allow HTTPS from the specified client FromPort: 443 IpProtocol: tcp ToPort: 443 CidrIp: !Ref AllowedSubnet SecurityGroupEgress: - Description: Allow all outbound traffic IpProtocol: -1 CidrIp: 0.0.0.0/0 Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} - Key: Name Value: !Sub SG-codeserver-${SystemName}-${SubName}-${YourId} # ------------------------------------------------------------# # EC2 Role / Instance Profile (IAM) # ------------------------------------------------------------# Ec2Role: Type: AWS::IAM::Role Properties: RoleName: !Sub Ec2Role-codeserver-${SystemName}-${SubName}-${YourId} Description: This role allows EC2 instance to invoke S3 and SSM. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: # Session Manager で CUI ログインできるようにしています。トラブルシューティング時に。 - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore # AWS CodeCommit リポジトリにアクセスできるようにしています。 - arn:aws:iam::aws:policy/AWSCodeCommitPowerUser - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy Policies: - PolicyName: !Sub Ec2Policy-codeserver-${SystemName}-${SubName}-${YourId} PolicyDocument: Version: 2012-10-17 Statement: # Amazon Q Developer の権限を付けています。 - Effect: Allow Action: - codewhisperer:GenerateRecommendations Resource: "*" # Amazon Route 53 の必要な権限です。Let's Encrypt の SSL 証明書作成に必要です。 - Effect: Allow Action: - route53:ListHostedZones - route53:GetChange Resource: - "*" - Effect: Allow Action: - route53:ChangeResourceRecordSets Resource: - !Sub arn:aws:route53:::hostedzone/${Route53HostZoneId} # Amazon Cognito ユーザープールアプリケーションクライアントのクライアントシークレット取得用です。 - Effect: Allow Action: - cognito-idp:DescribeUserPoolClient Resource: - Fn::ImportValue: !Sub CognitoUserPoolArn-${SystemName}-${SubName} Ec2InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: InstanceProfileName: !Ref Ec2Role Path: / Roles: - !Ref Ec2Role DependsOn: - Ec2Role # ------------------------------------------------------------# # Elastic IP address for EC2 instance # ------------------------------------------------------------# EipEc2: Type: AWS::EC2::EIP Properties: Domain: vpc Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} - Key: Name Value: !Sub eip-codeserver-${SystemName}-${SubName}-${YourId} # ------------------------------------------------------------# # EIP Association # ------------------------------------------------------------# EIPAssociation: Type: AWS::EC2::EIPAssociation Properties: AllocationId: !GetAtt EipEc2.AllocationId InstanceId: !Ref Ec2Instance DependsOn: - Ec2Instance - EipEc2 # ------------------------------------------------------------# # EC2 # ------------------------------------------------------------# Ec2Instance: Type: AWS::EC2::Instance Properties: IamInstanceProfile: !Ref Ec2InstanceProfile LaunchTemplate: LaunchTemplateId: !Ref EC2LaunchTemplate Version: !GetAtt EC2LaunchTemplate.LatestVersionNumber UserData: Fn::Base64: !Sub - | #!/bin/bash set -euxo pipefail # Locale & timezone timedatectl set-timezone ${TimeZone} # Install packages dnf update -y # とりあえず Git, Node.js, Python をインストールしています。 dnf install -y git nodejs gcc make zlib-devel bzip2-devel xz-devel curl-devel libffi-devel python3.13 python3-pip python3-boto3 python3-pytest # Install code-server export HOME=/home/ec2-user curl -fsSL https://code-server.dev/install.sh | bash mkdir -p /home/ec2-user/.config/code-server mkdir -p /home/ec2-user/.local/share/code-server/User mkdir -p /home/ec2-user/environment chown -R ec2-user:ec2-user /home/ec2-user/.config /home/ec2-user/.local /home/ec2-user/environment # Update code-server config # code-server は 8008 ポートで起動しています。よく使う 80 や 8080 と重複しないようにするため。 # code-server ネイティブの認証は無し(none)にしています。Amazon Cognito を使用するため。 tee /home/ec2-user/.config/code-server/config.yaml << EOF bind-addr: 127.0.0.1:8008 auth: none cert: false EOF chown ec2-user:ec2-user /home/ec2-user/.config/code-server/config.yaml tee /home/ec2-user/.local/share/code-server/User/settings.json << EOF { "extensions.autoUpdate": false, "extensions.autoCheckUpdates": false, "terminal.integrated.cwd": "/home/ec2-user/environment", "telemetry.telemetryLevel": "off", "security.workspace.trust.startupPrompt": "never", "security.workspace.trust.enabled": false, "security.workspace.trust.banner": "never", "security.workspace.trust.emptyWindow": false, "editor.indentSize": "tabSize", "editor.tabSize": 2, "python.testing.pytestEnabled": true, "auto-run-command.rules": [ { "command": "workbench.action.terminal.new" } ] } EOF chown ec2-user:ec2-user /home/ec2-user/.local/share/code-server/User/settings.json # Service start systemctl enable --now code-server@ec2-user # Create SSL cert # Let's Encrypt で SSL 証明書を作成するためのモジュール、Amazon Route 53 対応のものをインストールしています。 dnf install -y certbot python3-certbot-dns-route53 # 証明書を DNS-01 という認証方式で作成するコマンドです。 certbot certonly --dns-route53 -d codeserver-${SystemName}-${SubName}-${YourId}.${DomainName} --agree-tos -m ${YourEmail} --non-interactive --preferred-challenges dns-01 # Install oauth2-proxy curl -L -o /tmp/oauth2-proxy.tar.gz https://github.com/oauth2-proxy/oauth2-proxy/releases/download/v${Oauth2ProxyVersion}/oauth2-proxy-v${Oauth2ProxyVersion}.linux-amd64.tar.gz tar -xzf /tmp/oauth2-proxy.tar.gz -C /tmp cp /tmp/oauth2-proxy-v${Oauth2ProxyVersion}.linux-amd64/oauth2-proxy /usr/local/bin/ chmod +x /usr/local/bin/oauth2-proxy # ここで、Amazon Cognito ユーザープールアプリケーションクライアントのクライアントシークレットを取得します。 CLIENT_SECRET=$(aws cognito-idp describe-user-pool-client \ --user-pool-id ${UserPoolId} \ --client-id ${UserPoolAppClient} \ --region ${AWS::Region} \ --query 'UserPoolClient.ClientSecret' \ --output text) # クッキーシークレットを生成します。 COOKIE_SECRET=$(python3.13 -c 'import os,base64; print(base64.urlsafe_b64encode(os.urandom(32)).decode())') mkdir -p /etc/oauth2-proxy chown ec2-user:ec2-user /etc/oauth2-proxy chmod 700 /etc/oauth2-proxy # 以下は自分のメールアドレス以外ではログインを許可しない設定です。 echo ${YourEmail} > /etc/oauth2-proxy/allowed_emails.txt chmod 600 /etc/oauth2-proxy/allowed_emails.txt chown ec2-user:ec2-user /etc/oauth2-proxy/allowed_emails.txt # 以下は OAuth2 Proxy をサービスとして起動するための設定です。 # Amazon Cognito とやり取りするために、この通り記述する必要があります。 cat <<EOF > /etc/systemd/system/oauth2-proxy.service [Unit] Description=oauth2-proxy After=network.target [Service] Type=simple Environment=CLIENT_SECRET=${!CLIENT_SECRET} Environment=COOKIE_SECRET=${!COOKIE_SECRET} ExecStart=/usr/local/bin/oauth2-proxy \ --provider=oidc \ --oidc-issuer-url=${UserPoolProviderUrl} \ --client-id=${UserPoolAppClient} \ --client-secret=$CLIENT_SECRET \ --redirect-url=https://codeserver-${SystemName}-${SubName}-${YourId}.${DomainName}/oauth2/callback \ --login-url=https://${SystemName}-${SubName}.auth.${AWS::Region}.amazoncognito.com/oauth2/authorize \ --profile-url=https://${SystemName}-${SubName}.auth.${AWS::Region}.amazoncognito.com/oauth2/userInfo \ --redeem-url=https://${SystemName}-${SubName}.auth.${AWS::Region}.amazoncognito.com/oauth2/token \ --scope=openid \ --cookie-secure=true \ --cookie-expire=72h \ --cookie-refresh=1h \ --cookie-secret=$COOKIE_SECRET \ --authenticated-emails-file=/etc/oauth2-proxy/allowed_emails.txt \ --http-address=127.0.0.1:4180 Restart=on-failure User=ec2-user Group=ec2-user [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable --now oauth2-proxy # Install nginx # nginx は code-server を HTTPS 化するためにインストールします。SSL 証明書はここで使われます。 dnf install -y nginx systemctl enable --now nginx mkdir -p /etc/nginx/ssl chmod 700 /etc/nginx/ssl cp /etc/letsencrypt/live/codeserver-${SystemName}-${SubName}-${YourId}.${DomainName}/fullchain.pem /etc/nginx/ssl/nginx-chain.crt cp /etc/letsencrypt/live/codeserver-${SystemName}-${SubName}-${YourId}.${DomainName}/privkey.pem /etc/nginx/ssl/nginx.key chmod 644 /etc/nginx/ssl/nginx-chain.crt chmod 600 /etc/nginx/ssl/nginx.key # nginx が OAuth2 Proxy とやり取りするためにこの通りパスの設定をする必要があります。 # proxy_buffer 系の設定が重要で、これが大きくないとエラーになります。 tee /etc/nginx/conf.d/codeserver.conf << EOF server { listen 443 ssl; server_name codeserver-${SystemName}-${SubName}-${YourId}.${DomainName}; large_client_header_buffers 4 16k; ssl_certificate_key /etc/nginx/ssl/nginx.key; ssl_certificate /etc/nginx/ssl/nginx-chain.crt; location / { auth_request /oauth2/auth; error_page 401 = /oauth2/sign_in; proxy_pass http://127.0.0.1:8008; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; proxy_read_timeout 3600s; proxy_send_timeout 3600s; } location /oauth2/ { proxy_pass http://127.0.0.1:4180; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; proxy_set_header X-Auth-Request-Redirect \$request_uri; proxy_buffers 16 16k; proxy_buffer_size 16k; } location = /oauth2/auth { proxy_pass http://127.0.0.1:4180; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Scheme \$scheme; proxy_set_header Content-Length ""; proxy_pass_request_body off; proxy_buffers 16 16k; proxy_buffer_size 16k; } } EOF systemctl restart nginx # Create cert renew script # 以下は Let's Encrypt の SSL 証明書を更新するためのスクリプトです。ec2-user のホームディレクトリに配置します。 cat << 'EOF' > /home/ec2-user/renew-cert.sh #!/bin/bash set -e sudo certbot renew sudo cp -f /etc/letsencrypt/live/codeserver-${SystemName}-${SubName}-${YourId}.${DomainName}/fullchain.pem /etc/nginx/ssl/nginx-chain.crt sudo cp -f /etc/letsencrypt/live/codeserver-${SystemName}-${SubName}-${YourId}.${DomainName}/privkey.pem /etc/nginx/ssl/nginx.key sudo chmod 644 /etc/nginx/ssl/nginx-chain.crt sudo chmod 600 /etc/nginx/ssl/nginx.key sudo systemctl restart nginx echo "Certificate renewed." EOF chmod +x /home/ec2-user/renew-cert.sh chown ec2-user:ec2-user /home/ec2-user/renew-cert.sh # Create sign out file # 以下はサインアウト用の URL を md ファイルにして code-server のホームディレクトリに配置します。 tee /home/ec2-user/environment/signout.md > /dev/null << EOF [Sign Out](https://${SystemName}-${SubName}.auth.${AWS::Region}.amazoncognito.com/logout?client_id=${UserPoolAppClient}&logout_uri=https%3A%2F%2Fcodeserver-${SystemName}-${SubName}-${YourId}.${DomainName}%2Foauth2%2Fsign_out) EOF chown ec2-user:ec2-user /home/ec2-user/environment/signout.md chmod 644 /home/ec2-user/environment/signout.md # Download Amazon Q Developer CLI # Amazon Q Developer CLI のインストーラをダウンロードしています。 # インストールはサインインが必要なため、ダウンロードにとどめています。 sudo -i -u ec2-user bash << 'EOF' curl --proto '=https' --tlsv1.2 -sSf "https://desktop-release.q.us-east-1.amazonaws.com/latest/q-x86_64-linux.zip" -o "q.zip" unzip q.zip EOF # Install nvm # Node.js のバージョン管理ツール nvm をインストールします。 # インストールは OS 再起動が必要なので最後に入れています。 # 必要なバージョンを nvm install コマンドで手動で入れましょう。 sudo -u ec2-user bash -c "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash" # Finally, reboot reboot - UserPoolProviderUrl: Fn::ImportValue: !Sub CognitoUserPoolProviderUrl-${SystemName}-${SubName} UserPoolId: Fn::ImportValue: !Sub CognitoUserPoolId-${SystemName}-${SubName} Tags: - Key: Cost Value: !Sub ${SystemName}-${SubName} - Key: Name Value: !Sub codeserver-${SystemName}-${SubName}-${YourId} DependsOn: - Ec2InstanceProfile # Route 53 に Elastic IP アドレスの A レコードが登録されないと Let's Encrypt の SSL 証明書作成が # 失敗するので、明示的に DependsOn 設定を入れています。 - Route53RecordA - UserPoolAppClient # ------------------------------------------------------------# # Route 53 # ------------------------------------------------------------# Route53RecordA: Type: AWS::Route53::RecordSet Properties: HostedZoneName: !Sub ${DomainName}. Name: !Sub codeserver-${SystemName}-${SubName}-${YourId}.${DomainName}. Type: A TTL: 300 ResourceRecords: - !GetAtt EipEc2.PublicIp DependsOn: EipEc2 # ------------------------------------------------------------# # Cognito User Pool App Client # ------------------------------------------------------------# UserPoolAppClient: Type: AWS::Cognito::UserPoolClient Properties: UserPoolId: Fn::ImportValue: !Sub CognitoUserPoolId-${SystemName}-${SubName} ClientName: !Sub ${SystemName}-${SubName}-${YourId} GenerateSecret: true RefreshTokenValidity: 3 AccessTokenValidity: 6 IdTokenValidity: 6 ExplicitAuthFlows: - ALLOW_USER_SRP_AUTH - ALLOW_REFRESH_TOKEN_AUTH PreventUserExistenceErrors: ENABLED SupportedIdentityProviders: - COGNITO # Amazon Cognito マネージドログインを使用するには、以下の URL 系の設定が必須です。 # ここの設定は繊細で、EC2 内でコマンド実行している nginx や OAuth2 Proxy の設定ときっちり # 合わせる必要があります。 # 特に LogoutURLs に指定した URL を get パラメータの1つとして完全一致させないと # ログアウト時に使用しないとログアウトに失敗します。 # ここでは意味不明かもしれませんがやってみるとわかります。 # その他、AuthFlow 系の設定も繊細だと思うので、ここに書いてある通りに書いておかないと # 動かなそうな気がします。 CallbackURLs: - !Sub https://codeserver-${SystemName}-${SubName}-${YourId}.${DomainName}/oauth2/callback LogoutURLs: - !Sub https://codeserver-${SystemName}-${SubName}-${YourId}.${DomainName}/oauth2/sign_out DefaultRedirectURI: !Sub https://codeserver-${SystemName}-${SubName}-${YourId}.${DomainName}/oauth2/callback AllowedOAuthFlows: - code AllowedOAuthFlowsUserPoolClient: true AllowedOAuthScopes: - openid - email - profile # Amazon Cognito マネージドログインを使用する場合、以下の設定が必要になります。 # デザインを細かくカスタマイズできそうなのですが、大変なので完全デフォルトにしました。 ManagedLoginBranding: Type: AWS::Cognito::ManagedLoginBranding Properties: ClientId: !Ref UserPoolAppClient ReturnMergedResources: true UseCognitoProvidedValues: true UserPoolId: Fn::ImportValue: !Sub CognitoUserPoolId-${SystemName}-${SubName} # ------------------------------------------------------------# # Output Parameters # ------------------------------------------------------------# Outputs: # EC2 # 完成した code-server の URL です。 codeserverUrl: Value: !Sub "https://codeserver-${SystemName}-${SubName}-${YourId}.${DomainName}/?folder=/home/ec2-user/environment" # ログアウト時にアクセスする URL です。get パラメータがかなり繊細です。 signoutUrl: Value: !Sub "https://${SystemName}-${SubName}.auth.${AWS::Region}.amazoncognito.com/logout?client_id=${UserPoolAppClient}&logout_uri=https%3A%2F%2Fcodeserver-${SystemName}-${SubName}-${YourId}.${DomainName}%2Foauth2%2Fsign_out"   まとめ いかがでしたでしょうか? 今回の題材は code-server でしたが、他の認証機能のない (または弱い) Web アプリケーションによりセキュアな認証機能を付けたいニーズにぴったりはまると思います。 本件は CloudFormation 化するのに苦労しました。しかし、ユーザーデータスクリプトが dnf install でしばしば失敗するのは勘弁して欲しいです。その度に /var/log/cloud-init-output.log を見るはめになります。とりあえず動くものを作りましたが、今後はもっと信頼性の高い仕組みを作りたいです。AMI 化すればいい、では済まない処理もあるので。 さすがにここまでの内容を独力で作れるわけもなく、生成 AI にかなり助けていただきました。例によって AI の回答のままでは動かないことが多かったので各種ツールのリファレンスと見比べながらの作業を強いられましたが、総合的に見て開発、勉強の両面で非常に効率が良かったことに間違いはないでしょう。 一連の動くコマンドや設定はここにありますので、要件に合わせて部分的に活用いただければと思っております。 本記事が皆様のお役に立てれば幸いです。 雑談 Let’s Encrypt はいいですね。AWS Certificate Manager にも証明書をエクスポートできる機能が新たにできましたが、金額が結構高いので Amazon EC2 インスタンスに証明書を組み込むなら Let’s Encrypt 一択かなと思います。更新もスクリプト用意しておけば思ったより楽でしたし。 nginx も便利すぎます。とりあえず HTTPS 化、なら Let’s Encrypt と nginx だけでいいですね。 OAuth2 Proxy は神です。Amazon Cognito マネージドログインとの組み合わせ構成は私の中で標準化されました。w
アバター
こんにちは、SCSKの前田です。 今回は、LifeKeeper for Linux の最新機能を皆さまに知っていただきたく、最新バージョン 9.9.1 のリリースノートに記載されている新機能、バグ修正/機能強化、アップグレードの注意点等をご紹介します。 LifeKeeper for Linux v9.9.1 は本記事公開時点での最新バージョンとなります。 LifeKeeperとは?(おさらい) LifeKeeperは、ビジネスの継続性を支える「高可用性(HA: High Availability)クラスターソフトウェア」です。 サーバーやアプリケーションに障害が発生した際、その影響を最小限に抑え、システムが止まることのないよう自動で復旧・切り替えを行うのが LifeKeeper の主要な役割です。 具体的には、複数のサーバー(ノード)でクラスターを組み、稼働系サーバーで障害が発生した場合、LifeKeeper が検知し、瞬時に待機系サーバーへ処理を移行します。この一連の自動切り替え処理を「フェイルオーバー」と呼びます。 LifeKeeper の強みは、OS やミドルウェア、データベース、アプリケーションといった様々な「保護対象リソース」の状態を監視し、それらをグループ化して切り替え制御を行う点にあります。この柔軟なリソース保護と、複雑な設定なしに利用できる点が、多くの企業に採用される理由です。 リリースノートでは、この LifeKeeper の「保護能力」や「監視精度」、そして「フェイルオーバーの信頼性」をさらに高めるための新機能や改善点、対応環境の拡充などが記載されています。最新バージョンで、より堅牢で効率的なシステム運用を実現するための進化の全貌をぜひご覧ください。 新機能:LifeKeeper/DataKeeper の進化のポイント ここでは、LifeKeeper for Linux v9.9.1 で強化された LifeKeeper Core 及び DRBD Recovery Kit の新機能についてご紹介します。 多岐にわたるOSやVMwareのバージョンサポート追加も含まれますが、本記事では主要な機能強化に焦点を当て、バージョンサポートの詳細は公式リリースノートをご確認いただくようお願いいたします。 1.Linux ASLR 仕様変更への対応:LifeKeeper Core の安定稼働を強化 LifeKeeper for Linux v9.9.1 では、LifeKeeper Core の安定稼働をさらに強化するため、 共有メモリアドレスが変更 されました。 この変更は、Linux カーネルの  Address Space Layout Randomization (ASLR) 機能の仕様変更に対応したものです。ASLRはプロセスのアドレス空間の配置をランダム化することでセキュリティを強化する機能ですが、これにより  LifeKeeper が使用する共有メモリアドレスが OS 管理のアドレスと衝突する可能性 が生じていました。 今回のアップデートでは、LifeKeeper が利用する共有メモリアドレスを「37f00000」から「6ff00000」に変更することで、OS のアドレス空間との衝突リスクを排除。これにより、 LifeKeeper Core の安定した動作を確保し、予期せぬ問題発生の可能性を低減します。 これは、特に最新の Linux 環境における LifeKeeper の 信頼性と堅牢性を向上させる重要な変更点 です。 2.HANA 環境における lksupport の高速化と柔軟なデータ収集 LifeKeeper for Linux v9.9.1 は、 lksupport コマンドの HANAト レースファイル収集機能が改善され、診断データ収集の効率が大幅に向上 しました。 これまでのバージョンでは、HANA リソースが存在する環境において、特に HANA トレースファイルの容量が大きい場合、lksupport コマンドによるデータ収集に時間がかかるという課題がありました。 今回のアップデートでは、lksupport コマンドに 新しいオプションが追加 されました。これにより、以下のことが可能になります。 HANA トレースファイルを収集から除外する :大容量のトレースファイルを除外することで、lksupport の取得時間を大幅に短縮できます。 HANA リソースに関する情報のみを収集する :HANA 関連のトラブルシューティングに特化し、必要な情報だけを効率的に取得できるようになります。 この機能強化により、HANA が稼働する大規模な環境におけるトラブルシューティングや診断作業がより迅速かつスムーズになり、運用効率の向上に貢献します。必要な情報を効率的に取得できるため、分析時間の短縮にも繋がります。 3.DRBD Recovery Kit:4ノードクラスター対応で可用性を拡大 LifeKeeper for Linux v9.9.1 の DRBD Recovery Kit は、 4ノードクラスターのサポートを開始 しました。 DRBD Recovery Kit が初めて導入された LifeKeeper v9.9.0 では3ノードクラスターまでのサポートでしたが、今回のアップデートにより、より大規模な環境での高可用性構成が可能になります。 この拡張により、システム設計の柔軟性が大幅に向上し、 より複雑なシステム要件や高い可用性レベルが求められる環境において、DRBD を用いた堅牢な多ノードクラスターを構築できるようになります。 冗長性をさらに高めたい、あるいは地理的に分散した環境で複数拠点を活用したいといったニーズにも対応しやすくなります。 4.DRBD IP アドレス変更の簡素化:LKCLI でリソース再作成不要に LifeKeeper for Linux v9.9.1では、 DRBD リソースに関連付けられた IP アドレスの変更プロセスが大幅に簡素化 されました。 これまでの LifeKeeper v9.9.0 では、DRBD リソースの IP アドレスを変更する場合、既存の DRBD リソースを一度削除し、再作成する必要がありました。これは設定変更に伴う作業負荷が大きく、ヒューマンエラーのリスクも伴うものでした。 今回の機能強化により、 LKCLI コマンドを使用することで、DRBD リソースを再作成することなく、IP アドレスを直接変更できるようになりました。 この改善は、システム運用における 設定変更作業の工数を削減し、効率性を高めます。また、運用中の設定変更作業に伴うサービス停止のリスクを最小限に抑え、DRBD クラスターの管理をより柔軟かつ安全に行うことを可能にします。 バグ修正・機能強化:システムの安定性と運用性を向上 ここでは、多岐にわたるバグ修正および機能強化について、主な項目を一覧でご紹介します。 LifeKeeper for Linux v9.9.1 No 項目 内容 1 DataKeeperミラーの挙動改善: data_corruptフラグが削除された状態でDataKeeperミラーが強制的にオンラインになった際に、そのメッセージをログに記録するようになりました。 2 lksupportのSAP MaxDBデータ収集強化: lksupportがSAP MaxDB固有のデータをキャプチャできるようになりました。 3 シャットダウン時の予期せぬスイッチオーバー問題を修正: COMM_UPとCOMM_DOWN処理の競合により、シャットダウンストラテジーを”Do Not Switch Over Resources”(デフォルト)に設定していてもLifeKeeper停止時にスイッチオーバーが発生する問題を修正しました。 4 Recovery Kit for EC2:RouteTableリソース作成時の権限緩和: メインルートテーブルへのec2:replaceRoute権限がなくてもRouteTableリソースが作成できるようになりました。 5 Recovery Kit for EC2:メタデータ取得のリトライ機能追加: Recovery Kit for EC2でメタデータの取得に失敗した場合にリトライするようになりました(デフォルトで最大4回試行)。 6 lkcliリソース拡張時の優先順位改善: lkcliリソース拡張時、3番目と4番目のノードに拡張する際のデフォルトの優先順位レベルが改善されました。 7 サーバー ステータス表示のタイプミス修正: Monitoring.cgiのサーバー ステータス出力に含まれるタイプミス(DEADではなくDAED)を修正しました。 8 lksupportのネットワーク情報収集効率化: lksupportが/sys/class/net内のファイルを個別に作成するのではなく、圧縮tarアーカイブとして作成し、lksupportのtarファイルに含めるようになりました。 9 AWS PAYGイメージでのライセンスタイプ表示問題を修正: AWSの9.7.0 PAYG(Pay-as-you-go)イメージで、不明なライセンスタイプが表示される問題を修正しました。 10 lkbackupの使用法およびマニュアルページ更新: lkbackupコマンドの-qオプションが-xオプションからプロンプトを削除することを示す使用法とマニュアルページを更新しました。 11 lkbackupのバグ修正:DRBDリソースファイル: 複数のDRBDリソースファイルがバックアップされないというlkbackupのバグを修正しました。 12 lksupportのDRBDサブシステムファイル収集強化: lksupportが関連するDRBDサブシステムファイルを取得し、drbd.txtに記録するようになりました。 13 DRBDクラスターのレプリケーション再開挙動改善: DRBDクラスター内で複数のサーバーが一時停止されている場合、再開操作によりすべてのサーバー間のレプリケーションが再開されるようになりました。 14 STONITHインストール時のエラーハンドリング強化: LifeKeeperが停止している状態やコミュニケーションパスが作成されていない状態でSTONITHをインストールしようとすると、エラーになるように改修しました。 15 多ノードDRBDクラスターでのリソース復元失敗を修正: 2ノードを超えるクラスターで2つのノードがクラッシュした後、使用可能なノードが1つだけの場合に、DRBDリソースの復元が失敗する問題を修正しました。 16 NFSv4ファイルシステムリソース停止失敗のバグ修正: NFSv4でマウントされたディレクトリ内のファイルが開いたままになっていると、ファイルシステムリソースの停止(アンマウント)に失敗するバグを修正しました。 17 LifeKeeper起動中の停止処理改善: LifeKeeperが起動中に停止する場合、起動処理が完了するまで待つように改修しました。 18 DRBD lkcliサブコマンドの検証機能追加: DRBD lkcliサブコマンド(force、resume、removesys、options、status)が、渡されたタグがDRBDリソース用のものであることを検証しないバグを修正しました。 19 Oracle Recovery Kitの強制起動制御パラメータ追加: 強制起動を実行するかどうかを決定するデフォルトファイル調整パラメーターORA_SAFE_USE_START_FORCEが追加されました(デフォルトでは実行されません)。 スムーズな移行のために:LifeKeeper アップグレード時の重要事項 LifeKeeper関連製品のアップグレードを安全かつ確実に実行していただくため、以下の重要な注意点をご確認ください。 1. Perlバージョンの変更とGeneric ARKへの影響 LifeKeeper for Linux v9.8.0以降では、同梱されるPerlが 5.8.8から5.32.1に大幅にアップデート されています。 LifeKeeper for Linux v9.7.0以前のバージョンからv9.8.0以降にアップデートする場合、 PerlベースのGeneric ARKを使用している環境では、このPerlアップデートが既存のスクリプトに影響を与える可能性があります。 【対応】 アップグレードを実施する前に、ご利用のGeneric ARKが新しいPerlバージョンで正しく動作するか、互換性を十分に検証してください。 詳細は「 Perl 5.8.8からPerl 5.32.1へのアップグレード 」ドキュメントをご参照ください。 2. SAP HANA Application Recovery Kit の変更と移行 LifeKeeper for Linux v9.5.0 より、SIOS は 新しい SAP HANA Application Recovery Kit をリリースしています。 従来の gen/app ベースの SAP HANA Recovery Kit は LifeKeeper v9.5.0 以降ではサポートされていません。 【対応】LifeKeeper for Linux v9.5.0 以降へアップデートを検討されている既存の SAP HANA ユーザーは、必ず新しい(ビルトインの)SAP HANA Application Recovery Kit への移行作業が必要となります。 SIOS は2022年3月31日まで、9.4.xリリースでの従来の gen/app ベースの Recovery Kit のサポートを継続しましたので、現在は新しい SAP HANA Recovery Kit  への移行が必須です。 3. アップグレードパスの制限 LifeKeeper は、 最大2つ前のバージョン (例:9.7.x)から現在のバージョン(9.9.1)への 直接アップデートが可能 です。 これよりも古いバージョンからアップデートする場合は、以下のいずれかの対応が必要です。 ・ 旧バージョンのアンインストールと新規インストール : 最も確実な方法ですが、システム構築の手間がかかります。 ・ 段階的なアップデート : 古いバージョンを一度サポート対象のバージョン(例:9.7.x)に一時的にアップデートし、その後、現在のバージョン(9.9.1)へ再度アップデートすることで対応可能です。 【例】古いバージョンが 9.5.x の場合、まず 9.7.x にアップデートし、その後に 9.9.1 にアップデートします。 4. lkbackup 利用時の注意点 アップグレード中に lkbackup を使用する場合、リソースの作成後に lkbackup からリストアを行うと、破損したイクイバレンシが残される可能性があります。 これは、lkbackup がバックアップ後に初めて作成されたリソースの設定ファイルを適切に把握できないためです。 【対応】 ・ 新規リソース追加前 : 新しいリソースを初めて追加する前に lkbackup からリストアしてください。 ・ 新規リソース追加後 : lkbackup の後に新しいリソースを追加した場合は、リストアを行う前にそのリソースを削除するか、リソース階層のインスタンスを削除し、リストア後に再度階層を拡張してください。 【推奨】 特定のリソースを初めて作成する際に lkbackup を実行することを強く推奨します。 5. クラスター内の LifeKeeper バージョンの互換性 同じクラスター内のすべてのシステムには、同じバージョンおよびリリースのLifeKeeperをインストールする必要があります。 通常、バージョンまたはリリースの異なるLifeKeeperには互換性がありません。 【重要】 ローリングアップデートなどの特別な手順を除き、異なるバージョンまたはリリースの LifeKeeper がクラスター内の異なるシステムで実行されている状況では、LifeKeeper を起動しないでください。システムの不安定化や予期せぬ挙動を引き起こす可能性があります。 【アップグレードの注意点】本番環境と同等環境での徹底した事前検証を強く推奨 LifeKeeper の新バージョンがもたらす革新的な機能と強化された安定性は、システムの可用性をさらに向上させる大きな機会です。しかし、その恩恵を最大限に享受し、スムーズな移行を実現するためには、周到な準備と慎重な計画が不可欠です。 特にアップグレードの実施にあたっては、 本番環境と同一、または極めて近似した環境での事前検証を強く推奨いたします。 これまでの多くの導入経験から、簡易的な検証環境やPoC環境では表面化しなかった問題が、本番環境特有の複雑な構成、データ量、実際のワークロード、あるいは連携する他システムとの相互作用によって、予期せぬ形で露呈するケースが確認されています。 例えば、以下のような本番環境固有の要素が、アップグレード後の動作に影響を及ぼす可能性があります。 ・OS/カーネルの細かな設定やパッチレベルの差異 ・ネットワークインターフェース(NIC)の構成やドライババージョン ・ディスクI/Oの特性やストレージ連携 ・Firewallやセキュリティポリシー ・LifeKeeper以外のミドルウェア(DB、アプリケーション等)とのバージョン互換性 ・ネットワークレイテンシや帯域幅の制約 これらの要素は、疑似環境やPoC環境では再現が難しく、本番環境にデプロイされて初めて問題が顕在化することが少なくありません。 そのため、単なる新機能の動作確認に留まらず、 本番環境で想定される高負荷時におけるLifeKeeperの挙動、フェイルオーバー時間の計測、そして多岐にわたる障害シナリオ(ネットワーク障害、ディスク障害、ノード障害など)における健全な復旧プロセスの確認 までを含めた、網羅的な検証計画を立てることが極めて重要です。 本番環境へのスムーズな移行と、アップグレード後の安定稼働を確実なものとするために、この「本番環境と同等環境での徹底した事前検証」が何よりも重要なステップであると、強くご理解いただけますと幸いです。 まとめ 今回は、LifeKeeper製品の最新バージョンに記載されている新機能、バグ修正/機能強化、そしてアップグレードの注意点についてご紹介いたしました。 ビジネス継続性を支える高可用性(HA)クラスターソフトウェアとして、LifeKeeperは常に進化を続けており、およそ半年に一度のペースでアップグレードを実施しています。 今後もLifeKeeperの新機能や改善点、対応環境の拡充など、皆さまがより堅牢で効率的なシステム運用を実現できるよう、LifeKeeperに関する情報発信を続けてまいります。 最後までお読みいただき、誠にありがとうございました。   詳しい内容をお知りになりたいかたは、以下のバナーからSCSK LifeKeeper公式サイトまで
アバター
はじめに 当記事は、前回の記事「Ansibleを使用してNW機器設定を自動化する(PaloAlto-アドレス編①)」からの改善となります。 設定情報がベタ書きで使い勝手が悪い点 を 設定情報をまとめてINPUT(JSON)できる使い勝手の良い仕組みとしました!! これにより、Anibleとの連携ができるようになりますので、ご参考になれば幸いです。 ※前回記事: https://blog.usize-tech.com/ansible-automation-paloalto-address-1/ 当記事は、 日常の運用業務(NW機器設定)の自動化 により、 運用コストの削減 および 運用品質の向上  を目標に 「Ansible」 を使用し、様々なNW機器設定を自動化してみようと 試みた記事です。 Ansibleは、OSS版(AWX)+OSS版(Ansible)を使用しております。   PaloAltoの「Objects-アドレス」の登録/変更/削除を実施してみた 事前設定 Templateを作成し、インベントリーと認証情報を設定する。 インベントリー:対象機器(ホスト)の接続先を設定。 ※ホストには以下変数で接続先IPを指定 ansible_host: xxx.xxx.xxx.xxx 認証情報:対象機器へのログイン情報(ユーザ名/パスワード)を設定。 ユーザ名は  変数:ansible_user   に保持される パスワードは 変数:ansible_password に保持される   事前設定2:設定情報をまとめてINPUT(JSON)できるように、「Survey」を活用 テンプレートが読み込むことができる変数(Survey)を設定する。※今回は、各設定のデフォルト値に値を設定する。 実際の値(JSON) ・input_address1: {"name":"test_address001","address_type":"ip-netmask","value":"192.168.10.0/24","description":"address_ip-netmask","wk_tag":["test"]} ・input_address2: {"name":"test_address001","address_type":"ip-netmask","value":"192.168.20.0/24","description":"address_ip-netmask","wk_tag":["test"]} ・input_address3: {"name":"test_address001","address_type":"ip-netmask","value":"192.168.30.0/24","description":"address_ip-netmask","wk_tag":["test"]} ・input_address4: {"name":"test_address001"}   事前設定 Templateを作成し、インベントリーと認証情報を設定する。 インベントリー:対象機器(ホスト)の接続先を設定。 ※ホストには以下変数で接続先IPを指定 ansible_host: xxx.xxx.xxx.xxx 認証情報:対象機器へのログイン情報(ユーザ名/パスワード)を設定。 ユーザ名は  変数:ansible_user   に保持される パスワードは 変数:ansible_password に保持される   Playbook作成(YAML) 使用モジュール paloaltonetworks.panos.panos_address_object  を使用。 ※参考ページ:https://galaxy.ansible.com/ui/repo/published/paloaltonetworks/panos/content/module/panos_address_object/   接続情報(provider)の設定 providerには、ip_address/username/password の指定が必要。 vars: provider:   ip_address: '{{ ansible_host }}'   ← インベントリーのホストで設定   username: '{{ ansible_user }}'    ← 認証情報で設定   password: '{{ ansible_password }}'  ← 認証情報で設定   変数(Survey)の値取得 vars で 各変数(Survey)の値取得。 ※各変数(Survey)の値は、構造化データのように見えて「文字列」なので、ディクショナリ(構造化データ)として正しく扱えるように、from_json フィルターを使用すること!!      vars: wk_input1: '{{ input_address1 | from_json}}' wk_input2: '{{ input_address2 | from_json}}' wk_input3: '{{ input_address3 | from_json}}' wk_input4: '{{ input_address4 | from_json}}'   Objects-アドレスの登録 ★ 変数(Survey)の値をそのまま使用した場合…エラーとなる 接続情報とアドレス情報( Survey:input_address1 )を指定して登録(state: ‘present’)を行う。 - name: Add Address1_input_address1 paloaltonetworks.panos.panos_address_object: provider: '{{ provider }}' name: '{{ input_address1.name }}' address_type: '{{ input_address1.address_type }}' value: '{{ input_address1.value }}' description: '{{ input_address1.description }}' tag: '{{ input_address1.wk_tag }}' state: 'present' register: wk_result 実行結果:構造化データではないので、オブジェクトに項目が無いという エラー となる。 ※Ansibleの実行結果を抜粋 "msg": "The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'name'. ... Objects-アドレスの登録 接続情報とアドレス情報( Survey:input_address1 )を指定して登録(state: ‘present’)を行う。 - name: Add Address1_wk_input paloaltonetworks.panos.panos_address_object: provider: '{{ provider }}' name: '{{ wk_input1.name }}' address_type: '{{ wk_input1.address_type }}' value: '{{ wk_input1.value }}' description: '{{ wk_input1.description }}' tag: '{{ wk_input1.wk_tag }}' state: 'present' register: wk_result 実行結果:対象のアドレスが登録された。 ※Ansibleの実行結果(diff)を抜粋 "before": "", "after" : "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_address001\">\n\t<ip-netmask>192.168.10.0/24</ip-netmask>\n\t<description>address_ip-netmask</description>\n\t<tag>\n\t\t<member>test</member>\n\t</tag>\n</entry>\n"   Objects-アドレスの変更 ※登録のつづき 接続情報とアドレス情報を指定して 登録されたアドレスの変更( state: ‘replaced’ )を行う。  ※replacedの場合は、既存設定の置き換えとなる - name: Change Address1 paloaltonetworks.panos.panos_address_object: provider: '{{ provider }}' name: '{{ wk_input2.name }}' address_type: '{{ wk_input2.address_type }}' value: '{{ wk_input2.value }}' description: '{{ wk_input2.description }}' # tag: '{{ wk_input2.wk_tag }}' state: 'replaced' register: wk_result 実行結果:登録時のtag指定ありのアドレスが、Rreplaedによりtag指定なしのアドレスに変更された。 ※Ansibleの実行結果(diff)を抜粋 "before": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_address001\">\n\t<ip-netmask>192.168.10.0/24</ip-netmask>\n\t<description>address_ip-netmask</description>\n\t<tag>\n\t\t<member>test</member>\n\t</tag>\n</entry>\n", "after" : "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_address001\">\n\t<ip-netmask>192.168.20.0/24</ip-netmask>\n\t<description>address_ip-netmask</description>\n</entry>\n"   接続情報とアドレス情報を指定して 登録されたアドレスの変更( state: ‘merged’ )を行う。  ※mergedの場合は、既存設定の上書きとなる - name: Change Address2 paloaltonetworks.panos.panos_address_object: provider: '{{ provider }}' name: '{{ wk_input1.name }}' address_type: '{{ wk_input3.address_type }}' value: '{{ wk_input3.value }}' # description: '{{ wk_input3.description }}' tag: '{{ wk_input3.wk_tag }}' state: 'merged' register: wk_result 実行結果:上記変更時のtag指定なしのアドレスが、mergedによりtag指定ありのアドレスに変更された。また、アドレス情報にdescriptionを指定しなくても、既存設定が維持されていることを確認。 ※Ansibleの実行結果(diff)を抜粋 "before": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_address001\">\n\t<ip-netmask>192.168.20.0/24</ip-netmask>\n\t<description>address_ip-netmask</description>\n</entry>\n", "after" : "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_address001\">\n\t<ip-netmask>192.168.30.0/24</ip-netmask>\n\t<description>address_ip-netmask</description>\n\t<tag>\n\t\t<member>test</member>\n\t</tag>\n</entry>\n"   Objects-アドレスの情報収集 ※変更のつづき 接続情報とアドレスを指定して情報収集(state: ‘gathered’)を行う。 - name: Get Address Info paloaltonetworks.panos.panos_address_object: provider: '{{ provider }}' name: '{{ wk_input4.name }}' state: 'gathered' register: wk_result 実行結果:対象アドレスの情報が取得できた。 ※Ansibleの実行結果(gathered_xml)を抜粋 "gathered_xml": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_address001\">\n\t<ip-netmask>192.168.30.0/24</ip-netmask>\n\t<description>address_ip-netmask</description>\n\t<tag>\n\t\t<member>test</member>\n\t</tag>\n</entry>\n",   Objects-アドレスの削除 ※変更のつづき 接続情報とアドレスを指定して削除(state: ‘absent’)を行う。 - name: Delete Address1 paloaltonetworks.panos.panos_address_object: provider: '{{ provider }}' name: '{{ wk_input4.name }}' state: 'absent' register: wk_result 実行結果:対象のアドレスが削除された。 ※Ansibleの実行結果(diff)を抜粋 "before": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"test_address001\">\n\t<ip-netmask>192.168.30.0/24</ip-netmask>\n\t<description>address_ip-netmask</description>\n\t<tag>\n\t\t<member>test</member>\n\t</tag>\n</entry>\n", "after" : "" 最後に 今回、変数(Survey)を活用したことで、Ansibleに INPUT(JSON)を設定 できるようになりました。 設定情報がYAMLにベタ書きではなくなったので、使い勝手は増しましたが、 都度 変数(Survey)のデフォルト値に値を設定しての実行の為、まだまだ 使い勝手が悪い。。。      今後 外部からAnsibleの INPUT(JSON)に値を連携し実行させる仕組みを試みたいと思います。
アバター