æ¬è¨äºã¯
AWSã¢ã¯ã¼ãåè³è
ç¥ã
17æ¥ç®ã®è¨äºã§ãã
â¨ð
16æ¥ç®
â¶â¶ æ¬è¨äº â¶â¶
18æ¥ç®
ðâ¨
- ã¯ããã«
- ã¢ã¼ã«ã¤ãã«ã¼ã«ã¨ã¯
- ã«ã¹ã¿ã ãªã½ã¼ã¹ã«ããã¢ã¼ã«ã¤ãã«ã¼ã«ã®é©ç¨
- ãã³ãã¬ã¼ã
- ã«ã¹ã¿ã ãªã½ã¼ã¹ã®Lambda颿°ã®ã³ã¼ã
- ãããã¤æé
- çµããã«
ã¯ããã«
ããã«ã¡ã¯ãè¤æ¬ã§ãã
ãã®åº¦ãã2025 Japan AWS Jr. Championsããã2025 Japan All AWS Certifications Engineersãã«é¸åºããã ãã¾ããã
ã2025 Japan AWS Jr. Championsãã®é¸åºã®çµç·¯ã¯ãããã°ã§ã¾ã¨ãã¦ããã®ã§ãããã£ããè¦ã¦ãã ãã!
ä»åã¯ã以åå·çããããã°ããã«ãã¢ã«ã¦ã³ãç°å¢ã«ããã AWS IAM Access Analyzer ãç¨ããæ¨©é管çãããã¼ã¹ã«ã ã«ã¹ã¿ã ãªã½ã¼ã¹ã«ããIAM Access Analyzerã®ã¢ã¼ã«ã¤ãã«ã¼ã«ã®èªåé©ç¨ã«ã¤ãã¦ã¾ã¨ãã¦ã¿ã¾ããã IAM Access Analyzerã¨ã¯ãIAMãã¼ã«ããªã½ã¼ã¹ã«å¯¾ããã¢ã¯ã»ã¹è¨±å¯ãåæãããµã¼ãã¹ã§ãã 詳ããæ¦è¦ã«ã¤ãã¦ã¯ããã¡ãã®ããã°ã§ã¾ã¨ãã¦ããã®ã§ããåç §ãã ããã
ã¢ã¼ã«ã¤ãã«ã¼ã«ã¨ã¯
ã¢ã¼ã«ã¤ãã«ã¼ã«æ¦è¦
ã¢ã¼ã«ã¤ãã«ã¼ã« (Archive rules) ã¨ã¯ãIAM Access Analyzerãæ¤åºããå¤é¨ããã®ã¢ã¯ã»ã¹ãå¯è½ã§ãããªã½ã¼ã¹ã«å¯¾ãã¦ãç¹å®ã®æ¡ä»¶ã«åè´ããã¢ã¯ã»ã¹ãèªåçã«ã¢ã¼ã«ã¤ãããããã®è¨å®ã§ããæ¤åºçµæã¨ãã¦ç¢ºèªä¸è¦ãªã¢ã¯ã»ã¹ãã¢ã¼ã«ã¤ãã«ã¼ã«ã«ãã£ã¦ããã£ã«ã¿ãªã³ã°ãããã¨ã§æ¤åºçµæã®ãã¤ãºãæ¸ããã¾ããä¾ãã°ã䏿çã¾ãã¯æ¤è¨¼ç®çã§ä½æããããããªãã¹ãç°å¢ç¨ã®ãªã½ã¼ã¹ãç£è¦ç®çã®SaaSã§è¨±å¯ããã¦ãããªã½ã¼ã¹çãã¢ã¼ã«ã¤ã対象ã¨ãªãã¾ãã
ã¢ã¼ã«ã¤ãã«ã¼ã«ãå¤ç¨ããããã¨ãæå³ããªãã¢ã¯ã»ã¹ãè¦éãå¯è½æ§ããããããã¢ã¼ã«ã¤ãã«ã¼ã«ã®åãæ±ãã«ã¯æ³¨æãå¿
è¦ã§ãããã®ãã宿çã«ãã¢ã¼ã«ã¤ãã«ã¼ã«ãè¦ç´ããããªéç¨ãå¿
è¦ã¨ãªãã¾ãã
ã¢ã¼ã«ã¤ãã«ã¼ã«ã使ãã¦ãæ¢åã®çµæã«ã¯é©ç¨ãããªã
ã¢ã¼ã«ã¤ãã«ã¼ã«ã®æ³¨æç¹ã¨ãã¦ãã¢ã¼ã«ã¤ãã«ã¼ã«ã®ä½ææã«æ¢åã®æ¤åºçµæã«ã¯é©ç¨ãããªãç¹ãããã¾ãã æ°è¦ã«æ¤åºãããã¢ã¯ã»ã¹ã«å¯¾ãã¦ã¯èªåã§ã¢ã¼ã«ã¤ãããã¾ããã使åã«æ¤ç¥æ¸ã¿ã§ããã¢ã¯ã»ã¹ã«é¢ãã¦ã¯ã¢ã¼ã«ã¤ãããã¾ããã ã¾ããã¢ã¼ã«ã¤ãã«ã¼ã«ã夿´ããå ´åã§ããæ¢åã®çµæã«ã¯åé©ç¨ãè¡ããã¾ããã ãã®ãããã¢ã¼ã«ã¤ãã«ã¼ã«ä½æã»æ´æ°å¾ã«ã¯ãæç¤ºçã«é©ç¨ãè¡ãå¿ è¦ãããã¾ãã ã¢ã¼ã«ã¤ãã«ã¼ã«ã®é©ç¨ãå®è¡ããã«ã¯ããã¸ã¡ã³ãã³ã³ã½ã¼ã«ãCLIãã«ã¹ã¿ã ãªã½ã¼ã¹ã«ããé©ç¨ã®ããããã®å¯¾å¿ãå¿ è¦ã«ãªãã¾ãã
ããã¸ã¡ã³ãã³ã³ã½ã¼ã«ä¸ããã¢ã¼ã«ã¤ãã«ã¼ã«ãé©ç¨ããå ´åã¯ãã¢ã¼ã«ã¤ãã«ã¼ã«ä½ææã«ãã¢ã¯ãã£ããªæ¤åºçµæã使ããã³ã¢ã¼ã«ã¤ããã鏿ãããã¨ã§ãæ¢åã®åæçµæã«ãé©ç¨ããã¾ãã ãã«ã¼ã«ã使ãã鏿ããã¨ãæ¢åã®çµæã«ã¯é©ç¨ããããã¢ã¼ã«ã¤ãã«ã¼ã«ã®ä½æã®ã¿ãè¡ããã¾ãã

