Skip to content

Instantly share code, notes, and snippets.

@Sinetheta
Last active December 2, 2018 22:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sinetheta/ef918c21f27ed343d87ab076ffb090ad to your computer and use it in GitHub Desktop.
Save Sinetheta/ef918c21f27ed343d87ab076ffb090ad to your computer and use it in GitHub Desktop.
# A script to help setup S3 for new projects using aws sdk
#
# - Create new S3 bucket <prompt for bucket name>
# - [optional] configure bucket as website
# - [optional] configure bucket as publicly readable
# - Create new IAM user <prompt for user name>
# - Create new customer managed policy for full S3 access to new bucket only
# - Attach policy directly to new user
# - Create and print API access keypair
#
# Requires configured aws sdk https://github.com/aws/aws-sdk-ruby#configuration
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'highline'
gem 'aws-sdk-iam'
gem 'aws-sdk-s3'
end
cli = HighLine.new
profile = cli.ask('AWS profile name: ') { |q| q.default = 'default' }
region = cli.ask('S3 region: ') { |q| q.default = 'us-west-2' }
iam = Aws::IAM::Client.new(profile: profile, region: region)
s3 = Aws::S3::Client.new(profile: profile, region: region)
begin
puts 'Creating new bucket...'
bucket_name = cli.ask('New bucket name: ')
s3.create_bucket(bucket: bucket_name)
rescue Aws::S3::Errors::BucketAlreadyOwnedByYou
cli.say("<%= color('Bucket already exists', :yellow) %>")
end
is_website = cli.agree 'Configure bucket as website (yes/no)?'
if is_website
puts 'Configuring bucket as website...'
s3.put_bucket_website({
bucket: bucket_name,
website_configuration: {
error_document: {
key: 'error.html',
},
index_document: {
suffix: 'index.html',
},
},
})
index_path = "http://#{bucket_name}.s3-website-#{region}.amazonaws.com"
end
is_public = is_website || cli.agree('Make bucket publicly readable (yes/no)?')
if is_public
puts 'Adding public read bucket policy...'
policy_document = {
'Version': '2012-10-17',
'Statement': [
{
'Sid': 'AddPerm',
'Effect': 'Allow',
'Principal': '*',
'Action': 's3:GetObject',
'Resource': "arn:aws:s3:::#{bucket_name}/*"
}
]
}.to_json
s3.put_bucket_policy(
bucket: bucket_name,
policy: policy_document
)
end
begin
puts 'Creating new user...'
user_name = cli.ask('New IAM user name: ')
user = iam.create_user(user_name: user_name).user
rescue Aws::IAM::Errors::EntityAlreadyExists
cli.say("<%= color('User already exists', :yellow) %>")
end
# https://aws.amazon.com/blogs/security/writing-iam-policies-how-to-grant-access-to-an-amazon-s3-bucket/
policy_name = "s3-full-access-#{bucket_name}"
policy_document = {
'Version': '2012-10-17',
'Statement': [
{
'Effect': 'Allow',
'Action': ['s3:ListBucket'],
'Resource': ["arn:aws:s3:::#{bucket_name}"]
},
{
'Effect': 'Allow',
'Action': ['s3:*'],
'Resource': ["arn:aws:s3:::#{bucket_name}/*"]
}
]
}.to_json
policy_arn = begin
puts 'Creating new access policy...'
iam.create_policy({
policy_name: policy_name,
policy_document: policy_document
}).policy.arn
rescue Aws::IAM::Errors::EntityAlreadyExists => e
cli.say("<%= color('Policy already exists', :yellow) %>")
current_user = iam.get_user.user
account_id = current_user.arn.match(/arn:aws:iam::(\d+):.*/)[1]
iam.get_policy({
policy_arn: "arn:aws:iam::#{account_id}:policy/#{policy_name}"
}).policy.arn
end
iam.attach_user_policy({
policy_arn: policy_arn,
user_name: user_name
})
puts 'Creating new api access key...'
access_key = iam.create_access_key({ user_name: user_name }).access_key
cli.say("Finished creating new bucket <%= color('#{bucket_name}', :green) %> and user with full S3 access")
cli.say("<%= color('#{index_path}', :blue) %>") if defined? index_path
cli.say("<%= color('[#{user_name}]', :green) %>")
cli.say("<%= color('aws_access_key_id = #{access_key.access_key_id}', :green) %>")
cli.say("<%= color('aws_secret_access_key = #{access_key.secret_access_key}', :green) %>")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment