Pulumi 의 Policy 만드는 방법 3가지

Policy 를 만들 때 3가지 방법이 있습니다. 하나씩 설명해 봅니다.


"Pulumi 로 AWS EKS 구성하기" 글을 쓰면서 Policy 를 정말 길게 썼습니다. 최소한의 권한 원칙을 일부라도 지키려면 필요한 일이었습니다. 이제 그때보다 잘 설명할 수 있을 것 같습니다.

총 3가지 방법이 있습니다. TypeScript 로 직접 class PolicyDocument 를 적는 방법, getPolicyDocument 함수를 써서 얻는 방법, getPolicyDocumentOutput 을 써 Pulumi Input 에 들어갈 수 있는 객체를 얻는 -- Pulumi Output 을 얻는 -- 방법입니다.

첫 번째, 직접 class PolicyDocument를 적습니다. type PolicyDocument 로 변수를 선언하고 타이핑을 시작하면 IDE 의 도움을 받을 수 있습니다. VSCode 를 사용했습니다. VSCode 로 할 때는 key Version 의 값을 입력할 때 "2008--" 과 "2012-10-17" 두 가지가 드롭다운 메뉴로 나옵니다. 다른 key 를 입력할 때도 "actions" 인지 "Action" 인지 헷갈리는데 "Action" 하나만 표시되니 바로 골라 쓸 수 있습니다.

const policyDocument: PolicyDocument = {
  Version: "2012-10-17",
  Statement: [
    {
      Action: ["ec2:CreateNetworkInterface"],
      Effect: "Allow",
      Resource: ["*"],
    },
  ],
};

두 번째, getPolicyDocument 를 사용합니다. 첫 번째 처럼 Type 을 변수 선언에 붙여 줄 필요는 없지만 읽으시는 분들이 어떤 타입이 리턴되는지 바로 볼 수 있기 위해서만 붙여 두었습니다. 사용할 때는 거의 없는 채로 구현했습니다.

Promise 를 리턴하는 만큼 .then 함수로 resolve 된 후에 사용합니다. 또 resolve 된 결가가 PolicyDocument 가 아니니 .json 값으로 string 값을 얻어 썼습니다.

const policyDocument2: Promise<GetPolicyDocumentResult> =
  aws.iam.getPolicyDocument({
    version: "2012-10-17",
    statements: [
      {
        actions: ["ec2:CreateNetworkInterface"],
        effect: "Allow",
        resources: ["*"],
      },
    ],
  });


new aws.iam.Policy("...", {
  name: "...",
  policy: policyDocument2.then((_) => _.json),
});

이렇게 Javscript Promise 를 사용하는 만큼 불편함도 있지만, 아주 긴 JSON Policy 의 경우에 인터넷에서 구할 수 있는 예제 Policy 를 그대로 복붙 하는 것으로 사용할 수 있습니다. 여기서는 actions, resources 처럼 복수가 사용됩니다.

Promise 가 쓰이는 만큼 Javascrpt 생태계에 익숙해 져야 하는 부분이 있고, Pulumi 의 Input Output 으로 엮이는 안 맞기도 합니다. 그래서 Pulumi Community 에 처음 접한 분들의 숱한 질문에 답을 해야하는 상황이었나 봅니다. 그래서 Pulumi 에서 getPolicyDocumentOutput 이라는 함수를 만들었습니다. 그리고 많은 Class 에서 Input 도 인자를 넘길 수 있도록 바꿨습니다. 그렇게 되면 **Output 함수의 리턴값을 그대로 넘길 수 있습니다.

Functions Now Accept Outputs

const policyDocument3: pulumi.Output<aws.iam.GetPolicyDocumentResult> =
  aws.iam.getPolicyDocumentOutput({
    version: "2012-10-17",
    statements: [
      {
        actions: ["ec2:CreateNetworkInterface"],
        effect: "Allow",
        resources: ["*"],
      },
    ],
  });

new aws.iam.Policy("...", {
  name: "...",
  policy: policyDocument3.json,
});

policyDocument3.json 처럼 Pulumi 의 Input Output 을 활용해 .then 이나 .apply 함수 없이 간결하게 표현할 수 있습니다. 하위호환성을 위해 getPolicyDocument 함수가 남아 있지만 **Output 함수 활용을 pulumi 에서 권장합니다.