CLIã«ããã¢ã¼ã«ã¤ãã«ã¼ã«é©ç¨ã®å ´åã¯ãapply-archive-ruleã³ãã³ããå®è¡ãã¾ãã 使ãããã¢ã¼ã«ã¤ãã«ã¼ã«ã®ä¸è¦§ã確èªãããå ´åã¯ãlist-archive-rulesã³ãã³ããå®è¡ãã¾ãã
aws accessanalyzer apply-archive-rule \ --analyzer-arn <ã¢ãã©ã¤ã¶ã¼ARN> \ --rule-name <ã¢ã¼ã«ã¤ãã«ã¼ã«å>
apply-archive-rule â AWS CLI 2.27.61 Command Reference
aws accessanalyzer list-archive-rules \
--analyzer-name <ã¢ãã©ã¤ã¶ã¼å>
list-archive-rules â AWS CLI 2.27.61 Command Reference
ã«ã¹ã¿ã ãªã½ã¼ã¹ã«ããé©ç¨ã«é¢ãã¦ã¯ã次ã®ç« ã§è§£èª¬ãã¾ãã
ã«ã¹ã¿ã ãªã½ã¼ã¹ã«ããã¢ã¼ã«ã¤ãã«ã¼ã«ã®é©ç¨
ã«ã¹ã¿ã ãªã½ã¼ã¹ã¨ã¯
ã«ã¹ã¿ã ãªã½ã¼ã¹ã¨ã¯ãAWS CloudFormationã§å®ç¾©ããã¦ããªããªã½ã¼ã¹ãè¤éãªå¦çããAWS LambdaãAmazon SNSãªã©ã使ã£ã¦æ¡å¼µçã«å®è¡ããä»çµã¿ã®ãã¨ã§ãã
CloudFormationã対å¿ãã¦ããªãç¹å®ã®ãªã½ã¼ã¹ã®APIå¼ã³åºããå¤é¨ã®ãµã¼ãã¹ã¨ã®é£æºãè¡ãéãªã©ã«å©ç¨ããã¾ãã
CloudFormationã§IAM AccessAnalyzerãå±éããå ´åãIAM Access Analyzerã®ã¢ã¼ã«ã¤ãã«ã¼ã«é©ç¨ã¯ã CloudFormationã§ã¯å¯¾å¿ãã¦ããªãæä½ã«ãªããããã¢ã¼ã«ã¤ãã«ã¼ã«ã®ä½æã¨é©ç¨ãåæã«è¡ãããå ´åã¯ãLambdaã«ããã«ã¹ã¿ã ãªã½ã¼ã¹ã®å®è£
ãå¿
è¦ã«ãªãã¾ãã

ã«ã¹ã¿ã ãªã½ã¼ã¹ã®å®è¡ã¿ã¤ãã³ã°
ã«ã¹ã¿ã ãªã½ã¼ã¹ã¯ãCloudFormationã¹ã¿ãã¯ã®ä½æã»æ´æ°ã»åé¤ã®ã¿ã¤ãã³ã°ã§å®è¡ããã¾ãã ãããã®æä½ã«å¿ãã¦ãCloudFormationã¯ã«ã¹ã¿ã ãªã½ã¼ã¹ã«å¯¾ãã¦ãªã¯ã¨ã¹ãï¼ã¤ãã³ãã¿ã¤ãï¼ãéä¿¡ãã¾ãã
| ã¤ãã³ãã¿ã¤ã | çºçã®ã¿ã¤ãã³ã° |
|---|---|
Create |
CloudFormationã¹ã¿ãã¯ã®æ°è¦ä½ææ |
Update |
CloudFormationã¹ã¿ãã¯ã®æ´æ°æ |
Delete |
CloudFormationã¹ã¿ãã¯ã®å餿 |
Lambda颿°ã§ã¯ãã¤ãã³ãã¿ã¤ããã¨ã«å¦çãåãã¦å®è£
ãããã¨ãæ¨å¥¨ããã¦ãããåå²ãè¡ããªãã¨æå³ããªãåä½ãã¹ã¿ãã¯ã¨ã©ã¼ã®åå ã¨ãªãå¯è½æ§ãããã¾ãã
ä¾ãã°ã IAM Access Analyzerã®å ´åãCloudFormationã®ä½æã»æ´æ°æã«ã®ã¿ã¢ã¼ã«ã¤ãã«ã¼ã«ãé©ç¨ããå餿ã«ã¯ã«ã¹ã¿ã ãªã½ã¼ã¹ã®Lambda颿°ã«ããå¦çãè¡ããªãããã«å¶å¾¡ãã¾ãã
ã¤ãã³ãã¿ã¤ãã¯ãLambda颿°ã®eventã®RequestTypeã«å«ã¾ãã¦ãã¾ãã
def lambda_handler(event, context): request_type = event["RequestType"] if request_type == "Create": # ã¹ã¿ãã¯ã®æ°è¦ä½ææã®å¦ç elif request_type == "Update": # ã¹ã¿ãã¯æ´æ°æã®å¦ç elif request_type == "Delete": # ã¹ã¿ãã¯å餿ã®å¦ç
CloudFormationã«å¯¾ãã¦ã¬ã¹ãã³ã¹ãå¿ è¦
Lambda颿°ã®å¦çãå®äºããããCloudFormationã«å¯¾ãã¦ãLambda颿°ã®å¦ççµæï¼SUCCESSã¾ãã¯FAILEDï¼ãéç¥ããå¿
è¦ãããã¾ãã
ãã®éç¥ã¯ãCloudFormationããæ¸¡ããããªã¯ã¨ã¹ãå
ã«å«ã¾ãã¦ãã ResponseURLï¼ç½²åä»ãS3ã®URLï¼ ã«å¯¾ãã¦ãHTTP PUTãªã¯ã¨ã¹ãã§ã¬ã¹ãã³ã¹ãéä¿¡ãããã¨ã§è¡ãã¾ãã
ã¬ã¹ãã³ã¹ãè¡ãããªãå ´åãCloudFormationã¯Lambda颿°ããã®å¿çãããã©ã«ãã®ã¿ã¤ã ã¢ã¦ãæéã§ãã1æéï¼3600ç§ï¼å¾
æ©ããããã§ãå¿çããªãå ´åã¯ã¹ã¿ãã¯æä½ã失æï¼FAILEDï¼ã¨ãã¦çµäºãã¾ãã
ã¿ã¤ã ã¢ã¦ãæéãçµéããã¾ã§ã¯ãã¹ã¿ãã¯ã¸ã®æä½ãå®è¡ã§ãã¾ããã

