require 'renuo/cli/app/services/cloudfront_config_service' class CreateAwsProject def initialize ensure_aws_setup? ensure_aws_profile_existing? collect_project_information end def run %w[main develop testing].each do |branch| print_setup_commands branch end end private def collect_project_information say 'We need now some informations to create your s3-bucket:'.colorize :green collect_general_information collect_s3_information collect_cloudfront_information end def collect_general_information @project_name = ask('Project name (eg: renuo-cli): ') { |q| q.validate = /.+/ } end def collect_s3_information @project_purpose = ask('Suffix describing a non-default purpose (eg: "archives"): ') { |q| q.default = 'none' } @project_purpose = nil if @project_purpose.empty? || @project_purpose == 'none' @redmine_project = ask('Redmine project name for billing (eg: internal): ') do |q| q.default = @project_name q.validate = /.+/ end @aws_profile = 'renuo-app-setup' @aws_region = ask('AWS bucket region: ') { |q| q.default = 'eu-central-1' } @aws_app_group = 'renuo-apps-v2' end def collect_cloudfront_information @setup_cloudfront = agree('Would you like to setup also AWS CloudFront? '\ '(Default: yes, if you want to deliver assets/images from S3)') return unless @setup_cloudfront @cloudfront_alias = {} return unless agree('Would you like to use an alias to call your assets/images on S3? (Default: no)') %i[main develop testing].each do |branch| cloudfront_alias_for branch end end def cloudfront_alias_for(branch) @cloudfront_alias[branch] = ask("What CF-Alias do you want to use for #{branch}?") { |q| q.validate = /.+/ } end def ensure_aws_setup? ensure_is_setup?('aws --version > /dev/null', 'brew install awscli', 'Would you like to install aws-cli via `brew install awscli`?') end def ensure_aws_profile_existing? ensure_is_setup?('aws configure --profile renuo-app-setup list > /dev/null', 'aws configure --profile renuo-app-setup', 'Would you like set up a profile for AWS '\ '`aws configure --profile renuo-app-setup`? (User/Password in keystore)') end def ensure_is_setup?(installation_check_command, installation_command, agree_text) (system(installation_command) if agree(agree_text)) until system(installation_check_command) end def print_setup_commands(branch) say "\n# AWS #{branch} \n".colorize :green # wrap_at inserts newlines, after that, the command is no longer copyable $terminal.wrap_at = nil if $terminal puts aws_iam_setup(@aws_profile, aws_user(branch), @aws_app_group) puts aws_s3_setup(@aws_profile, aws_user(branch), @aws_region, @redmine_project) puts aws_s3_versioning_setup(@aws_profile, aws_user(branch)) if branch == 'main' cloudfront_setup(aws_user(branch), branch) $terminal.wrap_at = :auto if $terminal end def cloudfront_setup(bucket, branch) return unless @setup_cloudfront puts aws_cloudfront_setup(@aws_profile, bucket, branch, @redmine_project) if @cloudfront_alias[branch.to_sym] say "\n# Warning: Don't forget to set up `#{cloudfront_alias(branch)}` on the DNS "\ 'if not yet done'.colorize :yellow else say "\n# Hint: The domain name for your S3 files, can be found after running the" \ ' commands on https://console.aws.amazon.com/cloudfront/home'.colorize :yellow end end def aws_user(branch) [@project_name, branch, @project_purpose].compact.join('-') end def cloudfront_alias(branch) @cloudfront_alias[branch.to_sym] end def aws_iam_setup(profile, user, app_group) <<-IAM_COMMANDS aws --profile #{profile} iam create-user --user-name #{user} aws --profile #{profile} iam add-user-to-group --user-name #{user} --group-name #{app_group} aws --profile #{profile} iam create-access-key --user-name #{user} IAM_COMMANDS end def aws_s3_setup(profile, bucket, region, redmine_project) <<-S3_COMMANDS aws --profile #{profile} s3 mb s3://#{bucket} --region #{region} aws --profile #{profile} s3api put-bucket-tagging --bucket #{bucket} --tagging "TagSet=[{Key=redmine_project,Value=#{redmine_project}}]" S3_COMMANDS end def aws_s3_versioning_setup(profile, bucket) <<-S3_VERSIONING_COMMANDS aws --profile #{profile} s3api put-bucket-versioning --bucket #{bucket} --versioning-configuration Status=Enabled S3_VERSIONING_COMMANDS end def aws_cloudfront_setup(profile, bucket, branch, redmine_project) tags = [{ "Key": 'redmine_project', "Value": redmine_project }] cloudfront_config_string = CloudfrontConfigService.new(bucket, cloudfront_alias(branch), tags).to_s <<-CLOUDFRONT_COMMANDS aws --profile #{profile} cloudfront create-distribution-with-tags --distribution-config-with-tags '#{cloudfront_config_string}' CLOUDFRONT_COMMANDS end end