title: AWS - Associate EC2 with SSM to enable ssm.client.send_command
body: <p>I'd like to run a series of bash commands through boto3 on a newly launched instance.</p>
  
  <p>From some research it appears that associating this new instance with SSM is required to achieve this.</p>
  
  <p><em>Are there any clear mistakes or missed steps below? Also are there better approaches to achieve the stated goal?</em></p>
  
  <h2>Step 1 - Get clients and resources</h2>
  
  <pre><code>import boto3
  
  ec2c = boto3.client('ec2')
  ec2r = boto3.resource('ec2')
  ssmc = boto3.client('ssm')
  </code></pre>
  
  <h2>Step 2 - Create and wait for instance</h2>
  
  <pre><code>instances = ec2r.create_instances(
      ImageId = 'ami-####',
      InstanceType = 't2.micro',
      MinCount = 1,
      MaxCount = 1,
      SecurityGroupIds = ['sg-####'])
  
  instance_ids = [i.id for i in instances]
  instance = instances[0]
  
  instance.wait_until_running()
  </code></pre>
  
  <h2>Step 3 - Associate instance with IAM profile</h2>
  
  <p><strong><em>"RoleName" has the <code>AmazonEC2RoleforSSM</code> policy attached to it</em></strong></p>
  
  <pre><code>res = ec2c.associate_iam_instance_profile(
      IamInstanceProfile={
          'Arn': 'arn:aws:iam::###:instance-profile/RoleName',
          'Name': 'RoleName'
      },
      InstanceId = instance.id
  )
  </code></pre>
  
  <h2>Step 4 - Check for associations</h2>
  
  <pre><code>print(ssmc.describe_instance_information()['InstanceInformationList'])
  
  &gt; []
  </code></pre>
  
  <p><strong>(I think this empty list is why the next step is failing)</strong></p>
  
  <h2>Step 5 - Run commands</h2>
  
  <pre><code>resp = ssmc.send_command(
      DocumentName = "AWS-RunShellScript",
      Parameters = {'commands': [mkdir app]},
      InstanceIds = instance_ids
  )
  
  &gt; botocore.errorfactory.InvalidInstanceId: An error occurred ...
  &gt; ... (InvalidInstanceId) when calling the SendCommand operation:
  </code></pre>