Last active
December 2, 2018 22:17
-
-
Save Sinetheta/ef918c21f27ed343d87ab076ffb090ad to your computer and use it in GitHub Desktop.
Explanation at https://sinetheta.ca/2018/06/16/automating-aws-setup.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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