ã¬ã¹ãã³ã¹ã®å¦çãç°¡åã«è¡ãæ¹æ³ã¨ãã¦ãcfnresponse-sendã¢ã¸ã¥ã¼ã«ãããã¾ãã
ããã¯ãLambda颿°ãå¼ã³åºããã«ã¹ã¿ã ãªã½ã¼ã¹ã¸ã®å¿çã®éä¿¡ãç°¡ç´ åããAWSå
¬å¼ã®ã©ã¤ãã©ãªã®ãã¨ã§ãã
cfnresponse-sendã¢ã¸ã¥ã¼ã«ã¯ãCloudFormationãã³ãã¬ã¼ãå
ã®ZipFileããããã£ã使ç¨ãã¦ãPythonã³ã¼ããã¤ã³ã©ã¤ã³ã§è¨è¿°ããå ´åã«ã®ã¿å©ç¨å¯è½ã§ãã
ã¤ã¾ãããã³ãã¬ã¼ãå
ã«Pythonã³ã¼ããç´æ¥åãè¾¼ãå½¢å¼ã§å©ç¨ãããã¨ãåæã¨ãªãã¾ãã
ãã ããã¤ã³ã©ã¤ã³è¨è¿°ã«ã¯ããã¤ãã®ãã¡ãªãããããã¾ãã
ä¿å®æ§ãä½ã
ã³ã¼ãã®å¯èªæ§ãåå©ç¨æ§ãä¸ããããã¼ã¸ã§ã³ç®¡çããã«ãããªãã¾ãããããã°ãå°é£
åé¡ãCloudFormationå´ã«ããã®ããPythonã³ã¼ãå´ã«ããã®ãåãåããé£ãããªãã¾ãã ãã®ãããCloudFormation ãã³ãã¬ã¼ã㨠Lambdaã³ã¼ãã¯åé¢ããæ¹ãæã¾ããã§ããã³ã¼ããµã¤ãºå¶é
ZipFileããããã£ã«ã¯ã4096Byteï¼4KBï¼ã¾ã§ã¨ãããµã¤ãºå¶éãããã¾ãã
ãããã®çç±ãããä¸è¬çã«ã¯ Lambda颿°ã®ã³ã¼ããS3ãã±ããã«æ ¼ç´ããããããåç §ããæ¹æ³ãæ¡ç¨ããã¦ãã¾ãã ã¤ã³ã©ã¤ã³è¨è¿°ãæ¡ç¨ããå ´åã¯ãããåç´ãªå¦çã«éå®ãã¦ä½¿ç¨ãã¾ãã
S3ãã±ããã«æ ¼ç´ãããã³ã¼ãã§ã¯ãcfnresponse-sendã¢ã¸ã¥ã¼ã«ã¯ä½¿ç¨ã§ãã¾ããã
ããã¯ãcfnresponse-sendã¢ã¸ã¥ã¼ã«ãLambdaã©ã³ã¿ã¤ã ã«æ¨æºã§å«ã¾ãã¦ããããModuleNotFoundErrorãçºçããããã§ãã
ãã®ãããS3ä¸ã®ã³ã¼ãã§CloudFormationã«å¿çãè¿ãå¿
è¦ãããå ´åã¯ãã¬ã¹ãã³ã¹å¦çãç¬èªã«é¢æ°ã¨ãã¦å®è£
ããå¿
è¦ãããã¾ãã
ä»åã¯ãå°è¥¿ããã以åå·çãããããã°ãAWS Lambdaã«ã¹ã¿ã ãªã½ã¼ã¹ã§AWS Cloudformationã¹ã¿ãã¯ãå¥ãªã¼ã¸ã§ã³ã«ãããã¤ãããã®å
容ã¨AWSã®ããã¥ã¡ã³ããåèã«ã¬ã¹ãã³ã¹å¦çãç¬èªã®é¢æ°ã§ä½æãã¾ããã
ãã³ãã¬ã¼ã
CloudFormationãã³ãã¬ã¼ã
CloudFormationãã³ãã¬ã¼ãã§ã¯ã主ã«IAM Access Analyzerã®ã¢ãã©ã¤ã¶ã¼ã¨ã¢ã¼ã«ã¤ãã«ã¼ã«é©ç¨ã®ããã®Lambdaã使ãã¦ãã¾ãã
CloudFormationãã³ãã¬ã¼ã
AWSTemplateFormatVersion: '2010-09-09' Description: Create IAM Access Analyzer and apply archive rule automatically via Lambda (Custom Resource) Parameters: AnalyzerName: Description: The name of the Analyzer. Type: String Default: IAMAccessAnalyzer CustomResourceUpdateToken: Description: Execute a single CustomResource. Type: String Default: 0 LambdaCodeBucket: Description: S3 bucket containing Lambda source code (zip). Type: String LambdaCodeKey: Description: S3 key (path) to Lambda deployment package. Type: String Resources: Analyzer: Type: AWS::AccessAnalyzer::Analyzer Properties: AnalyzerName: !Sub "${AnalyzerName}-${AWS::AccountId}-${AWS::Region}" Type: ACCOUNT ArchiveRules: - Filter: - Property: resourceType Eq: - AWS::IAM::Role - Property: resource Contains: - test RuleName: PrefixIAMRoleRule RunCustomResourceApplyArchiveRule: Type: 'Custom::ApplyArchiveRule' DependsOn: ApplyArchiveRuleLambda Properties: ServiceToken: !GetAtt ApplyArchiveRuleLambda.Arn ServiceTimeout: 60 UpdateDummyInput: {Ref: CustomResourceUpdateToken} ApplyArchiveRuleLambda: Type: AWS::Lambda::Function DependsOn: - ApplyArchiveRuleRole - Analyzer Properties: FunctionName: ApplyArchiveRule Description : apply_archive_rule Runtime: python3.12 MemorySize: 1024 Timeout: 900 Role: !GetAtt ApplyArchiveRuleRole.Arn Handler: index.lambda_handler Code: S3Bucket: !Ref LambdaCodeBucket S3Key: !Ref LambdaCodeKey Environment: Variables: ANALYZER_ARN: !GetAtt Analyzer.Arn ANALYZER_NAME: !Sub "${AnalyzerName}-${AWS::AccountId}-${AWS::Region}" ApplyArchiveRuleRole: Type: AWS::IAM::Role Properties: RoleName: !Sub 'ApplyArchiveRule-${AWS::Region}' AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Policies: - PolicyName: !Sub 'IAMPolicy-ApplyArchiveRule-${AWS::Region}' PolicyDocument: Version: '2012-10-17' Statement: - Sid: ListRules Effect: Allow Action: - access-analyzer:ListArchiveRules Resource: "*" - Sid: ApplyRule Effect: Allow Action: - access-analyzer:ApplyArchiveRule Resource: !GetAtt Analyzer.Arn ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
CloudFormationã«ããIAM Access Analyzer使ã®è©³ç´°ã¯ãAWS CloudFormationã¦ã¼ã¶ã¼ã¬ã¤ã AccessAnalyzerãã確èªãã ããã
CloudFormationãã³ãã¬ã¼ã使ã«ããã¦ãTipsãç´¹ä»ãã¾ãã
ããã¼ãã©ã¡ã¼ã¿ãè¨å®ãã
CloudFormationã¯ãã«ã¹ã¿ã ãªã½ã¼ã¹ã®Propertiesã«å¤æ´ããªãéããã¹ã¿ãã¯æ´æ°æã«Lambda颿°ãåå®è¡ãã¾ããã
ã«ã¹ã¿ã ãªã½ã¼ã¹ã®å¦çãåå®è¡ãããå ´åãè¦ããä¸ã®å¤æ´ãå ããå¿
è¦ãããã¾ãã
ãã®ããã«ãããã¼ãã©ã¡ã¼ã¿ï¼ä»åã®å ´åã¯ãCustomResourceUpdateTokenã¨å®ç¾©ï¼ã使ç¨ãã¾ãã
ãã®ããã¼ãã©ã¡ã¼ã¿ã®å¤ã夿´ããCloudFormationãæ´æ°ããããã¨ã§ãã«ã¹ã¿ã ãªã½ã¼ã¹ãå¼·å¶çã«åå®è¡ãã¾ãã
ä»åã®ã±ã¼ã¹ã ã¨ãããã¸ã¡ã³ãã³ã³ã½ã¼ã«ãªã©ã§ã¢ã¼ã«ã¤ãã«ã¼ã«ä½æã®ã¿ãè¡ãããå¾ãããã¼ãã©ã¡ã¼ã¿ï¼CustomResourceUpdateTokenï¼ã®å¤ã夿´ãããã¨ã§ãã¢ã¼ã«ã¤ãã«ã¼ã«ã®é©ç¨ãå¥éå®è¡ã§ãã¾ãã
ServiceTimeoutãå©ç¨ãã
ãCloudFormationã«å¯¾ãã¦ã¬ã¹ãã³ã¹ãå¿
è¦ãã®ç« ã§èª¬æããéããCloudFormationã®ã«ã¹ã¿ã ãªã½ã¼ã¹ã§ã¯ãLambda颿°ããã®ã¬ã¹ãã³ã¹ããªãå ´åãããã©ã«ãã§æå¤§1æéï¼3600ç§ï¼ã¹ã¿ãã¯æä½ãå¾
æ©ç¶æ
ã«ãªãã¾ãã
ã¿ã¤ã ã¢ã¦ãæéãçµéããã¾ã§ã¯ãä»ã®æä½ãå®è¡ã§ããªããããéçºã»æ¤è¨¼æã«ã¯å¤§ããªããã«ããã¯ã«ãªãã¾ãã
ãã®åé¡ãåé¿ããããã«ãã«ã¹ã¿ã ãªã½ã¼ã¹ã«ServiceTimeoutãè¨å®ãã¾ãã
ServiceTimeoutã¯ãã«ã¹ã¿ã ãªã½ã¼ã¹ã®ã¿ã¤ã ã¢ã¦ãæéãç§åä½ã§æç¤ºçã«æå®ã§ããããããã£ã§ãã
ServiceTimeout: 300ã¨è¨å®ããã°ãLambda颿°ãã¨ã©ã¼ã«ãªã£ãå ´åã§ãCloudFormationã¯5åå¾ã«å¦çã失æï¼FAILEDï¼ã¨ãã¦çµäºããä¸è¦ãªå¾
æ©æéãé²ããã¨ãã§ãã¾ãã
RunCustomResourceApplyArchiveRule: Type: 'Custom::ApplyArchiveRule' DependsOn: ApplyArchiveRuleLambda Properties: ServiceToken: !GetAtt ApplyArchiveRuleLambda.Arn ServiceTimeout: 60 # ã¿ã¤ã ã¢ã¦ãæéè¨å® UpdateDummyInput: {Ref: CustomResourceUpdateToken} # ããã¼ãã©ã¡ã¼ã¿
ã«ã¹ã¿ã ãªã½ã¼ã¹ã®Lambda颿°ã®ã³ã¼ã
ä»å使ããã«ã¹ã¿ã ãªã½ã¼ã¹ã®Lambda颿°ã§ã¯ãIAM Access Analyzerã®ååãARNãPythonã³ã¼ãå
ã§ãã¼ãã³ã¼ãã£ã³ã°ãããCloudFormationã®ç°å¢å¤æ°ï¼Environment:ï¼ããåå¾ããããã«ãã¦ãã¾ãã
ããã«ãããå¯èªæ§ãä¿å®æ§ãåä¸ããCloudFormationå´ã®å¤ã夿´ããã ãã§ãæè»ã«å¯¾å¿ã§ããããã«ãªãã¾ãã
ã«ã¹ã¿ã ãªã½ã¼ã¹ã®Lambda颿°ã®ã³ã¼ã
import os import json import boto3 import botocore import logging import urllib.request # ãã¬ã¼è¨å® logger = logging.getLogger() logger.setLevel(logging.INFO) # ç°å¢æ å ± region = os.environ.get('AWS_REGION') sts_client = boto3.client("sts", region_name=region) accountId = sts_client.get_caller_identity()["Account"] # CloudFormationã®ç°å¢å¤æ°ãåãåã ANALYZER_ARN = os.environ["ANALYZER_ARN"] ANALYZER_NAME = os.environ.get("ANALYZER_NAME") or ANALYZER_ARN.split("/")[-1] def lambda_handler(event, context): logger.info(f"Received event: {json.dumps(event)}") try: request_type = event['RequestType'] if request_type == 'Delete': # ã¹ã¿ãã¯å餿 logger.info("Delete event received. No action needed.") cfn_response_send(event, context, 'SUCCESS', {}, reason='Delete request - no action') return elif request_type in ['Create', 'Update']: # ã¹ã¿ãã¯ä½æã»æ´æ°æ archive_rule_names = get_list_archiverules() if archive_rule_names: apply_archiverules(archive_rule_names) message = f"Applied archive rules: {archive_rule_names}" else: message = "No archive rules found" cfn_response_send(event, context, 'SUCCESS', {'Message': message}) return cfn_response_send(event, context, 'FAILED', {}, reason=f"Unexpected RequestType: {request_type}") except Exception as e: logger.error(f"Unhandled exception: {e}") cfn_response_send(event, context, 'FAILED', {}, reason=str(e)) # ã¢ã¼ã«ã¤ãã«ã¼ã«ã®ä¸è¦§ãåå¾ def get_list_archiverules(): accessanalyzer_client = boto3.client('accessanalyzer') archive_rule_names = [] try: paginator = accessanalyzer_client.get_paginator('list_archive_rules') for page in paginator.paginate(analyzerName=ANALYZER_NAME): archive_rule_names.extend(rule['ruleName'] for rule in page.get('archiveRules', [])) except botocore.exceptions.ClientError as e: logger.error(f"Failed to list archive rules: {e}") return archive_rule_names # ã¢ã¼ã«ã¤ãã«ã¼ã«ãé©ç¨ def apply_archiverules(archive_rule_names): accessanalyzer_client = boto3.client('accessanalyzer') for rule_name in archive_rule_names: try: accessanalyzer_client.apply_archive_rule( analyzerArn=ANALYZER_ARN, ruleName=rule_name ) logger.info(f"Applied archive rule: {rule_name}") except botocore.exceptions.ClientError as e: logger.error(f"Error applying archive rule {rule_name}: {e}") continue # ç¬èªã®ã¬ã¹ãã³ã¹å¦ç def cfn_response_send(event, context, response_status, response_data, physical_resource_id=None, no_echo=False, reason=None): response_url = event['ResponseURL'] logger.info(f"Response URL: {response_url}") response_body = { 'Status': response_status, 'Reason': reason or f"See the details in CloudWatch Log Stream: {context.log_stream_name}", 'PhysicalResourceId': physical_resource_id or context.log_stream_name, 'StackId': event['StackId'], 'RequestId': event['RequestId'], 'LogicalResourceId': event['LogicalResourceId'], 'NoEcho': no_echo, 'Data': response_data } json_response_body = json.dumps(response_body) logger.info(f"Response body: {json_response_body}") headers = { 'Content-Type': '', 'Content-Length': str(len(json_response_body)) } try: request = urllib.request.Request( response_url, data=json_response_body.encode('utf-8'), headers=headers, method='PUT' ) with urllib.request.urlopen(request) as response: logger.info(f"CloudFormation response sent. Status code: {response.status}") except Exception as e: logger.error(f"Failed to send CloudFormation response: {e}")
ãããã¤æé
å ±æããã«ã¹ã¿ã ãªã½ã¼ã¹ã®Lambda颿°ã®ã³ã¼ãã¨CloudFormationãã³ãã¬ã¼ããç¨ãã¦ããããã¤ãè¡ãã¾ãã
1.Lambda颿°ã®ã³ã¼ããS3ã«ã¢ãããã¼ã
Lambda颿°ã®ã³ã¼ãï¼index.pyï¼ãzipåããä¸ã§ãS3ãã±ããã«ã¢ãããã¼ããã¾ãã
S3ãã±ããã¯å¥é使ãã¾ãã
2.Cloud Shellã«ã¦ãCloudFormationã³ãã³ãå®è¡
Cloud Shellä¸ã«CloudFormationãã³ãã¬ã¼ã(YAMLãã¡ã¤ã«)ãã¢ãããã¼ãããä¸ã§ã以ä¸ã®ã³ãã³ããå®è¡ãã¾ãã
aws cloudformation deploy \
--template-file <CloudFormationãã³ãã¬ã¼ãå> \
--stack-name <ã¹ã¿ãã¯å> \
--capabilities CAPABILITY_NAMED_IAM \
--parameter-overrides \
LambdaCodeBucket=<ã¢ãããã¼ãå
ã®S3ãã±ããå> \
LambdaCodeKey=<S3ãã±ããã«ã¢ãããã¼ãããzipãã¡ã¤ã«å>
çµããã«
ã¢ã¼ã«ã¤ãã«ã¼ã«ã®èªåé©ç¨ã¨ããããããªå 容ã§ãããããããã§ããã§ããããã æ¬ããã°ã§ãCloudFormationã«ãããã«ã¹ã¿ã ãªã½ã¼ã¹ã®ä½¿ãæ¹ã»ã¢ã¼ã«ã¤ãã«ã¼ã«èªåé©ç¨ã®åèã«ãã¦ããã ããã°ã¨æãã¾ãã ã¾ããåã®ããã°ã§ã触ãã¾ããããIAM Access Analyzerã§ã¯ãªã½ã¼ã¹ã®æå³ããªãå ±æãæ¤åºãããã¨ã¯ã§ãã¾ãããã¢ãã©ã¤ã¶ã¼èªä½ãèªåçã«ä¿®æ£ãè¡ããã¨ã¯ããã¾ããã ãã®ãããæ¤åºãããå 容ã«å¯¾ããå¯¾å¿æ¹éãéç¨ããã»ã¹ãäºåã«æ¤è¨ãã¦ãããã¨ãéè¦ã§ãã