Created
November 15, 2017 16:18
-
-
Save akira345/3727029ff40942e6e40d51fc29023efc to your computer and use it in GitHub Desktop.
AWS Organizationsを利用したアカウント作成の自動化及びSTSでの認証取得、SNS、CloudWatch設定サンプルです。
This file contains 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
# -*- coding: utf-8 -*- | |
# | |
# AWS Organizationsを利用したアカウント作成の自動化(https://aws.amazon.com/jp/blogs/news/account-management-automation-using-aws-organizations/) | |
# をRubyに焼き直していくつか改善したもの。 | |
# 要 AWS SDK for Ruby V3 | |
require 'aws-sdk-core' | |
require 'aws-sdk-organizations' | |
require 'aws-sdk-sns' | |
require 'aws-sdk-cloudwatch' | |
require 'yaml' | |
require 'pp' | |
# このスクリプトを実行するIAMユーザロールはPowerUser相当が(多分)必要です。 | |
config = YAML.load(File.read("config.yml")) | |
Aws.config[:credentials] = Aws::Credentials.new(config['access_key_id'],config['secret_access_key']) | |
og = Aws::Organizations::Client.new(region: 'us-east-1') # us-east-1でないと怒られる | |
EMAIL = "hoge@example.com" | |
ACCOUNT_NAME = "ExampleAccount" | |
# 組織が作成済みでない場合作成する。 | |
organization_info = nil | |
begin | |
organization_info = og.describe_organization({ | |
}) | |
rescue | |
organization_info = og.create_organization({ | |
feature_set: "ALL", | |
}) | |
end | |
pp organization_info | |
pp "------------------------------" | |
# 組織のアカウントリストを取得し、メアドで検索し、すでにアカウントがないかチェック | |
next_token = nil | |
next_data = true | |
account_id = nil | |
account_exist = false | |
while next_data do | |
pp "------------------------------" | |
resp = og.list_accounts({ | |
next_token: next_token, | |
max_results: 1, | |
}) | |
pp resp | |
if resp.accounts[0].email == EMAIL | |
account_id = resp.accounts[0].id | |
break | |
end | |
if resp.next_token.nil? | |
next_data = false | |
else | |
next_token = resp.next_token | |
end | |
end | |
if account_id.nil? | |
# メアドが見当たらない場合、作成した組織にアカウントを作成する | |
create_account_resp = og.create_account({ | |
account_name: ACCOUNT_NAME, | |
email: EMAIL | |
}) | |
while true | |
account_info = og.describe_create_account_status({ | |
create_account_request_id: create_account_resp.create_account_status.id | |
}) | |
case account_info.create_account_status.state | |
when 'FAILED' | |
case account_info.create_account_status.failure_reason | |
when 'ACCOUNT_LIMIT_EXCEEDED' | |
pp "組織内のアカウント数の上限に達しているため、アカウントを作成できませんでした。" | |
when 'EMAIL_ALREADY_EXISTS' | |
pp "そのメールアドレスを持つ別のAWSアカウントが既に存在するため、アカウントを作成できませんでした。" | |
when 'INVALID_ADDRESS' | |
pp "指定したアドレスが有効でないため、アカウントを作成できませんでした。" | |
when 'INVALID_EMAIL' | |
pp "指定したメールアドレスが有効でないため、アカウントを作成できませんでした。" | |
when 'INTERNAL_FAILURE' | |
pp "内部エラーのためにアカウントを作成できませんでした。あとでもう一度試してみてください。問題が解決しない場合は、カスタマーサポートに連絡してください。" | |
end | |
exit(1) | |
when 'SUCCEEDED' | |
pp "アカウント作成完了!" | |
account_id = account_info.create_account_status.account_id | |
break | |
else | |
sleep(1) | |
end | |
end | |
end | |
pp account_id | |
# STSを利用して一時認証情報を取得 | |
role_credentials = Aws::AssumeRoleCredentials.new( | |
duration_seconds: 900, #有効期限は15分 | |
client: Aws::STS::Client.new(region: 'us-east-1'), | |
role_arn: "arn:aws:iam::#{account_id}:role/OrganizationAccountAccessRole", | |
role_session_name: "OrgMasterRoleSession" | |
) | |
# 取得した認証情報でBillingアラート設定 | |
sns = Aws::SNS::Client.new(region: 'us-east-1',credentials: role_credentials) | |
cloudwatch = Aws::CloudWatch::Client.new(region: 'us-east-1',credentials: role_credentials) | |
# SNS Topic作成 | |
sns_topic_arn = sns.create_topic({ | |
name: 'DefaultBillingAlertTopic' | |
}).topic_arn | |
pp sns_topic_arn | |
sns.subscribe({ | |
topic_arn: sns_topic_arn, | |
protocol: 'email', | |
endpoint: EMAIL | |
}) | |
# Billingアラート作成 | |
resp=cloudwatch.put_metric_alarm({ | |
alarm_name: 'DefaultBillingAlart', | |
alarm_description: 'DefaultBillingAlart', | |
actions_enabled: true, | |
alarm_actions: [sns_topic_arn], | |
metric_name: 'EstimatedCharges', | |
namespace: 'AWS/Billing', | |
statistic: 'Maximum', | |
dimensions: [ | |
{ | |
'name': 'Currency', | |
'value': 'USD' | |
}, | |
], | |
period: 21600, | |
evaluation_periods: 1, | |
threshold: 100, | |
comparison_operator: 'GreaterThanThreshold' | |
}) | |
pp resp | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment