如何使用CloudFormation模板访问UserData文件?从S3获取公开可访问的UserData.txt
1. How to Access a UserData File in a CloudFormation Template
If you want to pull content from an external UserData file directly into your CloudFormation template (instead of hardcoding it inline), the Fn::ReadFile intrinsic function is your go-to solution. Since EC2 UserData requires Base64 encoding, you’ll combine it with Fn::Base64 to ensure the content is formatted correctly for the instance.
Here’s a practical example of how to implement this:
Resources: MyEC2Instance: Type: AWS::EC2::Instance Properties: ImageId: ami-1234567890abcdef0 # Replace with your target AMI ID InstanceType: t2.micro UserData: Fn::Base64: Fn::ReadFile: ./UserData.txt # Path to your local UserData file (relative to where you run the CloudFormation command)
A few key notes:
- The path in
Fn::ReadFilemust be relative to the directory where you executeaws cloudformation deployoraws cloudformation create-stack. - For Windows AMIs, your UserData file should wrap PowerShell code in
<powershell>and</powershell>tags (unless you’re using thecfn-inithelper tool).
2. Accessing a UserData.txt File from S3 Instead of Rewriting Scripts in CloudFormation Init
Absolutely—this is a common pattern to keep your templates clean and scripts maintainable. There are two main approaches, depending on your security needs:
Option 1: Publicly Accessible S3 Object (Simpler, Less Secure)
If you’ve set your UserData.txt to be publicly readable in S3, you can directly download and run it from the instance’s UserData. For Windows PowerShell, this looks like:
Resources: MyEC2Instance: Type: AWS::EC2::Instance Properties: ImageId: ami-1234567890abcdef0 InstanceType: t2.micro UserData: Fn::Base64: | <powershell> # Download the script from S3 Invoke-WebRequest -Uri "https://your-bucket-name.s3.amazonaws.com/UserData.txt" -OutFile "C:\UserData.txt" # Execute the downloaded script & "C:\UserData.txt" </powershell>
Option 2: Private S3 Object (More Secure, Recommended for Production)
Never expose sensitive scripts publicly. Instead, attach an IAM role to your EC2 instance that grants permission to read from the target S3 bucket, then use AWS tools to download the file.
First, define the IAM role and instance profile in your template:
Resources: EC2S3AccessRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: AllowS3UserDataAccess PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: s3:GetObject Resource: arn:aws:s3:::your-bucket-name/UserData.txt EC2InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref EC2S3AccessRole
Then, update the EC2 instance to use this profile and download the script via PowerShell:
MyEC2Instance: Type: AWS::EC2::Instance Properties: ImageId: ami-1234567890abcdef0 InstanceType: t2.micro IamInstanceProfile: !Ref EC2InstanceProfile UserData: Fn::Base64: | <powershell> # Install AWS Tools for PowerShell if not pre-installed Install-Module -Name AWSPowerShell.NetCore -Force -AllowClobber # Download the private script from S3 Read-S3Object -BucketName "your-bucket-name" -Key "UserData.txt" -File "C:\UserData.txt" # Execute the script & "C:\UserData.txt" </powershell>
If you prefer using AWS::CloudFormation::Init for structured configuration, you can also use its files section to pull the script directly:
MyEC2Instance: Type: AWS::EC2::Instance Properties: ImageId: ami-1234567890abcdef0 InstanceType: t2.micro IamInstanceProfile: !Ref EC2InstanceProfile UserData: Fn::Base64: Fn::Sub: | <powershell> cfn-init -v --stack ${AWS::StackName} --resource MyEC2Instance --region ${AWS::Region} </powershell> Metadata: AWS::CloudFormation::Init: configSets: default: - downloadAndRunScript downloadAndRunScript: files: "C:\\UserData.txt": source: https://your-bucket-name.s3.amazonaws.com/UserData.txt authentication: S3AccessCreds commands: execute_script: command: "C:\\UserData.txt"
Note: Most AWS-managed Windows AMIs come with cfn-init pre-installed, but if yours doesn’t, you’ll need to install it first via UserData.
内容的提问来源于stack exchange,提问作者pgunana

