Account Profile States#
Each state in an SLS file defaults to using the default profile for the associated provider.
Idem determines which profile is appropriate by looking for ACCT
on the hub in the root of the state definition.
For example, in idem_aws/states/aws/init.py
we might see the following code:
def __init__(hub):
hub.states.aws.ACCT = ["aws"]
The code specifies that all plugins under hub.states.aws
should use profiles under the aws
provider key in the account file.
An account file with AWS credentials might look like this:
aws:
default:
id: XXXXXXXXXXXXXXXXX
key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
region: us-east-1
other:
id: XXXXXXXXXXXXXXXXX
key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
region: us-east-1
A single SLS file can reference multiple AWS credential profiles as shown in the following example:
# No profile is specified, so the default AWS profile is used.
ensure_vpc:
aws.vpc.present:
- kwarg1: value1
# The "other" AWS profile is specified for use.
ensure_vpc:
aws.vpc.present:
- acct_profile: other
- kwarg1: value1
States from one cloud can depend on states from another cloud. Idem will associate the right profiles with the right plugins and keep the profiles separate in their own contexts.
Consider the following multi-cloud account file:
aws:
default:
id: XXXXXXXXXXXXXXXXX
key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
region: us-east-1
azure:
default:
client_id: "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
secret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
subscription_id: "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
tenant: "cccccccc-cccc-cccc-cccc-cccccccccccc"
Profiles under the aws
provider are only sent to plugins that specify the aws
provider for authentication.
Profiles under the azure
provider are only sent to plugins that specify the azure
provider for authentication.
# The default aws profile is used.
ensure_vpc:
aws.vpc.present:
- kwarg1: value1
# The default azure profile is used.
ensure_vpc:
azure.vpc.present:
- kwarg1: value1
In this way, Idem seamlessly integrates multiple requisites and profiles across different clouds, all within a single SLS file.
Aggregate State#
You can dynamically extend account information using the acct.profile
state.
In the following example, test.present
represents data from an arbitrary resource.
Its values are passed via arg_bind
to an acct.profile
state.
The third state requires the new_profile
state and then makes use of the profile created in that state.
Caution
Use this feature with arg_binding to use information generated in one state as credentials in other states.
You can use the feature to create roles and dynamically assume those roles in subsequent states.
Do not use this feature to bypass encrypting your credentials file. Exercise caution and do not abuse this feature.
mock_acct:
test.present:
- new_state:
key_1: value_1
key_2: value_2
new_profile:
acct.profile:
- provider_name: test
- key_1: ${test:mock_acct:key_1}
- key_2: ${test:mock_acct:key_2}
test_result:
test.acct:
- acct_profile: new_profile
- require:
- acct: new_profile
Note
This can also be done without require
blocks by using the reconciliation loop.
Single-use Profiles#
In the following code block, acct_data is passed directly into the state. The profiles defined here will be used in place of all the profiles defined for the rest of the RUN. This acct_data is not preserved and only exists in the context of the state that uses it.
mock_acct:
test.present:
- new_state:
key_1: value_1
key_2: value_2
test_result:
test.acct:
- acct_profile: new_profile
- acct_data:
profiles:
test:
new_profile:
key_1: ${test:mock_acct:key_1}
key_2: ${test:mock_acct:key_2}
If arg_binding is not required, account data that isn’t sensitive can be saved in a Jinja variable and explicitly passed to each state that needs it. However, you get better value and security from writing an acct plugin.
{% set acct_data = {"profiles": {"test": {"new_profile": {"key_1": "value_1", "key_2": "value_2"}}}} %}
test_result:
test.acct:
- acct_profile: new_profile
- acct_data: {{acct_data}}
Copy From Existing Profiles#
To copy from an existing profile, specify the source_profile
key in the acct.profile
state.
The profile matching the source_profile
name under the given provider will be used as a base for constructing the new profile.
Consider the following acct_file:
test:
source:
key_1: overwritten
key_3: copied
The following state copies the existing profile under the given provider in the acct_file.
key_1
is defined in both places, so the new profile will overwrite that value.
key_3
is not defined in the new_profile, so it will be copied from the existing profile in the acct_file to the new profile.
new_profile:
acct.profile:
- provider_name: test
- source_profile: source
- key_1: value_1
- key_2: value_2
test_result:
test.acct:
- acct_profile: new_profile
- require:
- acct: new_profile