avatarTeri Radichel

Summarize

Setting Up A Delegated Organizations Administrator With CloudFormation

ACM.428 Moving our organization delegated administrator and service control policy deployment to our deployment container

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

⚙️ Part of my series on Automating Cybersecurity Metrics. The Code.

🔒 Related Stories: AWS Organizations | AWS Security

💻 Free Content on Jobs in Cybersecurity | ✉️ Sign up for the Email List

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In the last post I showed how to run git-secrets and introduced GitHub policies to prevent users from checking secrets into GitHub.

Rather than throw away useful constructs, prevent the things you don’t want to happen. I wrote about that here:

What’s an AWS Organizations Delegated Administrator?

I covered that in this post:

Selecting a delegated administrator account

In this post I’m going to make my policies account in the governance organizational unit (OU) the delegated administrator for our organization so it can manage the Service Control Policies (SCPs) for the organization.

Recall that I’ve already created some AWS accounts.

My organizational structure looks like this:

I’ve already deployed SCPs in past posts but will revisit and re-deploy them here. Some of them didn’t work so I’ll skip those — specifically enforcing deployment of accounts outside the root OU, since CloudFormation deploys first to that OU and then moves them. (Not ideal.)

To deploy a delegated administrator with CloudFormation we have to deploy a resource policy. I explained what resource policies are here:

CloudFormation Organizations Resource Policy

Here’s the CloudFormation Resource for a Organization Resource Policy:

Just a reminder that the option of using a JSON string as demonstrated in the CloudFormation documentation will not work with drift detection for some resources. I’m staying away from that.

Generate the initial code with my code generator

The first thing I’m going to do is run my code generator to create the base files:

  • A CloudFormation template shell for my resource policy
  • A functions file in the resource directory to deploy the template
  • A deploy script in the folder of the role that is allowed to deploy the resource
./gen_code/gen_code.sh

Select the role:

Enter the CloudFormation category:

Enter the CloudFormation type:

Enter the resource name (Yaml file name):

Enter a description:

Create deployment script:

Create functions file:

Create CloudFormation template:

I explained how my code generator works in more detail here:

Update the CloudFormation template

I already had an existing CloudFormation template so I copied that over, but in this case I’m removing any imports of outputs from other templates for reasons explained in another post. That is causing too many problems and won’t work with cross-account resources.

resources/organizations/resourcepolicy/resourcepolicy.yaml

Review the functions file

resources/organizations/resourcepolicy/resourcepolicy_functions.sh

This will hopefully just work:

Update the deployment script

The deployment script is in the directory of the role that has the least permissions that is allowed to run it. Roles with privileges that encompass those permissions can also run it. My root-orgadmin role will run this script.

deploy/root-orgadminrole/organizations_resourcepolicy_resourcepolicy.sh

This should just work as well with the exception of commenting out the check for passed in parameters since we don’t have any. I should probably add a question for that to my code generation script.

Add the script to the list of jobs the role can run

At the top of the script I add a number to choose that script.

Scrolling down I assign a script associated with the selected number.

Run the script and verify the results

Execute the local test script:

./localtest.sh

Now that we have a delegated administrator we can use it to redeploy some of our SCPs using our deployment container in the next post.

Oops, one thing I need to add to my code generator.

I’ve written about my common validation routines throughout this series which now reside at:

awsdeploy/deploy/shared/validate.sh

I’m now setting the script that calls the validation routine to get a kind of stack trace.

So I added this to my functions.txt file in the code generator.

gen_code/functions.txt

I re-run my code generator and only recreate that functions file and get an error stating that the environment is missing. That’s because a made a change to pass in the environment when deploying a resource but did not update my code generator to pass in the environment value to the function that deploys the resource:

I update this file:

gen_code/deploy.txt

While I’m at it I’m going to fix that validate parameters issue:

I check to see if the person running the code generator plans to pass in custom parameters for this deployment:

At the top of the file:

Re-run the code generator.

Answer the new question:

Check the output and now that line is automatically commented out if I don’t need to pass in parameters to the container when I run it:

Every tweak means less edits later.

Re-run the test script.

Made a change so re-run the container image build:

We don’t have ECR set up yet so do not push to ECR:

Select a role to get a list of jobs that role can run:

Enter the number for our new job:

Select a role from your existing role profiles to simulate the EC2 instance. The role profile needs permission to access the secret with the credentials used to execute the job.

For a local test, I have to enter MFA but on an EC2 instance the role would have access to the secret without MFA. However, to use the credentials in the secret, an MFA token needs to be provided to the container.

Enter the MFA token associated with the credentials stored in the secret. The credentials are associated with the user that is allowed to assume the role that is running this job.

Alright now here’s where I need to do a little customization of my deployment script and with the above fixes this is the only thing I should really have needed to do. I need to pass in the account number that will be the organizations delegated administrator:

I already have a function to get an account number by name in my account_functions.sh file:

resources/organizations/account/account_functions.sh 

So I source that file and get the account id by name and use it in my delegated administrator function. I’m going to do it this way for the moment but stay tuned for a change in an upcoming post that will make the system more flexible across the board and require less one-off changes.

Check the stack got created in the root account:

Navigate to AWS Organizations:

Now we should be able to use a role in that account to create service control policies for our organization. I still need to test that out.

In this post, I reduced some of the keystrokes I have to make to create a new resource, but I want to take it even farther and make it easier to deploy resources with customizable parameters. In the next post I am going to write about another change I’ve been thinking about for a while and I’m going to modify this code a bit more.

Major improvements in the next few posts, starting here:

Follow for updates.

Teri Radichel | © 2nd Sight Lab 2024

About Teri Radichel:
~~~~~~~~~~~~~~~~~~~~
⭐️ Author: Cybersecurity Books
⭐️ Presentations: Presentations by Teri Radichel
⭐️ Recognition: SANS Award, AWS Security Hero, IANS Faculty
⭐️ Certifications: SANS ~ GSE 240
⭐️ Education: BA Business, Master of Software Engineering, Master of Infosec
⭐️ Company: Penetration Tests, Assessments, Phone Consulting ~ 2nd Sight Lab
Need Help With Cybersecurity, Cloud, or Application Security?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
🔒 Request a penetration test or security assessment
🔒 Schedule a consulting call
🔒 Cybersecurity Speaker for Presentation
Follow for more stories like this:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
❤️ Sign Up my Medium Email List
❤️ Twitter: @teriradichel
❤️ LinkedIn: https://www.linkedin.com/in/teriradichel
❤️ Mastodon: @teriradichel@infosec.exchange
❤️ Facebook: 2nd Sight Lab
❤️ YouTube: @2ndsightlab
Deletegated Administrator
AWS
Organizations
Governance
Policies
Recommended from ReadMedium