[AWS CloudFormation とは何ですか?](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html) ## CloudFormationの動作概要 ポイントは**StackSets**でクロスリージョンやクロスアカウントのリソースを作成できる点。必要であればオリジナルな処理を**カスタムリソース**で定義できる点。クロスアカウントでは管理者とターゲットアカウントの間に信頼関係を設定する。
### CloudFormation テンプレートの操作 動的なパラメータ参照、テンプレートのスニペットなど * [CloudFormation テンプレートの使用](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-guide.html) * [CloudFormation テンプレートスニペット](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-snippets.html) ### スタックの作成と管理 * [AWS CloudFormation スタックを使用した単一ユニットとしての AWS リソースの管理](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stacks.html) ### 組込関数リファレンス * [組み込み関数リファレンス](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html) ``` # 使用例 UserData: Fn::Base64: Fn::Sub: - | #!/bin/bash sed -i -e 's/APP_URL=.*/APP_URL=${APP_URL}/' /tmp/.env sed -i -e 's/DB_HOST=.*/DB_HOST=${DB_HOST}/' /tmp/.env sed -i -e 's/DB_DATABASE=.*/DB_DATABASE=${DbName}/' /tmp/.env sed -i -e 's/DB_USERNAME=.*/DB_USERNAME=${UserName}/' /tmp/.env sed -i -e 's/DB_PASSWORD=.*/DB_PASSWORD=${Password}/' /tmp/.env sed -i -e 's/AWS_S3_BUCKET=.*/AWS_S3_BUCKET=${S3_BUCKET}/' /tmp/.env - APP_URL: Fn::ImportValue: !Sub ${Prefix}::${Client}::LoadBalancerDNSName DB_HOST: Fn::ImportValue: !Sub ${Prefix}::${Client}::EndpointAddress S3_BUCKET: Fn::ImportValue: !Sub ${Prefix}::${Client}::DataBucket ``` ### 疑似パラメータ * [擬似パラメータ参照](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html) ### AWS リソースとプロパティタイプのリファレンス * [AWS リソースおよびプロパティタイプのリファレンス](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) ### StackSets 信頼関係を構築すれば、Organizationsを利用していなくても利用可能 * [StackSets を使用したアカウントとリージョン全体でのスタックの管理](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html) * [AWS CloudFormation StackSets のサンプルテンプレート](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stacksets-sampletemplates.html) * [セルフマネージド型のアクセス許可を付与する](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stacksets-prereqs-self-managed.html) ``` # セルフマネージド型のアクセス許可 # # 管理者アカウント側 # AWSTemplateFormatVersion: 2010-09-09 Description: Configure the AWSCloudFormationStackSetAdministrationRole to enable use of AWS CloudFormation StackSets. Parameters: AdministrationRoleName: Type: String Default: AWSCloudFormationStackSetAdministrationRole Description: "The name of the administration role. Defaults to 'AWSCloudFormationStackSetAdministrationRole'." ExecutionRoleName: Type: String Default: AWSCloudFormationStackSetExecutionRole Description: "The name of the execution role that can assume this role. Defaults to 'AWSCloudFormationStackSetExecutionRole'." Resources: AdministrationRole: Type: AWS::IAM::Role Properties: RoleName: !Ref AdministrationRoleName AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: cloudformation.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: AssumeRole-AWSCloudFormationStackSetExecutionRole PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - sts:AssumeRole Resource: - !Sub 'arn:*:iam::*:role/${ExecutionRoleName}' # # ターゲットアカウント側 # AWSTemplateFormatVersion: 2010-09-09 Description: Configure the AWSCloudFormationStackSetExecutionRole to enable use of your account as a target account in AWS CloudFormation StackSets. Parameters: AdministratorAccountId: Type: String Description: AWS Account Id of the administrator account (the account in which StackSets will be created). MaxLength: 12 MinLength: 12 ExecutionRoleName: Type: String Default: AWSCloudFormationStackSetExecutionRole Description: "The name of the execution role. Defaults to 'AWSCloudFormationStackSetExecutionRole'." Resources: ExecutionRole: Type: AWS::IAM::Role Properties: RoleName: !Ref ExecutionRoleName AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: AWS: - !Ref AdministratorAccountId Action: - sts:AssumeRole Path: / ManagedPolicyArns: - !Sub arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess ``` ### カスタムリソース * [CloudFormation が提供するリソースタイプの使用によるテンプレートの機能の拡張](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cloudformation-supplied-resource-types.html) #### 削除イベントの時にS3バケットを掃除するカスタムリソース ``` AWSTemplateFormatVersion: 2010-09-09 Description: If you use S3 bucket, you need to clean up used S3 bucket. so this template is cleanup example Resources: #========================== # S3 Bucket #========================== DataBucket: Type: "AWS::S3::Bucket" Properties: BucketName: !Sub 'data-bucket' BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 OwnershipControls: Rules: - ObjectOwnership: BucketOwnerEnforced PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true #========================== # カスタムリソース #========================== # S3バケット掃除のカスタムリソース CleanoutBucketOnDelete: Type: Custom::cleanupBucket Properties: ServiceToken: !GetAtt CleanoutBucketFunction.Arn DependsOn: - CleanoutBucketFunction # 掃除用ファンクション CleanoutBucketFunction: Type: AWS::Lambda::Function DependsOn: - DataBucket - CleanoutBucketRole Properties: Description: Clean out Bucket on delete. Handler: index.handler Runtime: python3.12 Role: !GetAtt CleanoutBucketRole.Arn Timeout: 120 Environment: Variables: BUCKET_NAME: !Ref DataBucket Code: ZipFile: | import cfnresponse import logging import boto3 import time, os status = cfnresponse.SUCCESS logger = logging.getLogger(__name__) logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG) def handler(event, context): logger.debug(event) if event['RequestType'] == 'Delete': try: BUCKETNAME = os.environ['BUCKET_NAME'] s3 = boto3.resource('s3') bucket = s3.Bucket(BUCKETNAME) bucket_versioning = s3.BucketVersioning(BUCKETNAME) if bucket_versioning.status == 'Enabled': bucket.object_versions.delete() else: bucket.objects.all().delete() cfnresponse.send(event, context, status, {}, None) except Exception as e: print(e) cfnresponse.send(event, context, cfnresponse.FAILED, {}, None) else: cfnresponse.send(event, context, status, {}, None) # 掃除用ロール CleanoutBucketRole: Type: AWS::IAM::Role Properties: PermissionsBoundary: !Sub 'arn:aws:iam::${AWS::AccountId}:policy/DevelopUserBoundary' AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Policies: - PolicyName: lambda-bucketcleaner PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:DeleteObject - s3:DeleteObjectVersion Resource: !Sub 'arn:${AWS::Partition}:s3:::${DataBucket}/*' - Effect: Allow Action: - s3:ListBucket - s3:GetBucketVersioning Resource: !Sub 'arn:${AWS::Partition}:s3:::${DataBucket}' ``` #### インスタンスのネットワークインターフェイスを取得するカスタムリソース ``` AWSTemplateFormatVersion: 2010-09-09 Description: The template for creating FlowLog resources. Resources: CustomResource: Type: AWS::CloudFormation::CustomResource DependsOn: - Function Properties: ServiceToken: !GetAtt Function.Arn ServiceTimeout: 60 INSTANCEID: i-1234567890abcdef0 Function: Type: "AWS::Lambda::Function" Properties: Handler: index.handler Runtime: python3.8 Timeout: 60 Role: !GetAtt LambdaExecutionRole.Arn Code: ZipFile: | import cfnresponse import boto3 status = cfnresponse.SUCCESS def handler(event, context): try: INSTANCEID = event['ResourceProperties']['INSTANCEID'] ec2 = boto3.client('ec2') response = ec2.describe_network_interfaces( Filters=[ { 'Name': 'attachment.instance-id', 'Values': [INSTANCEID] } ] ) network_interface_id = response['NetworkInterfaces'][0]['NetworkInterfaceId'] responseData = {} responseData['Data'] = network_interface_id cfnresponse.send(event, context, status, responseData, None) except Exception as e: print(e) cfnresponse.send(event, context, cfnresponse.FAILED, {}, None) LambdaExecutionRole: Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - "lambda.amazonaws.com" Action: - "sts:AssumeRole" ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Policies: - PolicyName: "LambdaEC2Policy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "ec2:DescribeNetworkInterfaces" Resource: "*" LogGroup: DeletionPolicy: Delete UpdateReplacePolicy: Delete Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub '${AWS::StackName}-LogGroup' RetentionInDays: 1 FlowLogPolicy: Type: "AWS::IAM::ManagedPolicy" Properties: ManagedPolicyName: !Sub '${AWS::StackName}-FlowLogPolicy' Path: "/" PolicyDocument: | { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "logs:DescribeLogGroups", "logs:DescribeLogStreams" ], "Resource": "*" } ] } FlowLogRole: Type: "AWS::IAM::Role" DependsOn: - FlowLogPolicy Properties: Path: "/" RoleName: !Sub '${AWS::StackName}-FlowLogRole' AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - sts:AssumeRole Principal: Service: - vpc-flow-logs.amazonaws.com MaxSessionDuration: 3600 ManagedPolicyArns: - !Ref FlowLogPolicy EC2FlowLog: Type: "AWS::EC2::FlowLog" DependsOn: - CustomResource Properties: DeliverLogsPermissionArn: !GetAtt FlowLogRole.Arn LogGroupName: !Ref LogGroup ResourceId: !GetAtt CustomResource.Data TrafficType: "ALL" LogDestinationType: "cloud-watch-logs" ResourceType: "NetworkInterface" LogFormat: "${version} ${account-id} ${interface-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${start} ${end} ${action} ${log-status}" MaxAggregationInterval: 60 ```
0 件のコメント:
コメントを投稿